最近项目在做im即时通讯开发,在删除聊天列表的时候跟删除聊天详细信息的时候,产品经理想要跟ios一样,在当前选中行上方弹出一个删除窗口.于是先从网上找demo,找了一个发现是dialog做的,我感觉没有必要这么麻烦,于是我用popupwindow实现了一个,有需要的朋友可以参考一下。
1.效果图如下(长按列表弹窗,消息详细信息长按弹窗)
2.对源码进行说明。
一条消息实体类,有消息内容跟是否发送这两个属性。
public class message {
private string content;// 消息内容
private boolean sended;// 是否发送
public message(){
}
public message(string content,boolean sended){
this.content=content;
this.sended=sended;
public string getcontent() {
return content;
public void setcontent(string content) {
this.content = content;
public boolean issended() {
return sended;
public void setsended(boolean sended) {
this.sended = sended;
}
消息详细信息的activity
1).给每条消息设置长按事件,把点击的下标用tag传进去
2).用popupwindow展示,显示在当前点击的view下方,然后设置xy的偏移度
* 消息详细界面
* @author ansen
* @create time 2015-08-04
*/
public class messagedetailactivity extends activity{
private list<message> messages=new arraylist<message>();
private listview listview;
private myadapter madapter;
private popupwindow popupwindow;
private textview tvdelete;
private edittext etinput;
private int longclickposition;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_private_message_detail_list);
initdata();
listview=(listview) findviewbyid(r.id.list_private_message);
listview.setadapter(madapter=new myadapter());
textview sendmessage=(textview) findviewbyid(r.id.tv_send_message);
sendmessage.setonclicklistener(clicklistener);
etinput=(edittext) findviewbyid(r.id.et_input);
private class myadapter extends baseadapter{
private layoutinflater inflater;
public myadapter(){
inflater=layoutinflater.from(messagedetailactivity.this);
}
@override
public int getcount() {
return messages.size();
public object getitem(int position) {
return messages.get(position);
public long getitemid(int position) {
return position;
public view getview(int position, view convertview, viewgroup parent) {
viewholder holder = null;
if(null==convertview){
holder=new viewholder();
convertview= inflater.inflate(r.layout.item_private_message_chat,parent,false);
holder.tvmessageto=(textview) convertview.findviewbyid(r.id.tv_message_to);
holder.ivmessagetoheadimage=(imageview) convertview.findviewbyid(r.id.iv_message_to_head_image);
holder.tvmessagefrom=(textview) convertview.findviewbyid(r.id.tv_message_from);
holder.ivmessagefromheadimage=(imageview) convertview.findviewbyid(r.id.iv_message_from_head_image);
convertview.settag(holder);
}else{
holder=(viewholder) convertview.gettag();
}
message message=messages.get(position);
if(message.issended()){//发送消息
holder.tvmessageto.setvisibility(view.gone);
holder.ivmessagetoheadimage.setvisibility(view.gone);
holder.tvmessagefrom.setvisibility(view.visible);
holder.tvmessagefrom.settext(message.getcontent());
holder.tvmessagefrom.setonlongclicklistener(longclicklistener);
holder.tvmessagefrom.settag(position);
holder.ivmessagefromheadimage.setvisibility(view.visible);
}else{//接收消息
holder.tvmessagefrom.setvisibility(view.gone);
holder.ivmessagefromheadimage.setvisibility(view.gone);
holder.tvmessageto.setvisibility(view.visible);
holder.tvmessageto.settext(message.getcontent());
holder.tvmessageto.setonlongclicklistener(longclicklistener);
holder.tvmessageto.settag(position);
holder.ivmessagetoheadimage.setvisibility(view.visible);
return convertview;
private class viewholder{
private imageview ivmessagetoheadimage;//接收消息用户头像
private textview tvmessageto;//接收消息内容
private imageview ivmessagefromheadimage;//发送消息用户头像
private textview tvmessagefrom;//发送消息内容
private onlongclicklistener longclicklistener=new onlongclicklistener() {
public boolean onlongclick(view v) {
longclickposition=(integer) v.gettag();
showdialog(v);
return true;
};
private void showdialog(view view){
if(null==popupwindow){
view popview = layoutinflater.from(this).inflate(r.layout.layout_long_click_dialog, null);
tvdelete=(textview) popview.findviewbyid(r.id.tv_delete);
tvdelete.setonclicklistener(clicklistener);
popupwindow = new popupwindow(popview, layoutparams.wrap_content, layoutparams.wrap_content);
popupwindow.setanimationstyle(r.style.popanimstyle);
popupwindow.setoutsidetouchable(true);
popupwindow.setbackgrounddrawable(new bitmapdrawable());
if (popupwindow.isshowing())
popupwindow.dismiss();
//第一次显示控件的时候宽高会为0
int deleteheight=tvdelete.getheight()==0?145:tvdelete.getheight();
int deletewidth=tvdelete.getwidth()==0?212:tvdelete.getwidth();
popupwindow.showasdropdown(view,(view.getwidth()-deletewidth)/2,-view.getheight()-deleteheight);
private onclicklistener clicklistener=new onclicklistener() {
public void onclick(view v) {
switch (v.getid()) {
case r.id.tv_delete:
messages.remove(longclickposition);
madapter.notifydatasetchanged();
popupwindow.dismiss();
break;
case r.id.tv_send_message:
string content=etinput.gettext().tostring().trim();
if(!textutils.isempty(content)){
message message=new message(content, true);
messages.add(message);
madapter.notifydatasetchanged();
listview.setselection(madapter.getcount()-1);
}
private void initdata(){
message message=new message("范德萨范德", true);
message message7=new message("范德萨范德fds", true);
message message1=new message("个人提个人鬼地", false);
message message4=new message("接收消息", false);
message message2=new message("吃饭了嘛。。。。吃过了没有啊。。。。。还没有吃啊 范德萨范德萨发水电费的说法都是", true);
message message3=new message("吃饭了嘛。。。。吃过了没有啊。。。。。还没有吃啊 范德萨范德萨发水电费的说法都是", false);
messages.add(message);
messages.add(message1);
messages.add(message2);
messages.add(message3);
messages.add(message4);
messages.add(message7);
消息详细列表布局文件 activity_private_message_detail_list.xml
<?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<listview
android:id="@+id/list_private_message"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/ll_bottom"
android:divider="@null" >
</listview>
<include
android:id="@+id/ll_bottom"
android:layout_height="wrap_content"
android:layout_alignparentbottom="true"
layout="@layout/layout_input_comment" />
</relativelayout>
底部输入框布局
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<relativelayout
android:layout_width="wrap_content"
android:paddingbottom="7dip"
android:paddingtop="7dip">
<imageview
android:id="@+id/iv_message_to_head_image"
android:layout_alignparentleft="true"
android:layout_marginleft="5dp"
android:layout_marginright="5dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/slide_left_avatar_default"/>
<textview
android:id="@+id/tv_message_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/icon_message_to"
android:gravity="center"
android:paddingleft="20dip"
android:textcolor="@color/register_text_color"
android:layout_torightof="@+id/iv_message_to_head_image"
android:layout_marginright="55dp"
android:textsize="16dip"/>
android:id="@+id/tv_message_from"
android:layout_toleftof="@+id/iv_message_from_head_image"
android:background="@drawable/icon_message_from"
android:paddingright="20dip"
android:textcolor="@color/white_normal"
android:layout_marginleft="55dp"
android:text="我已经吃过了"
<!-- -->
android:id="@+id/iv_message_from_head_image"
android:layout_alignparentright="true"
</relativelayout>
</linearlayout>
每一条消息的布局文件
弹出删除按钮的布局文件
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
<textview
android:id="@+id/tv_delete"
android:background="@drawable/icon_private_message_delete"
android:gravity="center_horizontal"
android:padding="5dp"
android:text="删除"
android:textcolor="#ffffffff" />
</framelayout>
<a target="_blank" href="http://download.csdn.net/detail/lowprofile_coding/8958311">点击链接下载源码</a>