ListView最主要的功能是展示数据
listview的简单使用
ListView 与数据直接需要一个adapter来适配关系图如下:
有来adapter就可以减少listview与数据直接的耦合度
ListView中的setAdapter方法中需要设置的是ListAdapter
public void setAdapter(ListAdapter adapter)
ListAdapter是一个接口,需要实现的方法太多。所以Android有给我们封装了一层BaseAdapter,BaseAdapter继承了ListAdapter接口。
实现BaseAdapter
BaseAdapter是个抽象类,实现BaseAdapter需要实现里面的四个方法:
//获取数据源的总量
public abstract int getCount()
//获取指定位置的列表项数据
public abstract Object getItem(int position)
//获取指定位置列表项数据的ID
public abstract long getItemId(int position)
//获取指定位置的列表项视图
public abstract View getView(int position, View convertView, ViewGroup parent)
BaseAdapter的基本实现如下:
public class MyBaseAdapter extends BaseAdapter {
private List<TextMessage> messageList;
public MyBaseAdapter(List<TextMessage> messageList) {
this.messageList = messageList;
}
@Override
public int getCount() {
return messageList.size();
}
@Override
public Object getItem(int position) {
return messageList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
// @Override
// public boolean hasStableIds() {
return super.hasStableIds(); //默认返回false
// return true; //返回true的话效率更高 需要getItemId的时候 返回数据本身独有的ID messageList.get(position).getId()
// }
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
// View messageView = layoutInflater.inflate(R.layout.text_message_item,null);//会导致listview的item的高度是自适应,不能显示设置的高度
View messageView = layoutInflater.inflate(R.layout.text_message_item,viewGroup,false);//下面这个方法即可显示我们设置的高度
TextView textView = messageView.findViewById(R.id.message_content);
TextMessage message = messageList.get(position);
textView.setText(message.getText());
return messageView;
}
}
TextMessage的代码如下:
public class TextMessage {
private int id;
private String text;
public TextMessage(int id, String text) {
this.id = id;
this.text = text;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
ListView中设置BaseAdapter
ListView listView = findViewById(R.id.list_view);
List<TextMessage> messageList = new ArrayList<>();
for (int i = 0; i < 100; i++){
messageList.add(new TextMessage(i,"我是文本消息"+i));
}
MyBaseAdapter adapter = new MyBaseAdapter(messageList);
listView.setAdapter(adapter);
ListView中实现多种样式布局
需要实现以下两个方法
1)重写 getViewTypeCount() – 该方法返回多少个不同的布局
2)重写 getItemViewType(int) – 根据position返回相应的Item
其他用法与上面一样代码如下:
public class MyBaseAdapter extends BaseAdapter {
private static final int ViewTypeCount = 2;
private interface ViewType {
int TEXT = 0;
int IMAGE = 1;
}
private List<Object> messageList;
public MyBaseAdapter(List<Object> messageList) {
this.messageList = messageList;
}
@Override
public int getCount() {
return messageList.size();
}
@Override
public Object getItem(int position) {
return messageList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
if (getItemViewType(position) == ViewType.TEXT){
View convertView = inflater.inflate(R.layout.text_message_item,viewGroup,false);
TextView textView = convertView.findViewById(R.id.message_content);
TextMessage textMessage = (TextMessage)messageList.get(position);
textView.setText(textMessage.getText());
return convertView;
}else {
View convertView = inflater.inflate(R.layout.image_message_item,viewGroup,false);
ImageView imageView = convertView.findViewById(R.id.image_head);
ImageMessage imageMessage = (ImageMessage)messageList.get(position);
imageView.setImageResource(imageMessage.getImage());
return convertView;
}
}
@Override
public int getItemViewType(int position) {
if (getItem(position) instanceof TextMessage){
return ViewType.TEXT;
}else {
return ViewType.IMAGE;
}
}
@Override
public int getViewTypeCount() {
return ViewTypeCount;
}
}