Andoird 自定义ViewGroup
来源:互联网 发布:北京房山网络职业学院 编辑:程序博客网 时间:2024/06/02 03:20
1.自定义ViewGroup
主要关注两点测量和布局:
onMeasure
测量和保存各个视图和子视图的位置信息
onLayout
遍历所有子视图绘制
2.构造函数
1.res/values/attrs.xml
自定义视图的属性
<?xml version="1.0" encoding="utf-8" ?><resources> <declare-styleable name="CascadeLayout"> <attr name="horizontal_spacing" format="dimension" /> <attr name="vertical_spacing" format="dimension" /> </declare-styleable></resources>
2.res/values/dimens.xml
自定义视图属性的默认值
<resources> <dimen name="horizontal_spacing">16dp</dimen> <dimen name="vertical_spacing">16dp</dimen></resources>
- java 代码中使用。
private int mHorizontalSpacing; private int mVerticalSpacing; public CascadeLayout(Context context, AttributeSet attributeSet) { super(context, attributeSet); TypedArray a = context.obtainStyledAttributes(attributeSet, R.styleable.CascadeLayout); try { mHorizontalSpacing = a.getDimensionPixelSize(R.styleable.CascadeLayout_horizontal_spacing, getResources().getDimensionPixelSize(R.dimen.horizontal_spacing)); mVerticalSpacing = a.getDimensionPixelSize(R.styleable.CascadeLayout_vertical_spacing, getResources().getDimensionPixelSize(R.dimen.vertical_spacing)); } finally { a.recycle(); } }
3. 布局 写法
- 自定义属性使用
命名空间
a)eclipse写法,android studio也适用
类似系统自带属性命名空间 xmlns:android=”http://schemas.android.com/apk/res/android”
将res/android 换成你自定义view 所属的包名
xmlns:cascade=”http://schemas.android.com/apk/com.lq.viewpractice.viewgroup.CascadeLayout”
b)android studio写法,eclipse 不能用
使用res-auto
xmlns:cascade=”http://schemas.android.com/apk/res-auto”
引用lib 和自定义的view 都智能用res-auto
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cascade="http://schemas.android.com/apk/com.lq.viewpractice.viewgroup.CascadeLayout" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.lq.viewpractice.ViewGroupTestActivity"> <com.lq.viewpractice.viewgroup.CascadeLayout android:layout_width="match_parent" android:layout_height="match_parent" cascade:horizontal_spacing="30dp" cascade:vertical_spacing="20dp"> <View android:layout_width="100dp" android:layout_height="150dp" android:background="#FF0000" /> <View android:layout_width="100dp" android:layout_height="150dp" android:background="#00FF00" /> <View android:layout_width="100dp" android:layout_height="150dp" android:background="#0000FF" /> </com.lq.viewpractice.viewgroup.CascadeLayout></RelativeLayout>
4. 自定义LayoutParams
这个类的用途就是保存每个子视图的x,y轴位置。这里把它定义为静态内部类。
public static class LayoutParams extends ViewGroup.LayoutParams { int x; int y; public int verticalSpacing; public LayoutParams(Context context, AttributeSet attrs) { super(context, attrs); } public LayoutParams(int w, int h) { super(w, h); } }
除此之外,还需要重写一些方法,checkLayoutParams()、generateDefaultLayoutParams()等,这个方法在不同ViewGroup之间往往是相同的。
@Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { return p instanceof LayoutParams; } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); } @Override protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { return new LayoutParams(p.width, p.height); }
5. 核心代码 测量 onMeasure
测量子视图的坐标。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = getPaddingLeft(); int height = getPaddingTop(); int verticalSpacing; final int count = getChildCount(); for (int i = 0; i < count; i++) { verticalSpacing = mVerticalSpacing; View child = getChildAt(i); measureChild(child, widthMeasureSpec, heightMeasureSpec); LayoutParams lp = (LayoutParams) child.getLayoutParams(); width = getPaddingLeft() + mHorizontalSpacing * i; //保存每个子视图的x,y轴坐标 lp.x = width; lp.y = height; if (lp.verticalSpacing >= 0) { verticalSpacing += lp.verticalSpacing; } width += width; height += verticalSpacing; } width += getPaddingRight(); height += getChildAt(getChildCount() - 1).getMeasuredHeight() + getPaddingBottom(); setMeasuredDimension(resolveSize(width, widthMeasureSpec), resolveSize(height, heightMeasureSpec)); }
6.核心代码 布局 onLayout
循环调用子view 布局。
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y + child.getMeasuredHeight()); } }
7. 参考链接
http://www.w2bc.com/Article/59242
http://blog.csdn.net/manoel/article/details/39062737
8.demo地址
0 0
- Andoird 自定义ViewGroup
- Andoird 自定义ViewGroup实现竖向引导界面
- Andoird 自定义ViewGroup实现竖向引导界面
- Andoird 自定义ViewGroup实现竖向引导界面
- Andoird 自定义ViewGroup实现竖向引导界面
- Andoird 自定义ViewGroup实现竖向引导界面
- Andoird 自定义ViewGroup实现竖向引导界面
- Andoird自定义ViewGroup实现竖向引导界面
- Andoird 自定义ViewGroup实现竖向引导界面
- Andoird 自定义ViewGroup实现竖向引导界面
- Andoird 自定义ViewGroup实现竖向Viewpager
- Andoird 自定义ViewGroup实现竖向引导界面
- 对Hongyang大神文章《Andoird 自定义ViewGroup实现竖向引导界面》的阅读笔记
- 自定义ViewGroup
- 自定义ViewGroup
- 自定义ViewGroup
- 自定义ViewGroup
- 自定义viewGroup
- [转]使 Windows 下的 Qt 应用程序获得 Administrator 权限
- 电脑桌面图标或者文件左下角出现蓝色问号解决办法
- static作用
- JS-2---表达式和运算符
- bootstrap table 插件 从服务器请求数据 分页
- Andoird 自定义ViewGroup
- iOS开发中常见崩溃原因汇总,你遇到了吗?
- 关于未来,关于我
- 事务声明声明式事务和编程式事务介绍
- RecyclerView使用介绍
- ProgressBar 旋转
- Redis客户端之Spring整合Jedis
- 函数增删改查数据库
- android studio降低编译版本出错