一、ListView简介
在开发移动应用程序时,经常需要展示一组数据。这时,ListView就会派上大用场。ListView是Android中最基本的控件之一,可以快速、高效地展示一组数据,支持滚动,可以很好地适配各种屏幕大小。ListView通常用于实现类似聊天记录、联系人列表等需要展示大量数据的场景。
ListView展示数据的原理比较简单:首先,需要一个适配器(Adapter),将数据进行封装和处理,然后将适配器设置到ListView中,再刷新ListView即可显示出数据。
二、创建ListView
接下来我们就来实现一个简单的ListView,展示一组字符串数组。首先,我们需要在XML文件中定义ListView组件:
<ListView android:id="@+id/my_list_view" android:layout_width="match_parent" android:layout_height="wrap_content" />
定义好ListView组件后,我们需要在Java文件中获取到这个组件,并进行设置:
ListView listView = (ListView)findViewById(R.id.my_list_view);
接着,我们需要定义一个字符串数组,作为ListView要展示的数据:
String[] data = { "A", "B", "C", "D", "E", "F", "G" };
有了字符串数组后,我们就需要定义一个适配器,来将数据处理后返回给ListView。我们可以使用Android自带的ArrayAdapter来实现适配器:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data);
这里,我们使用了Android自带的simple_list_item_1布局文件,将数据展示在ListView中。
有了适配器后,我们就需要将适配器设置到ListView中:
listView.setAdapter(adapter);
最后,我们还需要刷新ListView,以展示数据:
adapter.notifyDataSetChanged();
这样,一个简单的ListView就创建好了!完整代码如下:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView listView = (ListView)findViewById(R.id.my_list_view); String[] data = { "A", "B", "C", "D", "E", "F", "G" }; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data); listView.setAdapter(adapter); adapter.notifyDataSetChanged(); } }
三、自定义ListView
虽然Android自带的ListView可以满足一般的需要,但如果需要更加个性化的展示效果,那么就需要自定义ListView了。自定义ListView通常需要自定义适配器,以满足自己的需要。
下面我们就以一个简单的例子来介绍自定义ListView的方法。假设我们需要展示一个联系人列表,每个联系人有头像和名字。首先,我们需要自定义一个数据结构,用来存储联系人的信息:
public class Contact { private int avatar; private String name; public Contact(int avatar, String name) { this.avatar = avatar; this.name = name; } public int getAvatar() { return avatar; } public void setAvatar(int avatar) { this.avatar = avatar; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
定义好数据结构后,我们就需要自定义适配器了。自定义适配器需要继承自BaseAdapter,并对其方法进行实现。我们可以在getView方法中自定义每个列表项的布局,并展示联系人的头像和名字。
public class ContactAdapter extends BaseAdapter { private List<Contact> data; private Context context; public ContactAdapter(Context context, List<Contact> data) { this.context = context; this.data = data; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.item_contact, null); viewHolder = new ViewHolder(); viewHolder.avatar = convertView.findViewById(R.id.avatar); viewHolder.name = convertView.findViewById(R.id.name); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder)convertView.getTag(); } Contact contact = data.get(position); viewHolder.avatar.setImageResource(contact.getAvatar()); viewHolder.name.setText(contact.getName()); return convertView; } static class ViewHolder { ImageView avatar; TextView name; } }
有了适配器后,我们就可以定义一个ListView,并将自定义的适配器设置到ListView中:
ListView listView = (ListView)findViewById(R.id.my_list_view); List<Contact> data = new ArrayList<>(); data.add(new Contact(R.drawable.avatar1, "Tom")); data.add(new Contact(R.drawable.avatar2, "Jerry")); data.add(new Contact(R.drawable.avatar3, "Mike")); data.add(new Contact(R.drawable.avatar4, "John")); ContactAdapter adapter = new ContactAdapter(this, data); listView.setAdapter(adapter);
这样,一个自定义的ListView就创建完成了!完整代码如下:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView listView = (ListView)findViewById(R.id.my_list_view); List<Contact> data = new ArrayList<>(); data.add(new Contact(R.drawable.avatar1, "Tom")); data.add(new Contact(R.drawable.avatar2, "Jerry")); data.add(new Contact(R.drawable.avatar3, "Mike")); data.add(new Contact(R.drawable.avatar4, "John")); ContactAdapter adapter = new ContactAdapter(this, data); listView.setAdapter(adapter); } public class Contact { private int avatar; private String name; public Contact(int avatar, String name) { this.avatar = avatar; this.name = name; } public int getAvatar() { return avatar; } public void setAvatar(int avatar) { this.avatar = avatar; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class ContactAdapter extends BaseAdapter { private List<Contact> data; private Context context; public ContactAdapter(Context context, List<Contact> data) { this.context = context; this.data = data; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.item_contact, null); viewHolder = new ViewHolder(); viewHolder.avatar = convertView.findViewById(R.id.avatar); viewHolder.name = convertView.findViewById(R.id.name); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder)convertView.getTag(); } Contact contact = data.get(position); viewHolder.avatar.setImageResource(contact.getAvatar()); viewHolder.name.setText(contact.getName()); return convertView; } static class ViewHolder { ImageView avatar; TextView name; } } }