您的位置:首页 > 移动开发 > 微信开发

类似微信的聊天界面ListView

2014-04-29 16:14 513 查看
微信中的ListView有一个特点就是存在许多不同的Item,即并不是平常的ListView,所有的Item布局都是一样的。针对这种情况,Google的Adapter提供了两个方法getItemViewType和getViewTypeCount。通过覆盖这两个方法就可以实现一个ListView中存在多种不同的Layout。实现了更加个性化的ListView效果。我归纳了下微信中的Item可以分为7中。针对这7种Item我对应地写了7中listItem。在getView的时候判断下当前数据对象中需要通过哪种布局来展现,来实时获取布局。

下面看代码:

Message.java

Java代码


public class Message {

private int type;//指定是哪种类型

private String value;//值

public int getType() {

return type;

}

public void setType(int type) {

this.type = type;

}

public String getValue() {

return value;

}

public void setValue(String value) {

this.value = value;

}

}

MainActivity.java:

Java代码


public class MainActivity extends Activity {

private ListView lvData;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

lvData = (ListView)findViewById(R.id.lv_data);

lvData.setAdapter(getAdapter());

}

private BaseAdapter getAdapter(){

return new MyAdapter(this, getMyData());

}

private List<Message> getMyData(){

List<Message> msgList = new ArrayList<Message>();

Message msg;

msg = new Message();

msg.setType(MyAdapter.VALUE_LEFT_TEXT);

msg.setValue("食堂真难吃啊");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_TIME_TIP);

msg.setValue("2012-12-23 下午2:23");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_RIGHT_TEXT);

msg.setValue("我就说食堂的饭难吃吧,你不相信!");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_LEFT_TEXT);

msg.setValue("好吧,这次听你的了。");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_TIME_TIP);

msg.setValue("2012-12-23 下午2:25");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_RIGHT_TEXT);

msg.setValue("就要圣诞了,有什么安排没有?");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_LEFT_TEXT);

msg.setValue("没有啊,你呢?");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_TIME_TIP);

msg.setValue("2012-12-23 下午3:25");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_LEFT_IMAGE);

msg.setValue("7min");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_RIGHT_TEXT);

msg.setValue("高帅富有三宝 木耳 跑车 和名表," +

"黑木耳有三宝 美瞳 备胎 黑丝脚 ,穷矮挫有三宝 AV 手纸 射得早 ,女神有三宝 干嘛 呵呵 去洗澡 ,宅男有三宝 Dota 基友 破电脑 " +

"女屌丝有三宝 虎背 熊腰 眼睛小 , 女屌丝还有三宝 饼脸 花痴 卖萌照");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_LEFT_TEXT);

msg.setValue("碉堡了");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_LEFT_AUDIO);

msg.setValue("7min");

msgList.add(msg);

msg = new Message();

msg.setType(MyAdapter.VALUE_RIGHT_IMAGE);

msg.setValue("7min");

msgList.add(msg);

return msgList;

}

}

下面是最重要的地方:

MyAdapter.java:

Java代码


