覆写onLayout进行layout,含自定义ViewGroup例子
2013-03-19 18:05
381 查看
一、自定义ViewGroup例子
例子代码 - 纵向显示两个TextView
(1)编写CustomViewGroup
[plain]
view plaincopyprint?
1. CustomViewGroup继承自ViewGroup,ViewGroup是所有Layout的父类
public class CustomViewGroup extends ViewGroup {
}
2. 覆写View.onMeasure回调函数,用于计算所有child view的宽高,这里偷懒没有进行MeasureSpec模式判断
[plain]
view plaincopyprint?
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthSize, heightSize);
}
3. 覆写ViewGroup.onLayout回调函数,用于指定所有child View的位置
[plain]
view plaincopyprint?
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int mTotalHeight = 0;
// 遍历所有子视图
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
// 获取在onMeasure中计算的视图尺寸
int measureHeight = childView.getMeasuredHeight();
int measuredWidth = childView.getMeasuredWidth();
childView.layout(left, mTotalHeight, measuredWidth, mTotalHeight + measureHeight);
mTotalHeight += measureHeight;
Log.e(TAG, "changed = " + changed
+ ", left = " + left + ", top = " + top
+ ", right = " + right + ", bottom = " + bottom
+ ", measureWidth = " + measuredWidth + ", measureHieght = " + measureHeight);
}
}
3.1 onLayout回调函数参数:
left, top, right, bottom是当前ViewGroup整个在屏幕上的位置,手机屏幕是480 * 800 ,其中高度去除状态栏和title大概724
如果页面只有此ViewGroup则个参数的值
left = 0, top = 0, right = 480, bottom = 724
在此ViewGroup的上面放置一个TextView当期回调的参数值
left = 0, top = 25, right = 480, bottom = 724
3.2 child.layout如何填写参数
View是一个矩形,right和bottom也可以通过以下计算获得,其中Width 和 Height由onMeasure最终设置和决定
right = left + width
bottom = top + height
(2)创建Activity
[plain]
view plaincopyprint?
public class CustomViewGroupActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CustomViewGroup customViewGroup = new CustomViewGroup(this);
customViewGroup.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
// 添加子视图
TextView textViewOne = new TextView(this);
textViewOne.setText("a child view");
textViewOne.setBackgroundColor(Color.BLUE);
textViewOne.setLayoutParams(new LayoutParams(130, 130));
customViewGroup.addView(textViewOne);
TextView textViewTwo = new TextView(this);
textViewTwo.setText("b child view");
textViewTwo.setBackgroundColor(Color.RED);
textViewTwo.setLayoutParams(new LayoutParams(80, 80));
customViewGroup.addView(textViewTwo);
setContentView(customViewGroup);
}
}
二、 疑问
代码添加view和布局中添加view的区别?
1. 代码中添加 ViewGroup
[plain]
view plaincopyprint?
CustomViewGroup customViewGroup = new CustomViewGroup(this);
customViewGroup.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
// 添加子视图
TextView textViewOne = new TextView(this);
textViewOne.setText("a child view");
textViewOne.setBackgroundColor(Color.BLUE);
textViewOne.setLayoutParams(new LayoutParams(130, 130));
customViewGroup.addView(textViewOne);
TextView textViewTwo = new TextView(this);
textViewTwo.setText("b child view");
textViewTwo.setBackgroundColor(Color.RED);
textViewTwo.setLayoutParams(new LayoutParams(80, 80));
customViewGroup.addView(textViewTwo);
setContentView(customViewGroup);
[align=left]onLayout输出信息:[/align]
[plain]
view plaincopyprint?
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 130, measureHieght = 130
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 80, measureHieght = 80
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 130, measureHieght = 130
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 80, measureHieght = 80
[align=left]
[/align]
2. xml中配置添加ViewGroup
[plain]
view plaincopyprint?
<? xml version = "1.0" encoding = "utf-8" ?>
< com.androiddemo.CustomViewGroup xmlns:android =
"http://schemas.android.com/apk/res/android"
android:id = "@+id/custom_viewgroup"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content" >
< TextView
android:layout_width = "130dip"
android:layout_height = "130dip"
android:background = "@color/blue"
android:text = "@string/first_childview_name" />
< TextView
android:layout_width = "80dip"
android:layout_height = "80dip"
android:background = "@color/red"
android:text = "@string/second_childview_name" />
</ com.androiddemo.CustomViewGroup >
[align=left]
[/align]
[align=left]onLayout输出信息:? Width和 Height并不是TextView中设置的固定值[/align]
[plain]
view plaincopyprint?
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 195, measureHieght = 195
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 120, measureHieght = 120
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 195, measureHieght = 195
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 120, measureHieght = 120
三 、扩展
× 三个方法的区别?后这个方法最终还是调用第一个方法
[plain]
view plaincopyprint?
childView.measure(widthMeasureSpec, heightMeasureSpec);
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
× 哪些视图属性影响 measure? padding、margin
× 哪些视图属性 影响 layout? gravity
× view的上下左右和measurespec width和height的关系 ?
四、资料
Android官方文档:
Layouts
http://developer.android.com/guide/topics/ui/declaring-layout.html
细说view流程上
http://blog.csdn.net/aaa2832/article/details/7844904
细说view流程下
http://blog.csdn.net/aaa2832/article/details/7849400
昨天晚上因为CSDN博客维护,没能发出来
今日计划: 自定义CustomViewGroup + 自定义Adapter
原文地址:http://blog.csdn.net/love_world_/article/details/8108970
例子代码 - 纵向显示两个TextView
(1)编写CustomViewGroup
[plain]
view plaincopyprint?
1. CustomViewGroup继承自ViewGroup,ViewGroup是所有Layout的父类
public class CustomViewGroup extends ViewGroup {
}
2. 覆写View.onMeasure回调函数,用于计算所有child view的宽高,这里偷懒没有进行MeasureSpec模式判断
[plain]
view plaincopyprint?
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthSize, heightSize);
}
3. 覆写ViewGroup.onLayout回调函数,用于指定所有child View的位置
[plain]
view plaincopyprint?
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int mTotalHeight = 0;
// 遍历所有子视图
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
// 获取在onMeasure中计算的视图尺寸
int measureHeight = childView.getMeasuredHeight();
int measuredWidth = childView.getMeasuredWidth();
childView.layout(left, mTotalHeight, measuredWidth, mTotalHeight + measureHeight);
mTotalHeight += measureHeight;
Log.e(TAG, "changed = " + changed
+ ", left = " + left + ", top = " + top
+ ", right = " + right + ", bottom = " + bottom
+ ", measureWidth = " + measuredWidth + ", measureHieght = " + measureHeight);
}
}
3.1 onLayout回调函数参数:
left, top, right, bottom是当前ViewGroup整个在屏幕上的位置,手机屏幕是480 * 800 ,其中高度去除状态栏和title大概724
如果页面只有此ViewGroup则个参数的值
left = 0, top = 0, right = 480, bottom = 724
在此ViewGroup的上面放置一个TextView当期回调的参数值
left = 0, top = 25, right = 480, bottom = 724
3.2 child.layout如何填写参数
View是一个矩形,right和bottom也可以通过以下计算获得,其中Width 和 Height由onMeasure最终设置和决定
right = left + width
bottom = top + height
(2)创建Activity
[plain]
view plaincopyprint?
public class CustomViewGroupActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CustomViewGroup customViewGroup = new CustomViewGroup(this);
customViewGroup.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
// 添加子视图
TextView textViewOne = new TextView(this);
textViewOne.setText("a child view");
textViewOne.setBackgroundColor(Color.BLUE);
textViewOne.setLayoutParams(new LayoutParams(130, 130));
customViewGroup.addView(textViewOne);
TextView textViewTwo = new TextView(this);
textViewTwo.setText("b child view");
textViewTwo.setBackgroundColor(Color.RED);
textViewTwo.setLayoutParams(new LayoutParams(80, 80));
customViewGroup.addView(textViewTwo);
setContentView(customViewGroup);
}
}
二、 疑问
代码添加view和布局中添加view的区别?
1. 代码中添加 ViewGroup
[plain]
view plaincopyprint?
CustomViewGroup customViewGroup = new CustomViewGroup(this);
customViewGroup.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
// 添加子视图
TextView textViewOne = new TextView(this);
textViewOne.setText("a child view");
textViewOne.setBackgroundColor(Color.BLUE);
textViewOne.setLayoutParams(new LayoutParams(130, 130));
customViewGroup.addView(textViewOne);
TextView textViewTwo = new TextView(this);
textViewTwo.setText("b child view");
textViewTwo.setBackgroundColor(Color.RED);
textViewTwo.setLayoutParams(new LayoutParams(80, 80));
customViewGroup.addView(textViewTwo);
setContentView(customViewGroup);
[align=left]onLayout输出信息:[/align]
[plain]
view plaincopyprint?
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 130, measureHieght = 130
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 80, measureHieght = 80
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 130, measureHieght = 130
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 80, measureHieght = 80
[align=left]
[/align]
2. xml中配置添加ViewGroup
[plain]
view plaincopyprint?
<? xml version = "1.0" encoding = "utf-8" ?>
< com.androiddemo.CustomViewGroup xmlns:android =
"http://schemas.android.com/apk/res/android"
android:id = "@+id/custom_viewgroup"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content" >
< TextView
android:layout_width = "130dip"
android:layout_height = "130dip"
android:background = "@color/blue"
android:text = "@string/first_childview_name" />
< TextView
android:layout_width = "80dip"
android:layout_height = "80dip"
android:background = "@color/red"
android:text = "@string/second_childview_name" />
</ com.androiddemo.CustomViewGroup >
[align=left]
[/align]
[align=left]onLayout输出信息:? Width和 Height并不是TextView中设置的固定值[/align]
[plain]
view plaincopyprint?
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 195, measureHieght = 195
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 120, measureHieght = 120
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 195, measureHieght = 195
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 120, measureHieght = 120
三 、扩展
× 三个方法的区别?后这个方法最终还是调用第一个方法
[plain]
view plaincopyprint?
childView.measure(widthMeasureSpec, heightMeasureSpec);
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
× 哪些视图属性影响 measure? padding、margin
× 哪些视图属性 影响 layout? gravity
× view的上下左右和measurespec width和height的关系 ?
四、资料
Android官方文档:
Layouts
http://developer.android.com/guide/topics/ui/declaring-layout.html
细说view流程上
http://blog.csdn.net/aaa2832/article/details/7844904
细说view流程下
http://blog.csdn.net/aaa2832/article/details/7849400
昨天晚上因为CSDN博客维护,没能发出来
今日计划: 自定义CustomViewGroup + 自定义Adapter
原文地址:http://blog.csdn.net/love_world_/article/details/8108970
相关文章推荐
- 覆写onLayout进行layout,含自定义ViewGroup例子
- 覆写onLayout进行layout,含自定义ViewGroup例子
- 覆写onLayout进行layout,含自定义ViewGroup例子
- 覆写onLayout进行layout,含自定义ViewGroup例子
- 自定义view(四)覆写onLayout进行layout,含自定义ViewGroup
- 自定义Layout用ViewGroup+ListView+GridView进行滑动事件拦截
- Android自定义ViewGroup之WaterfallLayout(二)
- 自定义Viewgroup拦截事件例子
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- Android自定义ViewGroup:onMeasure与onLayout(1)
- Android自定义ViewGroup实现堆叠头像的点赞Layout
- 自定义View添加到Viewgroup中layoutparams为空的记录
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu[转]
- Android开发实践:自定义ViewGroup的onLayout()分析
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
- 简单的例子了解自定义ViewGroup(一)
- 自定义ViewGroup-自定义LayoutParams支持显示方位
- 简单的例子了解自定义ViewGroup(一)
- 自定义ViewGroup-自动换行Layout