【Android】【ViewGroup】【ListView】ListView的一些细节
2016-07-27 13:39
507 查看
为什么我们在Item根布局xml中设置LayoutParams无效?
类似于上面这种 layout_height =”100dp”,然后运行后发现 高度还是wrap_content,这是为什么呢?
在我们的getView方法中
被注释的代码可以成功的设置Item的高度,但是没被注释的代码却不能.
是不是可以这么理解,tv = (TextView) getLayoutInflater().inflate(R.layout.layout_item_diy_view, null);
这句代码执行的时候 tv根本没有被加入到父布局中,我们在xml设置的 android:layout_是layout的属性是子View在父布局如何呈现的属性,所以这样设置根本是无效的,事实证明是的,在inflater的源码中
也未发现我们设置的android:layout_属性,但是你会发现我们在TextView外面再嵌套一层布局,TextView中设置的android:layout_属性可以了,但是TextView外层的android:layout_属性又不行了.那为什么我们在代码中setLayoutParams(new ViewGroup.LayoutParams(-1,100)); 有可以呢? 还有你们也许还会发现不管Item的根布局的android:layout_属性如何设置 高度都是wrap_content 宽度都是 match_parent,
这是因为在AbsListView中有这样一个方法
在这个方法中就这样一段代码
final View child = mAdapter.getView(position, scrapView, this);
这个很眼熟不是吗?就是我们的getView方法啊
然后是这个方法
setItemViewLayoutParams(child, position);
答案一目了然啊
final ViewGroup.LayoutParams vlp = child.getLayoutParams();
LayoutParams lp;
if (vlp == null) {
lp = (LayoutParams) generateDefaultLayoutParams();
} else if (!checkLayoutParams(vlp)) {
lp = (LayoutParams) generateLayoutParams(vlp);
} else {
lp = (LayoutParams) vlp;
}
先获取 getLayoutParams,如果是null 调用generateDefaultLayoutParams(),
否则判断是否是 AbsListView.LayoutParams的实例或者其子类的实例,
这就是为什么我们在getView中通过代码设置LayoutParams可以成功;
在generateDefaultLayoutParams()方法中
可以看到这就是为什么默认 宽度是match_parent ,高度是 wrap_content
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/textView1" android:layout_width="match_parent" android:background="#FFFF0000" android:layout_height="100dp" android:text="New Text"/>
类似于上面这种 layout_height =”100dp”,然后运行后发现 高度还是wrap_content,这是为什么呢?
在我们的getView方法中
final TextView tv; if (convertView == null) { // tv = new TextView(DiyViewActivity.this); // tv.setLayoutParams(new ViewGroup.LayoutParams(-1,100)); // tv.setBackgroundColor(0xFFFF0000); tv = (TextView) getLayoutInflater().inflate(R.layout.layout_item_diy_view, null); } else { tv = (TextView) convertView; }
被注释的代码可以成功的设置Item的高度,但是没被注释的代码却不能.
是不是可以这么理解,tv = (TextView) getLayoutInflater().inflate(R.layout.layout_item_diy_view, null);
这句代码执行的时候 tv根本没有被加入到父布局中,我们在xml设置的 android:layout_是layout的属性是子View在父布局如何呈现的属性,所以这样设置根本是无效的,事实证明是的,在inflater的源码中
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot)
也未发现我们设置的android:layout_属性,但是你会发现我们在TextView外面再嵌套一层布局,TextView中设置的android:layout_属性可以了,但是TextView外层的android:layout_属性又不行了.那为什么我们在代码中setLayoutParams(new ViewGroup.LayoutParams(-1,100)); 有可以呢? 还有你们也许还会发现不管Item的根布局的android:layout_属性如何设置 高度都是wrap_content 宽度都是 match_parent,
这是因为在AbsListView中有这样一个方法
View obtainView(int position, boolean[] isScrap)
在这个方法中就这样一段代码
final View scrapView = mRecycler.getScrapView(position); final View child = mAdapter.getView(position, scrapView, this); if (scrapView != null) { if (child != scrapView) { // Failed to re-bind the data, return scrap to the heap. mRecycler.addScrapView(scrapView, position); } else { isScrap[0] = true; // Finish the temporary detach started in addScrapView(). child.dispatchFinishTemporaryDetach(); } } if (mCacheColorHint != 0) { child.setDrawingCacheBackgroundColor(mCacheColorHint); } if (child.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); } setItemViewLayoutParams(child, position);
final View child = mAdapter.getView(position, scrapView, this);
这个很眼熟不是吗?就是我们的getView方法啊
然后是这个方法
setItemViewLayoutParams(child, position);
private void setItemViewLayoutParams(View child, int position) { final ViewGroup.LayoutParams vlp = child.getLayoutParams(); LayoutParams lp; if (vlp == null) { lp = (LayoutParams) generateDefaultLayoutParams(); } else if (!checkLayoutParams(vlp)) { lp = (LayoutParams) generateLayoutParams(vlp); } else { lp = (LayoutParams) vlp; } if (mAdapterHasStableIds) { lp.itemId = mAdapter.getItemId(position); } lp.viewType = mAdapter.getItemViewType(position); if (lp != vlp) { child.setLayoutParams(lp); } }
答案一目了然啊
final ViewGroup.LayoutParams vlp = child.getLayoutParams();
LayoutParams lp;
if (vlp == null) {
lp = (LayoutParams) generateDefaultLayoutParams();
} else if (!checkLayoutParams(vlp)) {
lp = (LayoutParams) generateLayoutParams(vlp);
} else {
lp = (LayoutParams) vlp;
}
先获取 getLayoutParams,如果是null 调用generateDefaultLayoutParams(),
否则判断是否是 AbsListView.LayoutParams的实例或者其子类的实例,
这就是为什么我们在getView中通过代码设置LayoutParams可以成功;
在generateDefaultLayoutParams()方法中
@Override protected ViewGroup.LayoutParams generateDefaultLayoutParams() { return new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0); }
可以看到这就是为什么默认 宽度是match_parent ,高度是 wrap_content
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories