Android仿qq聊天记录长按删除功能效果

最近项目在做IM即时通讯开发,在删除聊天列表的时候跟删除聊天详细信息的时候,产品经理想要跟ios一样,在当前选中行上方弹出一个删除窗口.于是先从网上找demo,找了一个发现是Dialog做的,我感觉没有必要这么麻烦,于是我用Popupwindow实现了一个,有需要的朋友可以参考一下。

1.效果图如下(长按列表弹窗,消息详细信息长按弹窗)

2.对源码进行说明。

一条消息实体类,有消息内容跟是否发送这两个属性。

  1. public class Message {  
  2.     private String content;// 消息内容  
  3.     private boolean sended;// 是否发送  
  4.       
  5.     public Message(){  
  6.     }  
  7.       
  8.     public Message(String content,boolean sended){  
  9.         this.content=content;  
  10.         this.sended=sended;  
  11.     }  
  12.   
  13.     public String getContent() {  
  14.         return content;  
  15.     }  
  16.   
  17.     public void setContent(String content) {  
  18.         this.content = content;  
  19.     }  
  20.   
  21.     public boolean isSended() {  
  22.         return sended;  
  23.     }  
  24.   
  25.     public void setSended(boolean sended) {  
  26.         this.sended = sended;  
  27.     }  
  28. }  

消息详细信息的Activity

1).给每条消息设置长按事件,把点击的下标用tag传进去

