开发实用技巧

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:

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/jeffery336699/p/9288611.html