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;
}
}