2).用popupwindow展示,显示在当前点击的View下方,然后设置xy的偏移度

  1.  * 消息详细界面  
  2.  * @author ansen  
  3.  * @create time 2015-08-04  
  4.  */  
  5. public class MessageDetailActivity extends Activity{  
  6.     private List<Message> messages=new ArrayList<Message>();  
  7.     private ListView listView;  
  8.     private MyAdapter mAdapter;  
  9.       
  10.     private PopupWindow popupWindow;  
  11.     private TextView tvDelete;  
  12.     private EditText etInput;  
  13.     private int longClickPosition;  
  14.       
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.activity_private_message_detail_list);  
  19.           
  20.         initData();  
  21.           
  22.         listView=(ListView) findViewById(R.id.list_private_message);  
  23.         listView.setAdapter(mAdapter=new MyAdapter());  
  24.           
  25.         TextView sendMessage=(TextView) findViewById(R.id.tv_send_message);  
  26.         sendMessage.setOnClickListener(clickListener);  
  27.           
  28.         etInput=(EditText) findViewById(R.id.et_input);  
  29.     }  
  30.       
  31.       
  32.     private class MyAdapter extends BaseAdapter{  
  33.         private LayoutInflater inflater;  
  34.         public MyAdapter(){  
  35.             inflater=LayoutInflater.from(MessageDetailActivity.this);  
  36.         }  
  37.   
  38.         @Override  
  39.         public int getCount() {  
  40.             return messages.size();  
  41.         }  
  42.   
  43.         @Override  
  44.         public Object getItem(int position) {  
  45.             return messages.get(position);  
  46.         }  
  47.   
  48.         @Override  
  49.         public long getItemId(int position) {  
  50.             return position;  
  51.         }  
  52.   
  53.         @Override  
  54.         public View getView(int position, View convertView, ViewGroup parent) {  
  55.             ViewHolder holder = null;  
  56.             if(null==convertView){  
  57.                 holder=new ViewHolder();  
  58.                 convertView= inflater.inflate(R.layout.item_private_message_chat,parent,false);  
  59.                 holder.tvMessageTo=(TextView) convertView.findViewById(R.id.tv_message_to);  
  60.                 holder.ivMessageToHeadImage=(ImageView) convertView.findViewById(R.id.iv_message_to_head_image);  
  61.                   
  62.                 holder.tvMessageFrom=(TextView) convertView.findViewById(R.id.tv_message_from);  
  63.                 holder.ivMessageFromHeadImage=(ImageView) convertView.findViewById(R.id.iv_message_from_head_image);  
  64.                 convertView.setTag(holder);  
  65.             }else{  
  66.                 holder=(ViewHolder) convertView.getTag();  
  67.             }  
  68.               
  69.             Message message=messages.get(position);  
  70.             if(message.isSended()){//发送消息  
  71.                 holder.tvMessageTo.setVisibility(View.GONE);  
  72.                 holder.ivMessageToHeadImage.setVisibility(View.GONE);  
  73.                   
  74.                 holder.tvMessageFrom.setVisibility(View.VISIBLE);  
  75.                 holder.tvMessageFrom.setText(message.getContent());  
  76.                 holder.tvMessageFrom.setOnLongClickListener(longClickListener);  
  77.                 holder.tvMessageFrom.setTag(position);  
  78.                   
  79.                 holder.ivMessageFromHeadImage.setVisibility(View.VISIBLE);  
  80.             }else{//接收消息  
  81.                 holder.tvMessageFrom.setVisibility(View.GONE);  
  82.                 holder.ivMessageFromHeadImage.setVisibility(View.GONE);  
  83.                   
  84.                 holder.tvMessageTo.setVisibility(View.VISIBLE);  
  85.                 holder.tvMessageTo.setText(message.getContent());  
  86.                 holder.tvMessageTo.setOnLongClickListener(longClickListener);  
  87.                 holder.tvMessageTo.setTag(position);  
  88.                   
  89.                 holder.ivMessageToHeadImage.setVisibility(View.VISIBLE);  
  90.             }  
  91.             return convertView;  
  92.         }  
  93.           
  94.         private class ViewHolder{  
  95.             private ImageView ivMessageToHeadImage;//接收消息用户头像  
  96.             private TextView tvMessageTo;//接收消息内容  
  97.               
  98.             private ImageView ivMessageFromHeadImage;//发送消息用户头像  
  99.             private TextView tvMessageFrom;//发送消息内容  
  100.         }  
  101.     }  
  102.       
  103.     private OnLongClickListener longClickListener=new OnLongClickListener() {  
  104.         @Override  
  105.         public boolean onLongClick(View v) {  
  106.             longClickPosition=(Integer) v.getTag();  
  107.             showDialog(v);  
  108.             return true;  
  109.         }  
  110.     };  
  111.       
  112.     private void  showDialog(View view){  
  113.         if(null==popupWindow){  
  114.             View popView = LayoutInflater.from(this).inflate(R.layout.layout_long_click_dialog, null);  
  115.             tvDelete=(TextView) popView.findViewById(R.id.tv_delete);  
  116.             tvDelete.setOnClickListener(clickListener);  
  117.             popupWindow = new PopupWindow(popView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  118.             popupWindow.setAnimationStyle(R.style.PopAnimStyle);  
  119.             popupWindow.setOutsideTouchable(true);  
  120.             popupWindow.setBackgroundDrawable(new BitmapDrawable());  
  121.         }  
  122.         if (popupWindow.isShowing())  
  123.             popupWindow.dismiss();  
  124.           
  125.         //第一次显示控件的时候宽高会为0   
  126.         int deleteHeight=tvDelete.getHeight()==0?145:tvDelete.getHeight();  
  127.         int deleteWidth=tvDelete.getWidth()==0?212:tvDelete.getWidth();  
  128.           
  129.         popupWindow.showAsDropDown(view,(view.getWidth()-deleteWidth)/2,-view.getHeight()-deleteHeight);  
  130.     }  
  131.       
  132.     private OnClickListener clickListener=new OnClickListener() {  
  133.         @Override  
  134.         public void onClick(View v) {  
  135.             switch (v.getId()) {  
  136.             case R.id.tv_delete:  
  137.                 messages.remove(longClickPosition);  
  138.                 mAdapter.notifyDataSetChanged();  
  139.                   
  140.                 popupWindow.dismiss();  
  141.                 break;  
  142.             case R.id.tv_send_message:  
  143.                 String content=etInput.getText().toString().trim();  
  144.                 if(!TextUtils.isEmpty(content)){  
  145.                     Message message=new Message(content, true);  
  146.                     messages.add(message);  
  147.                     mAdapter.notifyDataSetChanged();  
  148.                     listView.setSelection(mAdapter.getCount()-1);  
  149.                 }  
  150.                 break;  
  151.             }  
  152.         }  
  153.     };  
  154.       
  155.     private void initData(){  
  156.         Message message=new Message("范德萨范德", true);  
  157.         Message message7=new Message("范德萨范德fds", true);  
  158.         Message message1=new Message("个人提个人鬼地", false);  
  159.         Message message4=new Message("接收消息", false);  
  160.         Message message2=new Message("吃饭了嘛。。。。吃过了没有啊。。。。。还没有吃啊 范德萨范德萨发水电费的说法都是", true);  
  161.         Message message3=new Message("吃饭了嘛。。。。吃过了没有啊。。。。。还没有吃啊 范德萨范德萨发水电费的说法都是", false);  
  162.         messages.add(message);  
  163.         messages.add(message1);  
  164.         messages.add(message2);  
  165.         messages.add(message3);  
  166.         messages.add(message4);  
  167.         messages.add(message7);  
  168.     }  
  169. }  