public class MyAdapter extends BaseAdapter{

public static final String KEY = "key";

public static final String VALUE = "value";

public static final int VALUE_TIME_TIP = 0;//7种不同的布局

public static final int VALUE_LEFT_TEXT = 1;

public static final int VALUE_LEFT_IMAGE = 2;

public static final int VALUE_LEFT_AUDIO = 3;

public static final int VALUE_RIGHT_TEXT = 4;

public static final int VALUE_RIGHT_IMAGE = 5;

public static final int VALUE_RIGHT_AUDIO = 6;

private LayoutInflater mInflater;

private Context context;

private List<Message> myList;

public MyAdapter(Context context, List<Message> myList){

this.context = context;

this.myList = myList;

for(Message msg:myList){

Log.d("myList:", msg.getType()+"");

}

mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

public void addItem(final Message item) {

myList.add(item);

notifyDataSetChanged();

}

@Override

public int getCount() {

return myList.size();

}

@Override

public Object getItem(int arg0) {

return myList.get(arg0);

}

@Override

public long getItemId(int arg0) {

return arg0;

}

@Override

public View getView(int position, View convertView, ViewGroup arg2) {

Message msg = myList.get(position);

int type = getItemViewType(position);

ViewHolder holder = null;

if(convertView == null){

holder = new ViewHolder();

switch (type) {

case VALUE_TIME_TIP:

convertView = mInflater.inflate(R.layout.list_item_time_tip, null);

holder.tvTimeTip = (TextView)convertView.findViewById(R.id.tv_time_tip);

holder.tvTimeTip.setText(msg.getValue());

break;

//左边

case VALUE_LEFT_TEXT:

convertView = mInflater.inflate(R.layout.list_item_left_text, null);

holder.ivLeftIcon = (ImageView)convertView.findViewById(R.id.iv_icon);

holder.btnLeftText = (Button)convertView.findViewById(R.id.btn_left_text);

holder.btnLeftText.setText(msg.getValue());

break;

case VALUE_LEFT_IMAGE:

convertView = mInflater.inflate(R.layout.list_item_left_iamge, null);

holder.ivLeftIcon = (ImageView)convertView.findViewById(R.id.iv_icon);

holder.ivLeftImage = (ImageView)convertView.findViewById(R.id.iv_left_image);

holder.ivLeftImage.setImageResource(R.drawable.test);

break;

case VALUE_LEFT_AUDIO:

convertView = mInflater.inflate(R.layout.list_item_left_audio, null);

holder.ivLeftIcon = (ImageView)convertView.findViewById(R.id.iv_icon);

holder.btnLeftAudio = (Button)convertView.findViewById(R.id.btn_left_audio);

holder.tvLeftAudioTime = (TextView)convertView.findViewById(R.id.tv_left_audio_time);

holder.tvLeftAudioTime.setText(msg.getValue());

break;

//右边

case VALUE_RIGHT_TEXT:

convertView = mInflater.inflate(R.layout.list_item_right_text, null);

holder.ivRightIcon = (ImageView)convertView.findViewById(R.id.iv_icon);

holder.btnRightText = (Button)convertView.findViewById(R.id.btn_right_text);

holder.btnRightText.setText(msg.getValue());

break;

case VALUE_RIGHT_IMAGE:

convertView = mInflater.inflate(R.layout.list_item_right_iamge, null);

holder.ivRightIcon = (ImageView)convertView.findViewById(R.id.iv_icon);

holder.ivRightImage = (ImageView)convertView.findViewById(R.id.iv_right_image);

holder.ivRightImage.setImageResource(R.drawable.test);

break;

case VALUE_RIGHT_AUDIO:

convertView = mInflater.inflate(R.layout.list_item_right_audio, null);

holder.ivRightIcon = (ImageView)convertView.findViewById(R.id.iv_icon);

holder.btnRightAudio = (Button)convertView.findViewById(R.id.btn_right_audio);

holder.tvRightAudioTime = (TextView)convertView.findViewById(R.id.tv_right_audio_time);

holder.tvRightAudioTime.setText(msg.getValue());

break;

default:

break;

}

convertView.setTag(holder);

}else{

holder = (ViewHolder)convertView.getTag();

}

return convertView;

}

/**

* 根据数据源的position返回需要显示的的layout的type

*

* */

@Override

public int getItemViewType(int position) {

Message msg = myList.get(position);

int type = msg.getType();

Log.e("TYPE:", ""+type);

return type;

}

/**

* 返回所有的layout的数量

*

* */

@Override

public int getViewTypeCount() {

return 7;

}

class ViewHolder{

private TextView tvTimeTip;//时间

private ImageView ivLeftIcon;//左边的头像

private Button btnLeftText;//左边的文本

private ImageView ivLeftImage;//左边的图像

private Button btnLeftAudio;//左边的声音

private TextView tvLeftAudioTime;//左边的声音时间

private ImageView ivRightIcon;//右边的头像

private Button btnRightText;//右边的文本

private ImageView ivRightImage;//右边的图像

private Button btnRightAudio;//右边的声音

private TextView tvRightAudioTime;//右边的声音时间

}

}

在getView()的时候通过switch判断当前一条数据需要使用的是哪种布局,实时进行加载。

getItemViewType() 和getViewTypeCount() 这两个方法起到的作用是循环回收利用不同的布局,起到了优化的作用!这是不同于平时使用Adapter的地方。

效果如下:



项目地址:

https://github.com/michaelye/WeiXinListView
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: