Android中ListView多种Item布局的实现

本文介绍了在Android中处理ListView多种Item布局的问题,特别是在聊天界面显示发送和接收消息时的需求。通过分析使用布尔变量判断导致的显示错乱问题,提出了利用BaseAdapter的getItemViewType()和getViewTypeCount()方法来正确设置不同类型的item布局,从而实现预期效果。

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

    我们在对ListView设置item的布局的时候,通常只会考虑到一种item。但是多种item布局的情况还是很常见的,比如说聊天界面,需要用两种item布局来分别表示发送和接收的消息。

    刚开始我的想法是通过对发送消息的实体类中添加一个布尔型变量来区分消息是发送的还是接收的:

package cn.qt.demo;

public class Messages {
	private boolean isMe;
}

在BaseAdapter的getView()方法中通过判断当前显示item的消息的isMe属性来给convertView设置不同的layout,但是由于convertView的复用和优化,会导致显示错乱,达不到预期的结果。通过我的进一步查询资料,我发现BaseAdapter自带两个方法可以实现这种需求:

getItemViewType() 获得item的布局类型

getViewTypeCount() 获得item的布局的个数

废话不多说,上代码

MessageAdapter.java

package cn.qt.demo;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MessageAdapter extends BaseAdapter{
	private Context context;
	private List<Messages> data;
	private LayoutInflater inflater;
	
	public MessageAdapter(Context context, List<Messages> data) {
		super();
		this.context = context;
		setData(data);
		inflater = LayoutInflater.from(this.context);
	}

	public List<Messages> getData() {
		return data;
	}

	public void setData(List<Messages> data) {
		if(data == null) {
			data = new ArrayList<Messages>();
		}
		this.data = data;
	}

	@Override
	public int getCount() {
		return data.size();
	}

	@Override
	public Messages getItem(int position) {
		return getData().get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		Messages message = getItem(position);
		if(convertView == null) {
			holder = new ViewHolder();
			if(getItemViewType(position)==MESSAGE_TYPE_ME) {
				convertView=inflater.inflate(R.layout.item_isme, null);
			} else {
				convertView = inflater.inflate(R.layout.item_notme, null);
			}
			holder.tvText = (TextView) convertView.findViewById(R.id.tv_message);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		holder.tvText.setText(message.getText());
		return convertView;
	}
	
	class ViewHolder {
		TextView tvText;
	}

	public static final int MESSAGE_TYPE_ME = 0;
	public static final int MESSAGE_TYPE_NOTME = 1;
	@Override
	public int getItemViewType(int position) {
		return data.get(position).isMe()?MESSAGE_TYPE_ME:MESSAGE_TYPE_NOTME;
	}
	
	@Override
	public int getViewTypeCount() {
		return 2;
	}
}
Message.java

package cn.qt.demo;

public class Messages {
	private String text;
	private boolean isMe;
	public Messages() {
		super();
	}
	public Messages(String text, boolean isMe) {
		super();
		this.text = text;
		this.isMe = isMe;
	}
	public String getText() {
		return text;
	}
	public void setText(String text) {
		this.text = text;
	}
	public boolean isMe() {
		return isMe;
	}
	public void setMe(boolean isMe) {
		this.isMe = isMe;
	}
	
}
MainActivity.java

package cn.qt.demo;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;

public class MainActivity extends Activity {
	private ListView lvMessage;
	private MessageAdapter adapter;
	private List<Messages> data;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		lvMessage =(ListView) findViewById(R.id.lv_message);
		data = new ArrayList<Messages>();
		adapter = new MessageAdapter(this, data);
		lvMessage.setAdapter(adapter);
	}

	public void doClick(View v) {
		switch (v.getId()) {
		case R.id.btn_notme:
			data.add(new Messages("这是接收的消息", false));
			adapter.notifyDataSetChanged();
			lvMessage.setSelection(lvMessage.getBottom());
			break;

		case R.id.btn_isme:
			data.add(new Messages("这是发送的消息", true));
			adapter.notifyDataSetChanged();
			lvMessage.setSelection(lvMessage.getBottom());
			break;
		}
	}

}


此Demo的资源链接: http://download.youkuaiyun.com/detail/qt1105338951/9419788


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值