消息详细列表布局文件 activity_private_message_detail_list.xml     

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <ListView  
  7.         android:id="@+id/list_private_message"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="match_parent"  
  10.         android:layout_above="@+id/ll_bottom"  
  11.         android:divider="@null" >  
  12.     </ListView>  
  13.   
  14.     <include  
  15.         android:id="@+id/ll_bottom"  
  16.         android:layout_width="match_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:layout_alignParentBottom="true"  
  19.         layout="@layout/layout_input_comment" />  
  20.   
  21. </RelativeLayout>  

底部输入框布局

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_height="wrap_content"  
  5.     android:orientation="vertical">  
  6.   
  7.     <RelativeLayout  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:paddingBottom="7dip"  
  11.         android:paddingTop="7dip">  
  12.           
  13.         <ImageView  
  14.             android:id="@+id/iv_message_to_head_image"  
  15.             android:layout_alignParentLeft="true"  
  16.             android:layout_marginLeft="5dp"  
  17.             android:layout_marginRight="5dp"  
  18.             android:layout_width="40dp"  
  19.             android:layout_height="40dp"  
  20.             android:src="@drawable/slide_left_avatar_default"/>  
  21.   
  22.         <TextView  
  23.             android:id="@+id/tv_message_to"  
  24.             android:layout_width="wrap_content"  
  25.             android:layout_height="wrap_content"  
  26.             android:background="@drawable/icon_message_to"  
  27.             android:gravity="center"  
  28.             android:paddingLeft="20dip"  
  29.             android:textColor="@color/register_text_color"  
  30.             android:layout_toRightOf="@+id/iv_message_to_head_image"  
  31.             android:layout_marginRight="55dp"  
  32.             android:textSize="16dip"/>  
  33.   
  34.         <TextView  
  35.             android:id="@+id/tv_message_from"  
  36.             android:layout_width="wrap_content"  
  37.             android:layout_height="wrap_content"  
  38.             android:layout_toLeftOf="@+id/iv_message_from_head_image"  
  39.             android:background="@drawable/icon_message_from"  
  40.             android:gravity="center"  
  41.             android:paddingRight="20dip"  
  42.             android:textColor="@color/white_normal"  
  43.             android:layout_marginLeft="55dp"  
  44.             android:text="我已经吃过了"  
  45.             android:textSize="16dip"/>  
  46.           
  47.         <!--          -->  
  48.         <ImageView  
  49.             android:id="@+id/iv_message_from_head_image"  
  50.             android:layout_alignParentRight="true"  
  51.             android:layout_marginLeft="5dp"  
  52.             android:layout_marginRight="5dp"  
  53.             android:layout_width="40dp"  
  54.             android:layout_height="40dp"  
  55.             android:src="@drawable/slide_left_avatar_default"/>  
  56.     </RelativeLayout>  
  57.   
  58. </LinearLayout>  

