zoukankan      html  css  js  c++  java
  • 开发实用技巧

    1.recyclerview预览:
    1 tools:listitem="@layout/item_cv_fragment_start"

     2.androidstudio的源文件保存:

    as的源码需要拷贝出来时,不要直接去该项目所在路径复制源文件,一定要看清楚该路径下是否是最新编辑的源文件,可能不是(坑惨了)

    3.重新安装JDK:

    重新安装了JDK,为了不影响之前的JDK,应该把%JAVA_HOME%在path中的路径上移到最上面,JAVA_HOME还是采用之前的,然后在实际中选择特定的JDK.如图:

     4.MAVEN版本与JDK安装版本不兼容

    MAVEN版本需要与JDK版本不兼容可以在eclipse中重新制定相兼容的版本的JDK就行了

    3.spring中@Autowired注解与@Resource(这是java中的注解)的使用区别:

    @Autowired是spring中的自动注入,如果是一个接口一个实现类,需在实现类中上面引入@Service,再引入@Autowired时系统自动找到该接口的实现类,但是如果有多个接口就会出错,只能用@Resource(“xxx”)注入指定的实现,且实现接口需要用@Service(“xxx”)

     

    4.maven默认采用tomcat6端口,下面修改路径和端口

    <build>
            <plugins>
                <!-- maven内置 的tomcat6插件 -->
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>tomcat-maven-plugin</artifactId>
                    <version>1.1</version>
                    <configuration>
                        <!-- 可以灵活配置工程路径 -->
                        <path>/ssh</path>
                        <!-- 可以灵活配置端口号 -->
                        <port>8080</port>
                    </configuration>
                </plugin>
            </plugins>
    </build>

    5.ObjectAnimotor的x,y,width,height偏移:

    (1).如果没有水平方向的偏移,width的拉升默认是向正方向(右边)拉升;

    ObjectAnimator.ofFloat(newBall,"width", newBall.getWidth(),newBall.getWidth()+BALL_SIZE);

    (2).如果有x方向偏移,width的方向是按照x的移动方向拉升,比如

    ObjectAnimator.ofFloat(newBall, "x", newBall.getX(), newBall.getX() -BALL_SIZE/2);

    这是向左移动,所以width如果拉升BALL_SIZE个长度的话,拉升先满足向左BALL_SIZE/2,还有BALL_SIZE/2只能是向右了

    (3).onDraw()

    @Override
    protected void onDraw(Canvas canvas)
    {
        // 遍历balls集合中的每个ShapeHolder对象
        for (ShapeHolder shapeHolder : balls)
        {
            // 保存canvas的当前坐标系统
            canvas.save();
            // 坐标变换:将画布坐标系统平移到shapeHolder的X、Y坐标处
            canvas.translate(shapeHolder.getX(), shapeHolder.getY());
            // 将shapeHolder持有的圆形绘制在Canvas上
            shapeHolder.getShape().draw(canvas);
            // 恢复Canvas坐标系统
            canvas.restore();
        }
    }

    (4).ShapHolder中height,width发生改变,都需要重新定义大小,小球在移动的过程中就一直调用shape的绘制

    public void setHeight(float height)
        {
            Shape s = shape.getShape();
            Log.i(TAG, "setHeight: -------s.getWidth():"+s.getWidth()+",height:"+height);
            s.resize(s.getWidth(), height);
        }
    public void setWidth(float width)
        {
            Log.i(TAG, "setWidth: -------调用了");
            Shape s = shape.getShape();
            s.resize(width, s.getHeight());
        }

    (5).点睛之笔

    在构造方法中,开启一个背景变化,且是无限循环的,这样改View的onDraw方法就一直在执行,下来的任意操作后都会有onDraw()的重绘

    public MyAnimationView(Context context)
    {
        super(context);
        // 加载动画资源
        ObjectAnimator colorAnim = (ObjectAnimator) AnimatorInflater
            .loadAnimator(MainActivity.this, R.animator.color_anim);
        colorAnim.setEvaluator(new ArgbEvaluator());
        // 对该View本身应用属性动画
        colorAnim.setTarget(this);
        // 开始指定动画
        colorAnim.start();
    }

     

    (6).如果没有上面操作,可以设置动画更新监听,在其中来不断重绘

    @Override
    public void onAnimationUpdate(ValueAnimator animation)
    {
        // 指定重绘该界面
        this.invalidate();  //
    }

    6.RecyclerView刷新数据:

    (1).Date数据集采用date.addList(position,conllection)形式不易出错
    (2).增加完数据,记得adapter.notifyItemChanged(index)并且其他操作insert,move等等
    private void addData(){
        List<MultiItemEntity> list=new ArrayList<>();
        list.add(new Person("新增1", 111));
        list.add(new Person("新增2", 222));
        int index=6;
        mRes.addAll(index+1,list);
        adapter.notifyItemChanged(index);
        adapter.notifyItemRangeInserted(index + 1, list.size());
     }

    7.属性xml动画:

    (1).

    (2).实例popshow.xml  

     以自身为基础,Y正方向向上,100%~0表示,加p表示的是以父容器为标准,不加p则是以自身为标准,所以最终结果是移动自身的100%p就完全可见了

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!--以自身为基础,Y正方向向下,20%~0表示向上移动,p自身的距离,所以最终结果是移动自身的20%p就完全不见了-->
        <translate
            android:duration="3500"
            android:fromYDelta="100%"
            android:toYDelta="0" />
        <alpha
            android:duration="3500"
            android:fromAlpha="0.0"
            android:toAlpha="1.0" />
    </set>
    (3).实例pophide.xml
    以自身为基础,Y正方向向上,0~100%表示向下移动,加p表示的是以父容器为标准,不加p则是以自身为标准,,所以最终结果是移动自身的100%p就完全不见了
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!--以自身为基础,Y正方向向下,0~20%表示向下移动,p自身的距离,所以最终结果是移动自身的20%p就完全不见了-->
        <translate
            android:duration="3500"
            android:fromYDelta="0"
            android:toYDelta="100%" />
        <alpha
            android:duration="3500"
            android:fromAlpha="1.0"
            android:toAlpha="0.0" />
    </set>

     

     (4).效果图

     

     (5).坐标标准:

     

    8.View绘制流程(TimeLineView为例)

     (1).计算小球的合理直径:

    int pLeft = getPaddingLeft();
    int pRight = getPaddingRight();
    int pTop = getPaddingTop();
    int pBottom = getPaddingBottom();
    
    int width = getWidth();// Width of current custom view
    int height = getHeight();
    
    int cWidth = width - pLeft - pRight;// Circle width
    int cHeight = height - pTop - pBottom;
    
    int markSize = Math.min(mMarkerSize, Math.min(cWidth, cHeight));

     

    (2).计算小球在控件中的绘制范围:

    if(mMarkerInCenter) { //居中显示情况
                if(mMarker != null) {
                    mMarker.setBounds((width/2) - (markSize/2),(height/2) - (markSize/2), (width/2) + (markSize/2),(height/2) + (markSize/2));
                    mBounds = mMarker.getBounds();
                }
            } else { //水平居中,但是垂直根据mStartMaginTop来合理调整距离顶部的高度
                if(mMarker != null) {
                    mMarker.setBounds((width/2) - (markSize/2),mStartMaginTop, (width/2) + (markSize/2),markSize+mStartMaginTop);
                    mBounds = mMarker.getBounds();
                }
            }

     

    (3).绘制小球上下线,以小球为基准

     //TODO:注意,我这里只考虑了垂直方向的情况,水平方向按这个思路同理
            int centerX = mBounds.centerX();
            int lineLeft = centerX - (mLineSize >> 1);
            if(mLineOrientation==0) {
                //水平方向
                if(mStartLine != null) {
                    mStartLine.setBounds(0, pTop + (mBounds.height()/2), mBounds.left - mLinePadding, (mBounds.height()/2) + pTop + mLineSize);
                }
                if(mEndLine != null) {
                    mEndLine.setBounds(mBounds.right + mLinePadding, pTop + (mBounds.height()/2), width, (mBounds.height()/2) + pTop + mLineSize);
                }
            } else {
                //垂直方向
                if(mStartLine != null) {
                    //TODO:方式一:根据控件顶部(0,0)为基准点来绘制
                    mStartLine.setBounds(lineLeft, 0, mLineSize + lineLeft, mBounds.top - mLinePadding);
                    //TODO:方式二:根据底部(lineLeft, mBounds.top - mLinePadding)为基准点来绘制
                    //mStartLine.setBounds(lineLeft, mBounds.top - mLinePadding-((height-markSize)>>1), mLineSize + lineLeft, mBounds.top - mLinePadding);
                }
                if(mEndLine != null) {
                    mEndLine.setBounds(lineLeft, mBounds.bottom + mLinePadding, mLineSize + lineLeft, height);
                }
            }

    (4).onMesure方法记得需要重新测绘:

    @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            //内部的padding需要自己去计算,重新设置进去
            int w = mMarkerSize + getPaddingLeft() + getPaddingRight();
            int h = mMarkerSize + getPaddingTop() + getPaddingBottom();
    
            // 宽度和高度通过系统的决策方式来确定最终的视图宽高
            int widthSize = resolveSizeAndState(w, widthMeasureSpec, 0);
            int heightSize = resolveSizeAndState(h, heightMeasureSpec, 0);
    
            setMeasuredDimension(widthSize, heightSize);
            initDrawable();
        }

    (5).大小改变时也需要initDrawable():

    @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            initDrawable();
        }

    (6).最后就是onDraw()方法了

     @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if(mMarker != null) {
                mMarker.draw(canvas);
            }
            if(mStartLine != null) {
                mStartLine.draw(canvas);
            }
            if(mEndLine != null) {
                mEndLine.draw(canvas);
            }
        }

    (7).自定义属性

    (8)xml布局:

                       

                图1   默认居中显示                                                                                                      图2  marginTop 5dp

     (9).效果图:

                                                         

                图1居中显示                                                                                                                                                          图2 水平居中,marginTop一小段距离5dp

    (10)github:

     

     

     

     

     

     

     

  • 相关阅读:
    Python 使用 environs 库来更好地定义环境变量
    五分钟带你了解map、reduce和filter
    部署React前端和Django后端的3种方法
    marshmallow库更优雅的数据转换
    利用 attrs 和 cattrs 两个库实现 Python 面向对象编程
    parse库,更友好的格式化数据提取方案
    python之prettytable模块格式化打印
    使用类型注解让 Python 代码更易读
    jksj算法训练营-第三课01 数组、链表、跳表
    linux安装java步骤
  • 原文地址:https://www.cnblogs.com/jeffery336699/p/9288611.html
Copyright © 2011-2022 走看看