写RecycleView适配器时,发现inflate的问题

问题:在写RecycleView适配器时,发现inflate用不同的方法,UI效果不一样:


item布局就是一个TextView,

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/textview"
          android:layout_width="match_parent"
          android:layout_height="72dp"
          android:background="#55ff0000"
          android:gravity="center"
          android:orientation="vertical">
</TextView>


适配器如下:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private List<String> data;
    Context mContext;
    LayoutInflater mInflater;
    
    public MyAdapter(List<String> data, Context mContext) {
        this.mContext=mContext;
        this.data=data;
        mInflater = LayoutInflater.from(mContext);
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
        //R.layout.item, null,root!=null
        View inflate = View.inflate(mContext, R.layout.item, null);
        //View view = mInflater.inflate(R.layout.item, parent,false);
        Log.i("at22", "onCreateViewHolder: "+parent);
        return new MyViewHolder(inflate);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.mTextView.setText(data.get(position));
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView mTextView;
        public MyViewHolder(View itemView) {
            super(itemView);
            mTextView = (TextView) itemView.findViewById(R.id.textview);
        }
    }
}


在适配器中常用加载布局方法:

1.View的静态方法 View.inflate

public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
    LayoutInflater factory = LayoutInflater.from(context);
    return factory.inflate(resource, root);
}
内部也是调用了LayoutInflater的方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {}
    return inflate(resource, root, root != null);
}

继续跟踪方法的调用

//一般这么调用的方法

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
    final Resources res = getContext().getResources();
    if (DEBUG) {
        Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
                + Integer.toHexString(resource) + ")");
    }

    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) {
//最后都是调用这个方法来解析xml
	......	
}

View inflate = View.inflate(mContext, R.layout.item, null)-----------------------显示效果如图1
可见传入的root为null,
boolean attachToRoot=(root!=null),可见attachToRoot=false;
这种情况下,root=null,attachToRoot=false;
当我们用View的静态方法inflate( )时候,发现attachToRoot=(root!=null)这一点;
2.直接用
mInflater = LayoutInflater.from(mContext);
View view = mInflater.inflate(R.layout.item, parent,false);//public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
其中parent就是RecycleView,通过打印发现的
可见传入的root为RecycleView,boolean attachToRoot=false;
最后的效果图如第二个图所示
那么attachToRoot又表示的什么含义呢?/--------来自郭神博客:http://blog.csdn.net/guolin_blog/article/details/12921889


1. 如果root为null,attachToRoot将失去作用,设置任何值都没有意义。

2. 如果root不为null,attachToRoot设为true,则会给加载的布局文件的指定一个父布局,即root。

3. 如果root不为null,attachToRoot设为false,则会将布局文件最外层的所有layout属性进行设置,当该view被添加到父view当中时,这些layout属性会自动生效。

4. 在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。


对比下效果图:
第一种是在root为null,attachToRoot为false的情况下
第二种是在root不为null,attachToRoot为false的情况下,如果将attachToRoot改为true会报错:
                   <pre name="code" class="html">java.lang.IllegalStateException: The specified child already has a                              parent. You must call removeView() on the child's parent first.
在第二种的基础上,将root修改为null,发现attachToRoot修改了,不影响,效果都一样
1,LayoutInflater的内部实现方式,主要是pull解析布局文件,然后通过反射的方式生成控件对象,形成dom树结构;
2,setContentView方法会给xml布局文件添加一个FrameLayout;
3,视图界面都是由两个部分组成:标题栏和内容栏,标题栏是系统自动给我们添加的

没有更多推荐了,返回首页