每一条消息的布局文件

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_height="wrap_content"  
  5.     android:orientation="vertical">  
  6.   
  7.     <RelativeLayout  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:paddingBottom="7dip"  
  11.         android:paddingTop="7dip">  
  12.           
  13.         <ImageView  
  14.             android:id="@+id/iv_message_to_head_image"  
  15.             android:layout_alignParentLeft="true"  
  16.             android:layout_marginLeft="5dp"  
  17.             android:layout_marginRight="5dp"  
  18.             android:layout_width="40dp"  
  19.             android:layout_height="40dp"  
  20.             android:src="@drawable/slide_left_avatar_default"/>  
  21.   
  22.         <TextView  
  23.             android:id="@+id/tv_message_to"  
  24.             android:layout_width="wrap_content"  
  25.             android:layout_height="wrap_content"  
  26.             android:background="@drawable/icon_message_to"  
  27.             android:gravity="center"  
  28.             android:paddingLeft="20dip"  
  29.             android:textColor="@color/register_text_color"  
  30.             android:layout_toRightOf="@+id/iv_message_to_head_image"  
  31.             android:layout_marginRight="55dp"  
  32.             android:textSize="16dip"/>  
  33.   
  34.         <TextView  
  35.             android:id="@+id/tv_message_from"  
  36.             android:layout_width="wrap_content"  
  37.             android:layout_height="wrap_content"  
  38.             android:layout_toLeftOf="@+id/iv_message_from_head_image"  
  39.             android:background="@drawable/icon_message_from"  
  40.             android:gravity="center"  
  41.             android:paddingRight="20dip"  
  42.             android:textColor="@color/white_normal"  
  43.             android:layout_marginLeft="55dp"  
  44.             android:text="我已经吃过了"  
  45.             android:textSize="16dip"/>  
  46.           
  47.         <!--          -->  
  48.         <ImageView  
  49.             android:id="@+id/iv_message_from_head_image"  
  50.             android:layout_alignParentRight="true"  
  51.             android:layout_marginLeft="5dp"  
  52.             android:layout_marginRight="5dp"  
  53.             android:layout_width="40dp"  
  54.             android:layout_height="40dp"  
  55.             android:src="@drawable/slide_left_avatar_default"/>  
  56.     </RelativeLayout>  
  57.   
  58. </LinearLayout>  

弹出删除按钮的布局文件

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <TextView  
  7.         android:id="@+id/tv_delete"  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:background="@drawable/icon_private_message_delete"  
  11.         android:gravity="center_horizontal"  
  12.         android:padding="5dp"  
  13.         android:text="删除"  
  14.         android:textColor="#ffffffff" />  
  15.   
  16. </FrameLayout>  

点击链接下载源码

时间: 2024-12-31 04:20:55

Android仿qq聊天记录长按删除功能效果的相关文章

Android仿qq聊天记录待定与删除功能效果

模仿手机qq,历史聊天记录长按会弹出待定和删除按钮的效果.qq效果图  代码实现的效果图   首先,看到这个效果,想一下实现的思路:弹出的待办和删除按钮,是通过dialog实现的.那么这个dialog就要能完成几个效果,第一:自定义界面,第二:控制dialog的显示位置,第三:点击dialog区域之外的地方,dialog要消失,第四:dialog显示的时候,activity不要变暗.下面就一步一步解决问题: 1,自定义dialog package com.example.listitemdele

Android仿QQ空间动态界面分享功能

