- 以下是在自定义View过程中的一些总结,从不理解到理解,从不会到会的一个过程中,中间会学会很多的一些关于自定义view的一些知识点,将其记录下来。好记性不如烂笔头,时时重温,如果有不对的地方请麻烦指证,谢谢
关于在自定义View过程中的getHeight和getMeasureHeight()这两个的区别:
getMeasureHeight():
必须在OnMeasure()这个方法执行之后才能得到控件的宽高,一般在自定View的过程中会使用
getMeasuredHeight/Width()这个方法获取到控件的宽高.
getHeight():
必须在OnLayout这个方法执行完成后能才能得getHeight()的值,这个时候拿到的值是实际我们
能看到显示在界面上的宽高。
如果不重写onLayout对控件的摆放位置进行修改的话,这两个拿到的值是相等的。
在代码中可以用如下方式获取到getHeight和getMeasuredHeight这两个方法的值
getHeight();
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//这个是在当view在执行onLayout方法执行完成之后执行的。
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int height = headView.getHeight();
}
});
getMeasuredHeight():
view.measure(0,0)//会通知系统去测量这个view
view.getMeasuredHeight();//这个时候拿到的值是测量之后的值,不会是0了
关于在自定义ViewGroup中的移动
主要有三种方式:
layout(l,t,r,b);
scrollTo(x,y);
offsetLeftAndRight(offset); 左右同时移动
offsetTopAndBottom(offset); 上下同是移动
移动的不是子View的位置,而是移动的是当前ViewGroup的边框在移动。
/**
*当前ViewGroup的1级子view全部加载完成调用,可以初始化子view的引用
*这里只写了两个View的示例
*/
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mLeftView = getChildAt(0);
mLeftViewWidth = mLeftView.getLayoutParams().width;
Log.d("SlideMenu", "mLeftViewWidth:" + mLeftViewWidth);
mMainView = getChildAt(1);
mMainViewWidth = mLeftView.getLayoutParams().width;
/**
*下面这两个方法是拿不到控件的宽度的,可以用 mLeftView.getLayoutParams().width这个方
*法拿到控件的宽
*/
int width = getWidth();
int measuredWidth = getMeasuredWidth();
}
关于ViewDragHelper的使用
ViewDragHelper的移动效果内部也是利用了offsetLeftAndRight(offset)和offsetTopAndBottom(offset)这两个方法
这两个方法在高版本中已经实现了刷新的方法,而在低版本中,并没有实现
这会导致
onViewPositionChanged(View changedView, int left, int top, int dx, int dy)
这个方法的回调后不能移动的问题,解决的方法,重写这个方法,添加invalidate()就能实现低版本的兼容,
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
//do somthing
invalidate();
}
同样低版本的原因,view设置绽放,平移,等一些操作,如果有明确的指明兼容低本的话,可以引入
兼容低版本.png
用法:
低版本:
ViewHelper.setScaleX(view, value);
ViewHelper.setScaleY(view, value);
ViewHelper.setTranslationX(view, value);
ViewHelper.setAlpha(view,value);
……
高版本:
view.setScaleX(value);
view.setScaleY(value);
view.setAlpha(value);
view.setTranslationX(value);
……
两者效果是一样的
OnTouchEvent(event)获取action的两种方法
重绘的界面有多种:
invalidate();
postInvalidate();//线程中使用
ViewCompat.postInvalidateOnAnimation(viewgroup);//
在自定义View的自定义属性中,有很多不同的自定义属性通过xml的方式来获取,由于android 的adt14以上的版本的R.java的id类不再设置为final类型,导置我们在写成一个Library的时候,如果在获取的时写成switch case语言编译器会报错,可以写成if else的形式来获取,或者直接获取属性对应的值,这个在eclise和Android Studio都会出现的问题,不是编译器的问题