android 自定义ViewGroup
上文讲述了自定义的几个基本步骤,这篇接着上文讲述一下如何自定义viewgroup 。
代码参见 * https://github.com/lijing01/AndroidDemo
ViewGroup 定义
is a special view that can contain other views (called children.) The view group is the base >class for layouts and views containers. This class also defines theViewGroup.LayoutParams
class which serves as the base class for layouts parameters.
Also see ViewGroup.LayoutParams
for layout attributes.
ViewGroup 作用
根据子view 的测量模式给出建议的宽高,决定子view 的位置,为什么是建议的宽高,因为子view 和viewGroup 的宽高都可以设置warp_content,这样需要计算出子view 的宽高才能获取到viewGroup的宽高。给其他view或viewGroup 给出 layoutparamas 的基类。
ViewGroup 自定义过程
我们通过实现一个horizonal viewGroup 来演示这些功能。这个custom viewGroup 有些类似与下面的LinearLayout
<code><LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"/></code>
<com.tracelijing.androiddemo.customview.CustomViewGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/darkgoldenrod">
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorPrimary"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorAccent"
android:layout_marginLeft="10dp"/>
</com.tracelijing.androiddemo.customview.CustomViewGroup>
onmesure
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int desireWidth = 0, desireHeight = 0;
int count = getChildCount();
for (int i = 0; i < count; i++) {
View childView = getChildAt(i);
if (childView.getVisibility() != View.GONE) {
MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
//将measureChild改为measureChildWithMargin
measureChildWithMargins(childView, widthMeasureSpec, 0,
heightMeasureSpec, 0);
//这里在计算宽度时加上margin
desireWidth += childView.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
desireHeight = Math
.max(desireHeight, childView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
}
}
desireWidth += getPaddingLeft() + getPaddingRight();
desireHeight += getPaddingTop() + getPaddingBottom();
// see if the size is big enough
desireWidth = Math.max(desireWidth, getSuggestedMinimumWidth());
desireHeight = Math.max(desireHeight, getSuggestedMinimumHeight());
setMeasuredDimension(resolveSize(desireWidth, widthMeasureSpec),
resolveSize(desireHeight, heightMeasureSpec));
}
这里我们通过通过viewGroup 的测量模式,测量出子view 宽高,因为这里我们customVieewGroup 的宽高设置的是 warp_content, 并且是类似于水平方向的ViewGroup, 所以我们可以根据子view 的大小计算出viewGroup 的大小。
onlayout
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int parentLeft = getPaddingLeft();
int parentTop = getPaddingTop();
int left = parentLeft;
int top = parentTop;
int count = getChildCount();
for (int i = 0; i < count; i++) {
View view = getChildAt(i);
if (view.getVisibility() != View.GONE) {
MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
left += lp.leftMargin;
final int childWidth = view.getMeasuredWidth();
final int childHeight = view.getMeasuredHeight();
view.layout(left, top+lp.topMargin, left + childWidth, top + childHeight+lp.bottomMargin);
left += childWidth + lp.rightMargin;
}
}
}
onlayout 的左右是对所有的子view 进行定位。代码很简单,我们循环遍历每个子view并把前一个view 的结束位置作为它的起始位置。参数为:
- changed— 该参数指出当前ViewGroup的尺寸或者位置是否发生了改变
- Left — view的x轴起始位置
- Top — view的y轴起始位置
- Right — view的x轴结束位置
- Bottom — view的y轴结束位置
生成LayoutParams
public MarginLayoutParams generateLayoutParams(AttributeSet attrs)
{
return new MarginLayoutParams(getContext(), attrs);
}
这里我们先使用ViewGroup 的marginLayoutParams,这样我们就可以使用如上面xml 中给子view 添加margin 的效果。
Paste_Image.png运行效果如图,我们实现了带margin 效果的水平的类LinearLayout的效果。
自定义view 相关文章
android 自定义view
Reffer
- http://blog.csdn.net/lmj623565791/article/details/38339817
- http://www.cnblogs.com/Jaylong/p/viewgroup.html
- http://blog.csdn.net/lmj623565791/article/details/38352503
- http://www.jianshu.com/p/11e1a9da6a3d
- http://my.oschina.net/fengheju/blog/196266
- http://javatechig.com/android/how-to-create-custom-layout-in-android-by-extending-viewgroup-class
- http://developer.android.com/reference/android/view/ViewGroup.html