ListView的Adapter
来源:互联网 发布:无人机地面站软件 编辑:程序博客网 时间:2024/06/05 01:57
**
关于ListView控件的适配器Adapter
**
本人也只是刚刚接触安卓开发,就想对用的比较多的ListView开始进行一点知识的整理。就拿自己写的一个消息列表来作为例子来整理一波吧。
在主活动的布局文件中就只需要加入一个ListView的控件。
<ListView android:layout_marginTop="5dp" android:dividerHeight="5dp" android:divider="#99d9db" android:id="@+id/lv_msg" android:layout_width="match_parent" android:layout_height="match_parent"></ListView>
这里也没什么好讲的…
然后我们再来定义一波ListView中的item布局,我在这里只是简单地设置了一个头像的ImageView、一个用户名的TextView和一条内容的TextViews并为之一一设置ID。
<LinearLayout android:layout_marginTop="5dp" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:layout_height="60dp"> <ImageView android:id="@+id/iv_head" android:layout_width="65dp" android:layout_height="55dp" /> </LinearLayout> <LinearLayout android:orientation="vertical" android:layout_weight="4" android:layout_width="0dp" android:layout_height="60dp"> <TextView android:id="@+id/tv_name" android:layout_marginTop="5dp" android:layout_marginLeft="5dp" android:layout_width="100dp" android:layout_height="20dp" /> <TextView android:id="@+id/tv_msg" android:maxLines="1" android:layout_marginTop="2dp" android:layout_marginLeft="5dp" android:layout_width="match_parent" android:layout_height="30dp" /> </LinearLayout></LinearLayout>
接下来就是重头戏了——一个自定义的适配器。
这也是我今天挺想去总结的一个点,因为我个人觉得适配器就是一个ListView的灵魂,操控着它的数据更新、操控着它的视图展示等等。
常用的适配器有BaseAdapter,ArrayAdapter,SimpleAdapter等等。而SimpleAdapter在三者中又用的是比较少的,因为SimpleAdapter已经在内部被写好,改动的地方比较少,因此灵活性较低,不宜被继承改动。而ArrayAdapter则是由BaseAdapter派生而来,具有BaseAdapter的全部功能,再加上继承自ArrayAdapter的适配器在实例化时可直接使用泛型构造,从而使自定义适配器更加灵活。而在本例中的适配器继承的便是ArrayAdapter(因为使用了自定义的一个Msg类。)。
private int resourceId;private List<Msg> message = new ArrayList<Msg>();public MsgAdapter(@NonNull Context context, @LayoutRes int resource) { super(context, resource); resourceId = resource;}public MsgAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<Msg> objects) { super(context, resource, objects); resourceId = resource; this.message = objects;}public MsgAdapter(@NonNull Context context, @LayoutRes int resource, @IdRes int textViewResourceId) { super(context, resource, textViewResourceId);}public MsgAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull Msg[] objects) { super(context, resource, objects);}public MsgAdapter(@NonNull Context context, @LayoutRes int resource, @IdRes int textViewResourceId, @NonNull Msg[] objects) { super(context, resource, textViewResourceId, objects);}public MsgAdapter(@NonNull Context context, @LayoutRes int resource, @IdRes int textViewResourceId, @NonNull List<Msg> objects) { super(context, resource, textViewResourceId, objects);}
可见,在继承了ArrayAdater后,IDE会提示你要创建构造方法,而该适配器有6种构造方法。其中的几个参数如context指依附的活动,resource指加载item的布局id,List object则指列表中的对象等等就不一一赘述了,毕竟见名知意。
而在自定义的adapter中还可以重写内部方法。
(一)public View getView(int position, View convertView, ViewGroup parent)
此方法实现了加载每一个item的布局的功能,最终返回的是一个View对象,通常与类ViewHolder连用。此类只定义item的布局中存在的控件,以方便在加载整个列表布局时,更加快速地从类里取出存在的item布局。即若某个item的布局若存在于ViewHolder,则不需再重新实例一个新的对象,重新加载该item布局,而是从ViewHolder中取出该item的布局,直接展示在ui层。
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { View item; ViewHolder mViewHolder; //获取当前位置的position以填充布局 Msg msg = getItem(position); //如果当前view为空,则将当前view填充入viewholder中,否则从viewholder中回调出来 if (convertView == null) { //将当前view加载出来 item = LayoutInflater.from(getContext()).inflate(resourceId, null); mViewHolder = new ViewHolder(); mViewHolder.head = (ImageView) item.findViewById(R.id.iv_head); mViewHolder.name = (TextView) item.findViewById(R.id.tv_name); mViewHolder.msg = (TextView) item.findViewById(R.id.tv_msg); item.setTag(mViewHolder); } else { item = convertView; mViewHolder = (ViewHolder) item.getTag(); } mViewHolder.head.setImageResource(msg.getImageResource());//设定头像 mViewHolder.name.setText(msg.getName());//设定用户名 mViewHolder.msg.setText(msg.getMsg());//设定消息 return item;}
(二)public int getCount()、public int getPosition(T item)、public T getItem(int position)
这些方法分别是获取整个列表的长度,即item的数目,一般返回的是mList.size();获取当前item的位置,返回的是item在列表的位置;获取当前位置的item,返回的是position中对应的item对象。
@Overridepublic int getCount() { return message.size();}//获取item的位置@Overridepublic int getPosition(@Nullable Msg item) { return super.getPosition(item);}//获取当前位置的item@Nullable@Overridepublic Msg getItem(int position) { return super.getItem(position);}
(三)public void notifyDataSetChanged()
这个方法是用来刷新列表的。比如当你需要删除列表中的某个item时,点击删除后若当前的适配器没有调用此方法(即没有mAdapter.notifyDataSetChanged()),IDE会报错。而这个方法也可以在Activity的onResume()方法中调用,从而在跳转过程后,回到当前页面仍然保持最新的列表状态。
@Overridepublic void notifyDataSetChanged() { super.notifyDataSetChanged();}
整个MsgAdapter代码如下:
/** * Created by Carson on 2017/7/15. */public class MsgAdapter extends ArrayAdapter<Msg>{ private int resourceId; private List<Msg> message = new ArrayList<Msg>(); public MsgAdapter(@NonNull Context context, @LayoutRes int resource) { super(context, resource); resourceId = resource; } public MsgAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<Msg> objects) { super(context, resource, objects); resourceId = resource; this.message = objects; } //创建item的临时存储器,提升上下拉动时的加载的速度 class ViewHolder { ImageView head; TextView name, msg; } //获取列表的个数 @Override public int getCount() { return message.size(); } //获取item的位置 @Override public int getPosition(@Nullable Msg item) { return super.getPosition(item); } //获取当前位置的item @Nullable @Override public Msg getItem(int position) { return super.getItem(position); } //获取item的view @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { View item; ViewHolder mViewHolder; //获取当前位置的position以填充布局 Msg msg = getItem(position); //如果当前view为空,则将当前view填充入viewholder中,否则从viewholder中回调出来 if (convertView == null) { //将当前view加载出来 item = LayoutInflater.from(getContext()).inflate(resourceId, null); mViewHolder = new ViewHolder(); mViewHolder.head = (ImageView) item.findViewById(R.id.iv_head); mViewHolder.name = (TextView) item.findViewById(R.id.tv_name); mViewHolder.msg = (TextView) item.findViewById(R.id.tv_msg); item.setTag(mViewHolder); } else { item = convertView; mViewHolder = (ViewHolder) item.getTag(); } mViewHolder.head.setImageResource(msg.getImageResource());//设定头像 mViewHolder.name.setText(msg.getName());//设定用户名 mViewHolder.msg.setText(msg.getMsg());//设定消息 return item; } @Override public void notifyDataSetChanged() { super.notifyDataSetChanged(); }}
Activity的代码:
public class MsgActivity extends AppCompatActivity { private List<Msg> mList; private MsgAdapter mAdapter; private ListView mListView; //随机定义一些图片、用户名、内容 private int []head = { R.drawable.recommend_head1, R.drawable.recommend_head2, R.drawable.recommend_head3, R.drawable.recommend_head4 }; private String []name = { "King", "Lily", "July", "Kelvin" }; private String []message = { "I am message one.", "I am message two.", "I am message three.", "I am message four." }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getSupportActionBar().hide(); setContentView(R.layout.activity_msg); initViews(); } private void initViews() { mList = new ArrayList<Msg>(); mAdapter = new MsgAdapter(this, R.layout.layout_msg, mList); mListView = (ListView) findViewById(R.id.lv_msg); mListView.setAdapter(mAdapter); Random r = new Random(); //可以从这里初始化listView for (int i = 1; i <= 10; i++){ Msg msg = new Msg(head[r.nextInt(4)], "" + name[r.nextInt(4)], "" + message[r.nextInt(4)]); //将实例化后的对象加入到list中,然后list通过adapter适配于listview中 mList.add(msg); } }}
当然个人只是处于初学地步,若有错误也请各位大牛指点一下。
- ListView----Adapter的使用
- 自定义ListView的Adapter
- 好的ListView adapter
- 自定义Adapter的ListView
- Adapter的ListView详解
- listView Adapter 的应用
- Adapter,ListView的应用
- 自定义listview的adapter
- Listview的自定义Adapter
- listView的adapter问题
- 自定义adapter的listview
- 万能listview的adapter
- ListView的Adapter
- ListView的Adapter优化
- listView的 Adapter优化
- ListView的Adapter
- 自定义ListView的Adapter
- Listview的Adapter的转换
- scrapy下载的中文编码问题
- MySQL 利用视图来提高开发效率
- 1、成员内部类(概述和访问特点)
- C语言自增自减
- VR视频播放器Video Player
- ListView的Adapter
- Hadoop完全分布式在实际中优化方案
- 如何定义一个只能在堆上(栈上)生成对象的类?
- 前端如何实现图片懒加载(lazyload) 提高用户体验
- Java经典算法40例(二十九)
- Stall Reservations
- PAT a1005题解
- 如何定义一个只能在栈/堆上生成对象的类
- 通过URL实现下载