标签:lis 直接 etc 没有 视图 activity size spec 计算
第一步:复写onMeasure方法。
先measureChild方法 测量出所有子控件的moMeasure。
//1,测量自身 super.onMeasure(widthMeasureSpec, heightMeasureSpec); //2,为每个子view计算测量的限制信息 int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); //3,把上一步确定的限制信息,传递给每一个子view,然后子view开始measure自己的尺寸 int childCount = getChildCount();//子view的个数 for (int i = 0; i < childCount; i++) { View child = getChildAt(i); ViewGroup.LayoutParams lp = child.getLayoutParams(); int childWidthSpec = getChildMeasureSpec(widthMeasureSpec, 0, lp.width); int childHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0, lp.height); child.measure(childWidthSpec, childHeightSpec); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { for (int i = 0; i < childCount; i++) { View child = getChildAt(i); //测量子view 获取到当前子view的测量的宽度和高度 measureChild(child, widthMeasureSpec, heightMeasureSpec); } }
调用 setMeasuredDimension(int measuredWidth, int measuredHeight)设置测绘后的大小.
// 保存自身的尺寸 setMeasuredDimension(width, height);
第二步:onLayout方法
在方法调用getChildCount方法 获取到子条目数量。
用for循环遍历出每一个子条目的对象。 通过对象.layout方法 给子控件设置摆放位置。
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // 遍历子view的onLayout方法 int left = 0; int top = 0; int right = 0; int bottom = 0; int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); left = i * OFFSET; right = left + child.getMeasuredWidth(); bottom = top + child.getMeasuredHeight(); child.layout(left, top, right, bottom);//不考虑padding,margin等 top += child.getMeasuredHeight(); } }
第三步:onDraw方法
首先调用ViewGroup的disPatchDraw方法绘制ViewGroup。然后调用View中的onDraw方进行绘制。
需要调用MeasureSpec类可以获取到View的模式和大小:MeasureSpec.getMode() 获取模式、MeasureSpec.getSize() 获取大小。?
这里View模式如下:
MeasureSpec.EXACTLY 精确值模式: 表示父控件已经确切的指定了子视图的大小。
MeasureSpec.AT_MOST 最大值模式:表示子查看具体大小没有尺寸限制,但是存在上限,上限一般为父视图大小。
MeasureSpec.UNSPECIFIED 父控件没有给子视图任何限制,子视图可以设置为任意大小。这个模式会用到呢,可以看一下:https://www.cnblogs.com/liushilin/p/11055741.html
requestLayout方法会导致View的onMeasure、onLayout、onDraw方法被调用。
invalidate方法则只会导致View的onDraw方法被调用。
invalidate方法和postInvalidate方法都是用于进行View的刷新,invalidate方法应用在UI线程中,而postInvalidate方法应用在非UI线程中,用于将线程切换到UI线程,postInvalidate方法实现了消息机制,最终调用的也是invalidate方法来刷新View。
我们在自定义View时,当需要刷新View时,如果是在UI线程中,那就直接调用invalidate方法,如果是在非UI线程中,那就通过postInvalidate方法来刷新View。
invalidate方法最终调用的是ViewRootImpl中的performTraversals来重新绘制View。
----------------------------------------------------------------------------------------------------------------
从事件分发机制来分析,在响应事件的时候,如果同时绑定了长按和点击事件,长按事件触发时默认不做处理的话会优先响应长按事件,如果长按事件里面没有消费掉改事件,根据事件分发机制,该事件会继续传递,直到有控件把它消费了。明白了这个道理,长按事件和短按事件同时响应的问题就不难解决了,在同时绑定两个事件的情况下,如果先点击的是短按事件没问题,自然触发不到长按事件,但是如果先触发的是长按事件如果当前return false的话代表当前事件需要继续向下传递所以短按事件就被响应了,这种情况在onLongClick中返回true即可,代表当前有能力消费掉该事件,阻止事件向下传递,短按事件就不会被触发了。
//longClick事件 textView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { onItemClickListener.onItemLongClick(myViewHolder.textView,position); return true; //return true即可解决长按事件跟点击事件同时响应的问题 } });
标签:lis 直接 etc 没有 视图 activity size spec 计算
原文地址:https://www.cnblogs.com/renhui/p/12527634.html