ArrayAdatper构造传值和getView()方法

博客探讨了ArrayAdapter在构造时如何将datalist传值给mObjects,并在getView()方法中使用。虽然不同构造器可能导致mObjects为null,但默认情况下getView()仍然能正常工作。内容还提到了list_item.xml布局文件以及ArrayAdapter与BaseAdapter的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用ListView和Arrayader实现一个带有图片和介绍的列表:
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //use ArrayAdapter
        lv_list = (ListView) findViewById(R.id.lv_list);
        initDataList();

        Log.e(TAG, "will new adapter");
        adapter = new MyAdapter(this, R.layout.list_item, datalist);
        //adapter = new MyAdapter(this, R.layout.list_item, 0);
        Log.e(TAG, "new adapter done");

        lv_list.setAdapter(adapter);
    }
    private void initDataList() {
        datalist = new ArrayList<>();
        for (int i = 1; i < 10; i++){
            Fruit fruit = new Fruit();
            fruit.imgId = R.drawable.adc;
            fruit.name = "lyl" + i;
            datalist.add(fruit);
        }
    }
class MyAdapter extends ArrayAdapter<Fruit>{
        private int resourceId;
        private Context myContext;
        private ViewHolder holder;

//        public MyAdapter(Context context, int resource, int textViewResourceId) {
//            super(context, resource, textViewResourceId);
//            resourceId = resource;
//        }

        public MyAdapter(Context context, int textViewResourceId, List<Fruit> objects) {
            super(context, textViewResourceId, objects);
            resourceId = textViewResourceId;
            myContext = context;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Fruit fruit = getItem(position);
            //Fruit fruit = datalist.get(position);//二者相同
            if (null == convertView){
                convertView = LayoutInflater.from(myContext).inflate(resourceId, parent, false);
                /* 
                参3为false,只让在父布局声明的Layout属性生效,并不会为这个View添加父布局。
                因为View一旦有了父布局之后,就不能添加到ListView中了
                */

                holder = new ViewHolder();
                holder.tv_list = convertView.findViewById(R.id.tv_list);
                holder.iv_list = convertView.findViewById(R.id.iv_list);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder)convertView.getTag();
            }
            holder.iv_list.setImageResource(fruit.imgId);
            holder.tv_list.setText(fruit.name);


            return convertView;
        }
    }
    class ViewHolder{
        ImageView iv_list;
        TextView tv_list;
    }
    class Fruit{
        int imgId;
        String name;
    }

list_item.xml布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@mipmap/ic_launcher"
        android:layout_margin="10dp"
        android:id="@+id/iv_list"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="name"
        android:layout_gravity="center"
        android:layout_marginLeft="10dp"
        android:textSize="20sp"
        android:id="@+id/tv_list"/>
</LinearLayout>

代码比较简单,可是在实现getView()方法时,发现

    Fruit fruit = getItem(position);
    Fruit fruit1 = datalist.get(position);

二者是同一个对象,就跟了下源码。

大家都比较熟悉的就是,继承了BaseAdapter,要实现以下四个方法

            public int getCount() ;
            public Object getItem(int position) ;
            public long getItemId(int position);
            public View getView(int position, View convertView, ViewGroup parent);

很显然,ArrayAdapter继承自BaseAdapter

public class ArrayAdapter<T> extends BaseAdapter implements Filterable, ThemedSpinnerAdapter {}

也要实现以上四种方法

            @Override
            public int getCount() {
                return mObjects.size();
            }
            @Override
            public @Nullable T getItem(int position) {
                return mObjects.get(position);
            }
            @Override
            public long getItemId(int position) {
                return position;
            }
            @Override
            public @NonNull View getView(int position, @Nullable View convertView,
                    @NonNull ViewGroup parent) {
                return createViewFromResource(mInflater, position, convertView, parent, mResource);
            }

getItem()方法, 返回了mObjects.get(position); 很自然的联想到datalist.get(position),但mObjects是如何赋值的?通过源码可以查知

            private ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
                    @IdRes int textViewResourceId, @NonNull List<T> objects, boolean objsFromResources) {
                mContext = context;
                mInflater = LayoutInflater.from(context);
                mResource = mDropDownResource = resource;
                mObjects = objects;
                mObjectsFromResources = objsFromResources;
                mFieldId = textViewResourceId;
            }
            public ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects) {
                this(context, resource, textViewResourceId, objects, false);
            }
            public ArrayAdapter(Context context, int resource, List<T> objects) {
                this(context, resource, 0, objects);
            }
            public MyAdapter(Context context, int textViewResourceId, List<Fruit> objects) {
                super(context, textViewResourceId, objects);
                resourceId = textViewResourceId;
                myContext = context;
            }
            adapter = new MyAdapter(this, R.layout.list_item, datalist);

就是datalist传值给mObjects的。所以在getView()方法中

 

    Fruit fruit = getItem(position);
    Fruit fruit1 = datalist.get(position);

二者相同。

但是调用ArrayAdapter的其他构造器,如

public MyAdapter(Context context, int resource, int textViewResourceId)

mObjects为null,但并未调用重写的getView()方法,不知为何,虽然该例子中没有textViewResourceId,且该值置为了0.

链接:inflate方法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值