先看看效果: 用极少的代码实现了 动态详情 及 二级评论 的 数据获取与处理 和 UI显示与交互,并且高解耦.高复用.高灵活. 动态列表界面MomentListFragment支持 下拉刷新与上拉加载 和 模糊搜索,反复快速滑动仍然非常流畅. 缓存机制使得数据可在启动界面后瞬间加载完成. 动态详情界面MomentActivity支持 (取消)点赞.(删除)评论.点击姓名跳到个人详情 等. 只有1张图片时图片放大显示,超过1张则按九宫格显示. 用到的CommentContainerView和Mom

Android仿QQ列表左滑删除操作_Android

最近学习了如何做一个像QQ的左滑RecyclerView的item显示选项的,主要是用到Scroller 我们首先新建一个自己的RecyclerView 定义好一些要用的的变量 重写构造方法,把前两个构造方法改为如下,使无论如何构造都要执行第三个构造方法 在第三个构造方法里初始化Scroller public class LeftSwipeMenuRecyclerView extends RecyclerView { //置顶按钮 private TextView tvTop; //删除按钮 p

Android仿QQ列表左滑删除操作

最近学习了如何做一个像QQ的左滑RecyclerView的item显示选项的,主要是用到Scroller 我们首先新建一个自己的RecyclerView 定义好一些要用的的变量 重写构造方法,把前两个构造方法改为如下,使无论如何构造都要执行第三个构造方法 在第三个构造方法里初始化Scroller public class LeftSwipeMenuRecyclerView extends RecyclerView { //置顶按钮 private TextView tvTop; //删除按钮 p

Android 自定View实现仿QQ运动步数圆弧及动画效果_Android

在之前的Android超精准计步器开发-Dylan计步中的首页用到了一个自定义控件,和QQ运动的界面有点类似,还有动画效果,下面就来讲一下这个View是如何绘制的. 1.先看效果图 2.效果图分析 功能说明:黄色的代表用户设置的总计划锻炼步数,红色的代表用户当前所走的步数. 初步分析:完全自定义View重写onDraw()方法,画圆弧. 3.画一个圆弧必备知识 在Canvas中有一个画圆弧的方法 drawArc(RectF oval, float startAngle, float sweepA

Android仿QQ长按删除弹出框功能示例

废话不说,先看一下效果图,如果大家感觉不错,请参考实现代码: 对于列表来说,如果想操作某个列表项,一般会采用长按弹出菜单的形式,默认的上下文菜单比较难看,而QQ的上下文菜单就人性化多了,整个菜单给用户一种气泡弹出的感觉,而且会显示在手指按下的位置,而技术实现我之前是使用popupWindow和RecyclerView实现的,上面一个RecyclerView,下面一个小箭头ImageView,但后来发现没有必要,而且可定制化也不高,还是使用多个TextView更好一点. 我封装了一下,只需要一个P

Android自定义ListView实现仿QQ可拖拽列表功能_Android

我们大致的思路,其实是这样子的,也是我的设想,我们可以先去实现一个简单的ListView的数据,但是他的Adapter,我们可以用系统封装好的,然后传递进去一个实体类,最后自定义一个listview去操作,所以我们先把准备的工作做好,比如? list_item.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.a

Android仿QQ、微信聊天界面长按提示框效果_Android

先来看看效果图 如何使用 示例代码 PromptViewHelper pvHelper = new PromptViewHelper(mActivity); pvHelper.setPromptViewManager(new ChatPromptViewManager(mActivity)); pvHelper.addPrompt(holder.itemView.findViewById(R.id.textview_content)); 使用起来还是很简单的 首先new一个PromptViewH

Android自定义ListView实现仿QQ可拖拽列表功能

我们大致的思路,其实是这样子的,也是我的设想,我们可以先去实现一个简单的ListView的数据,但是他的Adapter,我们可以用系统封装好的,然后传递进去一个实体类,最后自定义一个listview去操作,所以我们先把准备的工作做好,比如? list_item.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.a