仿微信的语音聊天记录,左右两个布局
2016-10-04 22:21
323 查看
1.微信聊天记录是一个listview,并且分为自己和其他人的两个布局
1.1左侧为其他人的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:background="#F5F5F5" >
<TextView
android:id="@+id/tv_voice_history_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#DCDCDC"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:minHeight="24dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="2016年09月02日 16:40:00"
android:textColor="#fff"
android:textSize="14dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="5dp">
<ImageView
android:id="@+id/iv_member_portrait"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:background="@drawable/member_info" />
<LinearLayout
android:id="@+id/ll_voice_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_member_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="张星星"
android:textColor="#a0a0a0"
android:textSize="14dp"
android:textStyle="normal" />
<RelativeLayout
android:id="@+id/rl_voice_play"
android:visibility="visible"
android:layout_width="80dp"
android:layout_height="34dp"
android:focusable="false"
android:background="@drawable/selector_voice_history_bg"
>
<ImageView
android:id="@+id/iv_voice_image_anim"
android:layout_width="15dp"
android:layout_height="20dp"
android:background="@anim/voice_history_play_anim"
android:layout_centerVertical="true"
android:layout_marginLeft="18dp"
android:visibility="gone"
/>
<ImageView
android:id="@+id/iv_voice_image"
android:layout_width="15dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:layout_marginLeft="18dp"
android:background="@drawable/sound_item"
android:visibility="visible" />
</RelativeLayout>
</LinearLayout>
<TextView
android:id="@+id/tv_voice_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="12 ''"
android:textColor="#a0a0a0"
android:textSize="16dp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
其中的动画是帧动画:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/sound_blank" android:duration="300"/>
<item android:drawable="@drawable/sound_chat_send_one" android:duration="300"/>
<item android:drawable="@drawable/sound_chat_send_two" android:duration="300"/>
<item android:drawable="@drawable/sound_item" android:duration="300"/>
</animation-list>
1.2 右侧是自己的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.andro
cd1c
id.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:background="#F5F5F5" >
<TextView
android:id="@+id/tv_voice_history_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#DCDCDC"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:minHeight="24dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="2016年09月02日 16:40:00"
android:textColor="#000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="5dp">
<View
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="1dp"
/>
<!-- <ImageView
android:id="@+id/iv_unread"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/unread_message_circle_shape"
/> -->
<TextView
android:id="@+id/tv_voice_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="12 ''"
android:textColor="#a0a0a0"
android:textSize="16dp"
android:textStyle="normal" />
<LinearLayout
android:id="@+id/ll_voice_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:gravity="right"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_member_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我"
android:textColor="#313131"
android:textSize="18dp"
android:textStyle="normal" />
<RelativeLayout
android:id="@+id/rl_voice_play"
android:visibility="visible"
android:layout_width="80dp"
android:layout_height="34dp"
android:focusable="false"
android:gravity="right"
android:background="@drawable/selector_voice_history_bg_right"
>
<ImageView
android:id="@+id/iv_voice_image_anim"
android:layout_width="15dp"
android:layout_height="20dp"
android:layout_marginRight="18dp"
android:background="@anim/voice_history_play_anim_right"
android:layout_centerVertical="true"
android:visibility="visible"
/>
<ImageView
android:id="@+id/iv_voice_image"
android:layout_width="15dp"
android:layout_height="20dp"
android:layout_marginRight="18dp"
android:layout_centerVertical="true"
android:background="@drawable/sound_item_right"
android:visibility="visible" />
</RelativeLayout>
</LinearLayout>
<ImageView
android:id="@+id/iv_member_portrait"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginRight="10dp"
android:background="@drawable/member_info" />
</LinearLayout>
</LinearLayout>
同样是帧动画,只是换成了沿Y轴对称的图片就行。
2.listview的adapter,adapter在填充布局的时候要选择用哪种布局,这里主要用到两个重写的方法getItemViewType()和getViewTypeCount();
/**
* 根据数据源的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 2;
}
下面是我的完整的adapter类:
package com.example.listviewchatui;
import java.util.List;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* 想比较原来的多了getItemViewType和getViewTypeCount这两个方法,原来循环使用layout布局,起到了优化的作用
*/
public class MyAdapter extends BaseAdapter implements OnClickListener{
public static final String KEY = "key";
public static final String VALUE = "value";
//因为在getViewTypeCount()方法中返回的是2,所以这两个值只能设置为0和1;切记,切记!否则会报角标越界的。
public static final int VALUE_LEFT = 0;
public static final int VALUE_RIGHT = 1;
private LayoutInflater mInflater;
private Context context;
private List<Message> myList;
private InterClick interClick;
private int mPosition;
private boolean isplaying;
private boolean isSameItem;
public MyAdapter(Context context, List<Message> myList, InterClick interClick){
this.context = context;
this.myList = myList;
this.interClick = interClick;
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_LEFT:
convertView = mInflater.inflate(R.layout.item_voice_history_left, null);
// holder.tv_voice_history_time = (TextView)convertView.findViewById(R.id.tv_voice_history_time);
// holder.tv_member_name = (TextView)convertView.findViewById(R.id.tv_member_name);
// holder.tv_member_name.setText(msg.getValue());
// holder.tv_voice_duration = (TextView)convertView.findViewById(R.id.tv_voice_duration);
// holder.iv_voice_image = (ImageView)convertView.findViewById(R.id.iv_voice_image);
// holder.iv_voice_image_anim = (ImageView)convertView.findViewById(R.id.iv_voice_image_anim);
break;
//右边
case VALUE_RIGHT:
convertView = mInflater.inflate(R.layout.item_voice_history_right, null);
// holder.tv_voice_history_time = (TextView)convertView.findViewById(R.id.tv_voice_history_time);
// holder.tv_member_name = (TextView)convertView.findViewById(R.id.tv_member_name);
// holder.tv_member_name.setText(msg.getValue());
// holder.tv_voice_duration = (TextView)convertView.findViewById(R.id.tv_voice_duration);
// holder.iv_voice_image = (ImageView)convertView.findViewById(R.id.iv_voice_image);
// holder.iv_voice_image_anim = (ImageView)convertView.findViewById(R.id.iv_voice_image_anim);
break;
default:
break;
}
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.tv_voice_history_time = (TextView)convertView.findViewById(R.id.tv_voice_history_time);
holder.tv_member_name = (TextView)convertView.findViewById(R.id.tv_member_name);
holder.tv_member_name.setText(msg.getValue());
holder.tv_voice_duration = (TextView)convertView.findViewById(R.id.tv_voice_duration);
holder.iv_voice_image = (ImageView)convertView.findViewById(R.id.iv_voice_image);
holder.iv_voice_image_anim = (ImageView)convertView.findViewById(R.id.iv_voice_image_anim);
holder.ll_voice_play = (LinearLayout)convertView.findViewById(R.id.ll_voice_play);
AnimationDrawable animationDrawable = (AnimationDrawable) holder.iv_voice_image_anim.getBackground();
if (position == mPosition) {
System.out.println("点击的条目======"+position);
if (isSameItem) {
if (isplaying) {
holder.iv_voice_image.setVisibility(View.GONE);
holder.iv_voice_image_anim.setVisibility(View.VISIBLE);
animationDrawable.start();
} else {
holder.iv_voice_image_anim.setVisibility(View.GONE);
holder.iv_voice_image.setVisibility(View.VISIBLE);
animationDrawable.stop();
}
}else {
animationDrawable.start();
holder.iv_voice_image_anim.setVisibility(View.VISIBLE);
holder.iv_voice_image.setVisibility(View.GONE);
}
}else {
System.out.println("其它条目--------"+position);
animationDrawable.stop();
holder.iv_voice_image_anim.setVisibility(View.GONE);
holder.iv_voice_image.setVisibility(View.VISIBLE);
}
holder.ll_voice_play.setOnClickListener(this);
// 设置位置,获取点击的条目按钮
holder.ll_voice_play.setTag(position);
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 2;
}
class ViewHolder{
public LinearLayout ll_voice_play;
public ImageView iv_voice_image_anim;
public ImageView iv_voice_image;
public TextView tv_voice_duration;
public TextView tv_member_name;
public TextView tv_voice_history_time;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ll_voice_play:
interClick.animClick(v);
break;
default:
break;
}
}
public void refreshPersonContactsAdapter(int mPosition, boolean isplaying,
boolean isSameItem) {
this.mPosition = mPosition;
this.isplaying = isplaying;
this.isSameItem = isSameItem;
notifyDataSetChanged();
}
}
同样的里面也用到了接口,来实现语音播放时的动画效果,接口类如下:
package com.example.listviewchatui;
import android.view.View;
public interface InterClick {
public void animClick(View v);
}
3.activity中为listview设置adapter,并监听条目中的按钮或布局的点击事件;
package com.example.listviewchatui;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView lvData;
private boolean isplaying;
private boolean isSameItem;
private int mPosition = -1;
private int lastPosition = -1;
private MyAdapter myAdapter;
@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(){
myAdapter = new MyAdapter(this, getMyData(), interClick);
return myAdapter;
}
private List<Message> getMyData(){
List<Message> msgList = new ArrayList<Message>();
Message msg;
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
return msgList;
}
private InterClick interClick = new InterClick() {
@Override
public void animClick(View v) {
mPosition = (Integer) v.getTag();
if (lastPosition == mPosition) {
isSameItem = true;
isplaying = !isplaying;
} else {
isSameItem = false;
isplaying = true;
}
myAdapter.refreshPersonContactsAdapter(mPosition, isplaying, isSameItem);
lastPosition = mPosition;
}
};
}
Message只是一个JavaBean对象,可以根据自己的需要设置对象。
这里只是写了2种不同的布局,更多详细的布局可以参考:http://blog.csdn.net/cleanness/article/details/24722403
1.1左侧为其他人的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:background="#F5F5F5" >
<TextView
android:id="@+id/tv_voice_history_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#DCDCDC"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:minHeight="24dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="2016年09月02日 16:40:00"
android:textColor="#fff"
android:textSize="14dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="5dp">
<ImageView
android:id="@+id/iv_member_portrait"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:background="@drawable/member_info" />
<LinearLayout
android:id="@+id/ll_voice_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_member_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="张星星"
android:textColor="#a0a0a0"
android:textSize="14dp"
android:textStyle="normal" />
<RelativeLayout
android:id="@+id/rl_voice_play"
android:visibility="visible"
android:layout_width="80dp"
android:layout_height="34dp"
android:focusable="false"
android:background="@drawable/selector_voice_history_bg"
>
<ImageView
android:id="@+id/iv_voice_image_anim"
android:layout_width="15dp"
android:layout_height="20dp"
android:background="@anim/voice_history_play_anim"
android:layout_centerVertical="true"
android:layout_marginLeft="18dp"
android:visibility="gone"
/>
<ImageView
android:id="@+id/iv_voice_image"
android:layout_width="15dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:layout_marginLeft="18dp"
android:background="@drawable/sound_item"
android:visibility="visible" />
</RelativeLayout>
</LinearLayout>
<TextView
android:id="@+id/tv_voice_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="12 ''"
android:textColor="#a0a0a0"
android:textSize="16dp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
其中的动画是帧动画:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/sound_blank" android:duration="300"/>
<item android:drawable="@drawable/sound_chat_send_one" android:duration="300"/>
<item android:drawable="@drawable/sound_chat_send_two" android:duration="300"/>
<item android:drawable="@drawable/sound_item" android:duration="300"/>
</animation-list>
1.2 右侧是自己的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.andro
cd1c
id.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:background="#F5F5F5" >
<TextView
android:id="@+id/tv_voice_history_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#DCDCDC"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:minHeight="24dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="2016年09月02日 16:40:00"
android:textColor="#000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="5dp">
<View
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="1dp"
/>
<!-- <ImageView
android:id="@+id/iv_unread"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/unread_message_circle_shape"
/> -->
<TextView
android:id="@+id/tv_voice_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="12 ''"
android:textColor="#a0a0a0"
android:textSize="16dp"
android:textStyle="normal" />
<LinearLayout
android:id="@+id/ll_voice_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:gravity="right"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_member_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我"
android:textColor="#313131"
android:textSize="18dp"
android:textStyle="normal" />
<RelativeLayout
android:id="@+id/rl_voice_play"
android:visibility="visible"
android:layout_width="80dp"
android:layout_height="34dp"
android:focusable="false"
android:gravity="right"
android:background="@drawable/selector_voice_history_bg_right"
>
<ImageView
android:id="@+id/iv_voice_image_anim"
android:layout_width="15dp"
android:layout_height="20dp"
android:layout_marginRight="18dp"
android:background="@anim/voice_history_play_anim_right"
android:layout_centerVertical="true"
android:visibility="visible"
/>
<ImageView
android:id="@+id/iv_voice_image"
android:layout_width="15dp"
android:layout_height="20dp"
android:layout_marginRight="18dp"
android:layout_centerVertical="true"
android:background="@drawable/sound_item_right"
android:visibility="visible" />
</RelativeLayout>
</LinearLayout>
<ImageView
android:id="@+id/iv_member_portrait"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginRight="10dp"
android:background="@drawable/member_info" />
</LinearLayout>
</LinearLayout>
同样是帧动画,只是换成了沿Y轴对称的图片就行。
2.listview的adapter,adapter在填充布局的时候要选择用哪种布局,这里主要用到两个重写的方法getItemViewType()和getViewTypeCount();
/**
* 根据数据源的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 2;
}
下面是我的完整的adapter类:
package com.example.listviewchatui;
import java.util.List;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* 想比较原来的多了getItemViewType和getViewTypeCount这两个方法,原来循环使用layout布局,起到了优化的作用
*/
public class MyAdapter extends BaseAdapter implements OnClickListener{
public static final String KEY = "key";
public static final String VALUE = "value";
//因为在getViewTypeCount()方法中返回的是2,所以这两个值只能设置为0和1;切记,切记!否则会报角标越界的。
public static final int VALUE_LEFT = 0;
public static final int VALUE_RIGHT = 1;
private LayoutInflater mInflater;
private Context context;
private List<Message> myList;
private InterClick interClick;
private int mPosition;
private boolean isplaying;
private boolean isSameItem;
public MyAdapter(Context context, List<Message> myList, InterClick interClick){
this.context = context;
this.myList = myList;
this.interClick = interClick;
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_LEFT:
convertView = mInflater.inflate(R.layout.item_voice_history_left, null);
// holder.tv_voice_history_time = (TextView)convertView.findViewById(R.id.tv_voice_history_time);
// holder.tv_member_name = (TextView)convertView.findViewById(R.id.tv_member_name);
// holder.tv_member_name.setText(msg.getValue());
// holder.tv_voice_duration = (TextView)convertView.findViewById(R.id.tv_voice_duration);
// holder.iv_voice_image = (ImageView)convertView.findViewById(R.id.iv_voice_image);
// holder.iv_voice_image_anim = (ImageView)convertView.findViewById(R.id.iv_voice_image_anim);
break;
//右边
case VALUE_RIGHT:
convertView = mInflater.inflate(R.layout.item_voice_history_right, null);
// holder.tv_voice_history_time = (TextView)convertView.findViewById(R.id.tv_voice_history_time);
// holder.tv_member_name = (TextView)convertView.findViewById(R.id.tv_member_name);
// holder.tv_member_name.setText(msg.getValue());
// holder.tv_voice_duration = (TextView)convertView.findViewById(R.id.tv_voice_duration);
// holder.iv_voice_image = (ImageView)convertView.findViewById(R.id.iv_voice_image);
// holder.iv_voice_image_anim = (ImageView)convertView.findViewById(R.id.iv_voice_image_anim);
break;
default:
break;
}
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.tv_voice_history_time = (TextView)convertView.findViewById(R.id.tv_voice_history_time);
holder.tv_member_name = (TextView)convertView.findViewById(R.id.tv_member_name);
holder.tv_member_name.setText(msg.getValue());
holder.tv_voice_duration = (TextView)convertView.findViewById(R.id.tv_voice_duration);
holder.iv_voice_image = (ImageView)convertView.findViewById(R.id.iv_voice_image);
holder.iv_voice_image_anim = (ImageView)convertView.findViewById(R.id.iv_voice_image_anim);
holder.ll_voice_play = (LinearLayout)convertView.findViewById(R.id.ll_voice_play);
AnimationDrawable animationDrawable = (AnimationDrawable) holder.iv_voice_image_anim.getBackground();
if (position == mPosition) {
System.out.println("点击的条目======"+position);
if (isSameItem) {
if (isplaying) {
holder.iv_voice_image.setVisibility(View.GONE);
holder.iv_voice_image_anim.setVisibility(View.VISIBLE);
animationDrawable.start();
} else {
holder.iv_voice_image_anim.setVisibility(View.GONE);
holder.iv_voice_image.setVisibility(View.VISIBLE);
animationDrawable.stop();
}
}else {
animationDrawable.start();
holder.iv_voice_image_anim.setVisibility(View.VISIBLE);
holder.iv_voice_image.setVisibility(View.GONE);
}
}else {
System.out.println("其它条目--------"+position);
animationDrawable.stop();
holder.iv_voice_image_anim.setVisibility(View.GONE);
holder.iv_voice_image.setVisibility(View.VISIBLE);
}
holder.ll_voice_play.setOnClickListener(this);
// 设置位置,获取点击的条目按钮
holder.ll_voice_play.setTag(position);
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 2;
}
class ViewHolder{
public LinearLayout ll_voice_play;
public ImageView iv_voice_image_anim;
public ImageView iv_voice_image;
public TextView tv_voice_duration;
public TextView tv_member_name;
public TextView tv_voice_history_time;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ll_voice_play:
interClick.animClick(v);
break;
default:
break;
}
}
public void refreshPersonContactsAdapter(int mPosition, boolean isplaying,
boolean isSameItem) {
this.mPosition = mPosition;
this.isplaying = isplaying;
this.isSameItem = isSameItem;
notifyDataSetChanged();
}
}
同样的里面也用到了接口,来实现语音播放时的动画效果,接口类如下:
package com.example.listviewchatui;
import android.view.View;
public interface InterClick {
public void animClick(View v);
}
3.activity中为listview设置adapter,并监听条目中的按钮或布局的点击事件;
package com.example.listviewchatui;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView lvData;
private boolean isplaying;
private boolean isSameItem;
private int mPosition = -1;
private int lastPosition = -1;
private MyAdapter myAdapter;
@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(){
myAdapter = new MyAdapter(this, getMyData(), interClick);
return myAdapter;
}
private List<Message> getMyData(){
List<Message> msgList = new ArrayList<Message>();
Message msg;
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_LEFT);
msg.setValue("别人");
msgList.add(msg);
msg = new Message();
msg.setType(MyAdapter.VALUE_RIGHT);
msg.setValue("自己");
msgList.add(msg);
return msgList;
}
private InterClick interClick = new InterClick() {
@Override
public void animClick(View v) {
mPosition = (Integer) v.getTag();
if (lastPosition == mPosition) {
isSameItem = true;
isplaying = !isplaying;
} else {
isSameItem = false;
isplaying = true;
}
myAdapter.refreshPersonContactsAdapter(mPosition, isplaying, isSameItem);
lastPosition = mPosition;
}
};
}
Message只是一个JavaBean对象,可以根据自己的需要设置对象。
这里只是写了2种不同的布局,更多详细的布局可以参考:http://blog.csdn.net/cleanness/article/details/24722403
相关文章推荐
- 微信5.2 for iPhone 全体验:新增图片墙、语音转文字,可搜索聊天记录,群聊被@会收到提醒
- Android微信语音聊天记录及文本聊天记录 数据库破解 silk 整理
- 删除的微信聊天记录怎么恢复?如何恢复删除的微信聊天记录、语音聊天记录
- 如何用腾讯电脑管家备份微信聊天记录
- 手机微信聊天记录怎么可以在电脑上查看呢?
- 恢复删除的安卓微信聊天记录
- 怎样恢复微信历史聊天记录
- 导出微信聊天记录的工具
- 微信语音记录丢失如何恢复
- 如何导出微信聊天记录
- 微信好友聊天记录删除了还能恢复吗,怎么恢复
- 两个Div左右浮动布局且按其中最高一方占位
- 两个机器人的聊天记录
- 用SQLite查看编辑android导出的微信聊天记录
- android设置微信聊天布局
- 怎样把微信聊天记录导出备份到电脑【微信公众平台技巧】
- 如何导出微信聊天记录
- Android 实现微信聊天一样的布局
- 安卓微信聊天记录解密查看恢复
- 查询别人微信聊天记录,操作只需30分钟快速完成