博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解Adapter<2>
阅读量:6496 次
发布时间:2019-06-24

本文共 5691 字,大约阅读时间需要 18 分钟。

hot3.png

今日研究研究ListView的onTouch事件,无意发现了一个问题:

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {    MyAdapterHolder holder = null;    if (convertView == null) {        holder = new MyAdapterHolder();        convertView = inflater.inflate(R.layout.item, null);        holder.textView = (TextView) convertView.findViewById(R.id.text);        convertView.setTag(holder);    } else {        holder = (MyAdapterHolder) convertView.getTag();    }    holder.textView.setText("position = " + position);    return convertView;}

运行发现结果截图如下:

同志们看到没有?我设置的明明是android:layout_height="100dp",可是运行出来的结果高度很明显不够。

因此我在convertView = inflater.inflate(R.layout.item, null);行处打了断点,调试发现

mLayoutParams = null.

我们姑且先不管为什么convertView.mLayoutParams = null,我们继续从源码中寻找答案。

我想应该从调用getView( )的地方入手。

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    // Sets up mListPadding    ...    mItemCount = mAdapter == null ? 0 : mAdapter.getCount();    if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED            || heightMode == MeasureSpec.UNSPECIFIED)) {        final View child = obtainView(0, mIsScrap);        ...    }    ...}

此处调用absListView的中obtainView( )获取View,调至此方法我们继续分析:

View obtainView(int position, boolean[] isScrap) {    ...    final View transientView = mRecycler.getTransientStateView(position);    {}    ...    setItemViewLayoutParams(child, position);    ...    return child;}
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);    }}

有前面可知convertView.mLayoutParams = null,因此我们查看 generateDefaultLayoutParams():

@Overrideprotected ViewGroup.LayoutParams generateDefaultLayoutParams() {    return new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,            ViewGroup.LayoutParams.WRAP_CONTENT, 0);}

看到这里我们应该都明白为什么上面为什么会出现酱紫情况了。

可是,问题又来了,convertView.mLayoutParams = null?为什么?

老办法,看源码:

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {    ...    final XmlResourceParser parser = res.getLayout(resource);    try {        return inflate(parser, root, attachToRoot);    } finally {        parser.close();    }}
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {    synchronized (mConstructorArgs) {        ...        final AttributeSet attrs = Xml.asAttributeSet(parser);        ...        View result = root;        try {            // Look for the root node.            ....            final String name = parser.getName();            ...            if (TAG_MERGE.equals(name)) {                ...            } else {                // Temp is the root view that was found in the xml                final View temp = createViewFromTag(root, name, inflaterContext, attrs);                ViewGroup.LayoutParams params = null;                if (root != null) {                    if (DEBUG) {                        System.out.println("Creating params from root: " +                                root);                    }                    // Create layout params that match root, if supplied                    params = root.generateLayoutParams(attrs);                    if (!attachToRoot) {                        // Set the layout params for temp if we are not                        // attaching. (If we are, we use addView, below)                        temp.setLayoutParams(params);                    }                }                if (DEBUG) {                    System.out.println("-----> start inflating children");                }                // Inflate all children under temp against its context.                rInflateChildren(parser, temp, attrs, true);                if (DEBUG) {                    System.out.println("-----> done inflating children");                }                // We are supposed to attach all the views we found (int temp)                // to root. Do that now.                if (root != null && attachToRoot) {                    root.addView(temp, params);                }                // Decide whether to return the root that was passed in or the                // top view found in xml.                if (root == null || !attachToRoot) {                    result = temp;                }            }        }         ...        return result;    }}

由此代码我们发现,只有root != null 的情况下才会有root.addView(temp, params);设置layoutParams,可是我们传的root = null,所以有convertView.mLayoutParams = null。

后面我又测试了root !=null,即:

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {    MyAdapterHolder holder = null;    if (convertView == null) {        holder = new MyAdapterHolder();        convertView = inflater.inflate(R.layout.item, parent);        holder.textView = (TextView) convertView.findViewById(R.id.text);        convertView.setTag(holder);    } else {        holder = (MyAdapterHolder) convertView.getTag();    }    holder.textView.setText("position = " + position);    return convertView;}

发现还是报错了:

@Overridepublic void addView(View child, LayoutParams params) {    throw new UnsupportedOperationException("addView(View, LayoutParams) "            + "is not supported in AdapterView");}

嗯,就是这个异常。不支持啊!

 

 

转载于:https://my.oschina.net/u/3342652/blog/864015

你可能感兴趣的文章
[Array]189. Rotate Array
查看>>
iuap
查看>>
inkscape
查看>>
关于C语言中单双引号的问题
查看>>
I00003 贝尔三角形
查看>>
HDU1200 POJ2039 ZOJ2208 UVALive3084 To and Fro【密码】
查看>>
CCF201403-1 相反数(100分)
查看>>
表单通过连接数据库数据进行验证
查看>>
redis hash操作 list列表操作
查看>>
利用Hibernate 框架,实现对数据库的增删改查
查看>>
mysql开启远程连接权限
查看>>
关于商米D1S,USB默认权限在关机后丢失的FAQ
查看>>
css3 text-transform变形动画
查看>>
scikit-learn中文api
查看>>
一个完整的大作业--广州市社会保障(市民)卡服务网
查看>>
迭代器和生成器
查看>>
Vue 组件之间传值
查看>>
指向方法之委托(一)
查看>>
2013 Multi-University Training Contest 3 部分解题报告
查看>>
Linux 网桥配置命令:brctl
查看>>