高仿腾讯QQ侧滑删除

继承ListView然后结合PopupWindow。


首先是布局文件:

delete_btn.xml:这里只需要一个Button


[html]  view plain  copy
  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.       <Button   
  7.         android:id="@+id/id_item_btn"  
  8.         android:layout_width="60dp"  
  9.         android:singleLine="true"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="删除"  
  12.         android:background="@drawable/d_delete_btn"  
  13.         android:textColor="#ffffff"  
  14.         android:paddingLeft="15dp"  
  15.         android:paddingRight="15dp"  
  16.         android:layout_alignParentRight="true"  
  17.         android:layout_centerVertical="true"  
  18.         android:layout_marginRight="15dp"  
  19.         />  
  20. </LinearLayout>  
主布局文件:activity_main.xml ,ListView的每个Item的样式直接使用了系统的android.R.layout.simple_list_item_1

[html]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <com.example.listviewitemslidedeletebtnshow.QQListView  
  7.         android:id="@+id/id_listview"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="wrap_content" >  
  10.     </com.example.listviewitemslidedeletebtnshow.QQListView>  
  11.   
  12. </RelativeLayout>  
接下来看看QQListView的实现:

[java]  view plain  copy
  1. package com.example.listviewitemslidedeletebtnshow;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.view.Gravity;  
  6. import android.view.LayoutInflater;  
  7. import android.view.MotionEvent;  
  8. import android.view.View;  
  9. import android.view.ViewConfiguration;  
  10. import android.widget.Button;  
  11. import android.widget.LinearLayout;  
  12. import android.widget.ListView;  
  13. import android.widget.PopupWindow;  
  14.   
  15. public class QQListView extends ListView  
  16. {  
  17.   
  18.     private static final String TAG = "QQlistView";  
  19.   
  20.     // private static final int VELOCITY_SANP = 200;  
  21.     // private VelocityTracker mVelocityTracker;  
  22.     /** 
  23.      * 用户滑动的最小距离 
  24.      */  
  25.     private int touchSlop;  
  26.   
  27.     /** 
  28.      * 是否响应滑动 
  29.      */  
  30.     private boolean isSliding;  
  31.   
  32.     /** 
  33.      * 手指按下时的x坐标 
  34.      */  
  35.     private int xDown;  
  36.     /** 
  37.      * 手指按下时的y坐标 
  38.      */  
  39.     private int yDown;  
  40.     /** 
  41.      * 手指移动时的x坐标 
  42.      */  
  43.     private int xMove;  
  44.     /** 
  45.      * 手指移动时的y坐标 
  46.      */  
  47.     private int yMove;  
  48.   
  49.     private LayoutInflater mInflater;  
  50.   
  51.     private PopupWindow mPopupWindow;  
  52.     private int mPopupWindowHeight;  
  53.     private int mPopupWindowWidth;  
  54.   
  55.     private Button mDelBtn;  
  56.     /** 
  57.      * 为删除按钮提供一个回调接口 
  58.      */  
  59.     private DelButtonClickListener mListener;  
  60.   
  61.     /** 
  62.      * 当前手指触摸的View 
  63.      */  
  64.     private View mCurrentView;  
  65.   
  66.     /** 
  67.      * 当前手指触摸的位置 
  68.      */  
  69.     private int mCurrentViewPos;  
  70.   
  71.     /** 
  72.      * 必要的一些初始化 
  73.      *  
  74.      * @param context 
  75.      * @param attrs 
  76.      */  
  77.     public QQListView(Context context, AttributeSet attrs)  
  78.     {  
  79.         super(context, attrs);  
  80.   
  81.         mInflater = LayoutInflater.from(context);  
  82.         touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();  
  83.   
  84.         View view = mInflater.inflate(R.layout.delete_btn, null);  
  85.         mDelBtn = (Button) view.findViewById(R.id.id_item_btn);  
  86.         mPopupWindow = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT,  
  87.                 LinearLayout.LayoutParams.WRAP_CONTENT);  
  88.         /** 
  89.          * 先调用下measure,否则拿不到宽和高 
  90.          */  
  91.         mPopupWindow.getContentView().measure(00);  
  92.         mPopupWindowHeight = mPopupWindow.getContentView().getMeasuredHeight();  
  93.         mPopupWindowWidth = mPopupWindow.getContentView().getMeasuredWidth();  
  94.     }  
  95.   
  96.     @Override  
  97.     public boolean dispatchTouchEvent(MotionEvent ev)  
  98.     {  
  99.         int action = ev.getAction();  
  100.         int x = (int) ev.getX();  
  101.         int y = (int) ev.getY();  
  102.         switch (action)  
  103.         {  
  104.   
  105.         case MotionEvent.ACTION_DOWN:  
  106.             xDown = x;  
  107.             yDown = y;  
  108.             /** 
  109.              * 如果当前popupWindow显示,则直接隐藏,然后屏蔽ListView的touch事件的下传 
  110.              */  
  111.             if (mPopupWindow.isShowing())  
  112.             {  
  113.                 dismissPopWindow();  
  114.                 return false;  
  115.             }  
  116.             // 获得当前手指按下时的item的位置  
  117.             mCurrentViewPos = pointToPosition(xDown, yDown);  
  118.             // 获得当前手指按下时的item  
  119.             View view = getChildAt(mCurrentViewPos - getFirstVisiblePosition());  
  120.             mCurrentView = view;  
  121.             break;  
  122.         case MotionEvent.ACTION_MOVE:  
  123.             xMove = x;  
  124.             yMove = y;  
  125.             int dx = xMove - xDown;  
  126.             int dy = yMove - yDown;  
  127.             /** 
  128.              * 判断是否是从右到左的滑动 
  129.              */  
  130.             if (xMove < xDown && Math.abs(dx) > touchSlop && Math.abs(dy) < touchSlop)  
  131.             {  
  132.                 // Log.e(TAG, "touchslop = " + touchSlop + " , dx = " + dx +  
  133.                 // " , dy = " + dy);  
  134.                 isSliding = true;  
  135.             }  
  136.             break;  
  137.         }  
  138.         return super.dispatchTouchEvent(ev);  
  139.     }  
  140.   
  141.     @Override  
  142.     public boolean onTouchEvent(MotionEvent ev)  
  143.     {  
  144.         int action = ev.getAction();  
  145.         /** 
  146.          * 如果是从右到左的滑动才相应 
  147.          */  
  148.         if (isSliding)  
  149.         {  
  150.             switch (action)  
  151.             {  
  152.             case MotionEvent.ACTION_MOVE:  
  153.   
  154.                 int[] location = new int[2];  
  155.                 // 获得当前item的位置x与y  
  156.                 mCurrentView.getLocationOnScreen(location);  
  157.                 // 设置popupWindow的动画  
  158.                 mPopupWindow.setAnimationStyle(R.style.popwindow_delete_btn_anim_style);  
  159.                 mPopupWindow.update();  
  160.                 mPopupWindow.showAtLocation(mCurrentView, Gravity.LEFT | Gravity.TOP,  
  161.                         location[0] + mCurrentView.getWidth(), location[1] + mCurrentView.getHeight() / 2  
  162.                                 - mPopupWindowHeight / 2);  
  163.                 // 设置删除按钮的回调  
  164.                 mDelBtn.setOnClickListener(new OnClickListener()  
  165.                 {  
  166.                     @Override  
  167.                     public void onClick(View v)  
  168.                     {  
  169.                         if (mListener != null)  
  170.                         {  
  171.                             mListener.clickHappend(mCurrentViewPos);  
  172.                             mPopupWindow.dismiss();  
  173.                         }  
  174.                     }  
  175.                 });  
  176.                 // Log.e(TAG, "mPopupWindow.getHeight()=" + mPopupWindowHeight);  
  177.   
  178.                 break;  
  179.             case MotionEvent.ACTION_UP:  
  180.                 isSliding = false;  
  181.   
  182.             }  
  183.             // 相应滑动期间屏幕itemClick事件,避免发生冲突  
  184.             return true;  
  185.         }  
  186.   
  187.         return super.onTouchEvent(ev);  
  188.     }  
  189.   
  190.     /** 
  191.      * 隐藏popupWindow 
  192.      */  
  193.     private void dismissPopWindow()  
  194.     {  
  195.         if (mPopupWindow != null && mPopupWindow.isShowing())  
  196.         {  
  197.             mPopupWindow.dismiss();  
  198.         }  
  199.     }  
  200.   
  201.     public void setDelButtonClickListener(DelButtonClickListener listener)  
  202.     {  
  203.         mListener = listener;  
  204.     }  
  205.   
  206.     interface DelButtonClickListener  
  207.     {  
  208.         public void clickHappend(int position);  
  209.     }  
  210.   
  211. }  
代码注释写得很详细,简单说一下,在dispatchTouchEvent中设置当前是否响应用户滑动,然后在onTouchEvent中判断是否响应,如果响应则popupWindow以动画的形式展示出来。当然屏幕上如果存在PopupWindow则屏幕ListView的滚动与Item的点击,以及从右到左滑动时屏幕Item的click事件。

接下来是MainActivity.Java,这里代码很简单不做介绍了。

[java]  view plain  copy
  1. package com.example.listviewitemslidedeletebtnshow;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Arrays;  
  5. import java.util.List;  
  6.   
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.view.View;  
  10. import android.widget.AdapterView;  
  11. import android.widget.AdapterView.OnItemClickListener;  
  12. import android.widget.ArrayAdapter;  
  13. import android.widget.Toast;  
  14.   
  15. import com.example.listviewitemslidedeletebtnshow.QQListView.DelButtonClickListener;  
  16.   
  17. public class MainActivity extends Activity  
  18. {  
  19.     private QQListView mListView;  
  20.     private ArrayAdapter<String> mAdapter;  
  21.     private List<String> mDatas;  
  22.   
  23.     @Override  
  24.     protected void onCreate(Bundle savedInstanceState)  
  25.     {  
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.activity_main);  
  28.   
  29.         mListView = (QQListView) findViewById(R.id.id_listview);  
  30.         // 不要直接Arrays.asList  
  31.         mDatas = new ArrayList<String>(Arrays.asList("HelloWorld""Welcome""Java""Android""Servlet""Struts",  
  32.                 "Hibernate""Spring""HTML5""Javascript""Lucene"));  
  33.         mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mDatas);  
  34.         mListView.setAdapter(mAdapter);  
  35.   
  36.         mListView.setDelButtonClickListener(new DelButtonClickListener()  
  37.         {  
  38.             @Override  
  39.             public void clickHappend(final int position)  
  40.             {  
  41.                 Toast.makeText(MainActivity.this, position + " : " + mAdapter.getItem(position), 1).show();  
  42.                 mAdapter.remove(mAdapter.getItem(position));  
  43.             }  
  44.         });  
  45.   
  46.         mListView.setOnItemClickListener(new OnItemClickListener()  
  47.         {  
  48.             @Override  
  49.             public void onItemClick(AdapterView<?> parent, View view, int position, long id)  
  50.             {  
  51.                 Toast.makeText(MainActivity.this, position + " : " + mAdapter.getItem(position), 1).show();  
  52.             }  
  53.         });  
  54.     }  
  55. }  
效果图如下:楼主使用asm.jar以及gifcamera截的gif,由于button的动画很短感觉截图效果很卡不流畅,大家有什么好的截图,还望推荐。有兴趣的还是下载源码看看效果i。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,以下是关于"c"的回答: C是英文字母表中的第三个字母,有着与其他字母不同的音节和形状。它没有直接的中文注音,但在汉语中有一些与之相关的词汇。 首先,C在计算机科学中是一种编程语言。C语言是一种通用的计算机编程语言,广泛应用于软件开发、嵌入式系统和操作系统的构建。它具有高效、灵活和强大的特点,是计算机科学学习的重要基础。 此外,C还可以代表一些数字和符号。在罗马数字中,C表示100,代表正百。在化学元素周期表中,C是碳的化学符号,碳是一种常见的元素,它存在于自然界中的许多有机物质中。 此外,C还可以表示一些描述词。比如,Courage(勇气),表示勇敢和坚决的品质。Creativity(创造力),表示创新和创造的能力。Confidence(自信),表示对自己的能力和行为有信心。 总而言之,C是一个多义词,在不同的领域有着不同的含义和用途。无论是在计算机科学、数学、化学,还是在描述人的品质等方面,C都扮演着重要的角色。 ### 回答2: “C”可以有很多不同的含义和用途。首先,它是英语字母表中的第三个字母,也是拉丁字母表的起源之一。在现代英语中,它是一个常见的字母,用于表示许多单词的开头,如“cat”(猫)、 “car”(汽车)和“city”(城市)。 此外,C还有很多其他的用途。在数学中,C通常表示复数集合,例如C={a + bi | a, b∈R},其中“a”和“b”是实数,“i”是虚数单位。在计算机编程中,C是一种广泛使用的编程语言,特别适合系统和应用软件的开发。 C还有其他一些重要的意义。在音乐中,C代表了C调,也被称为“Do”。C还是一种国际音标中的声母,例如在单词“cat”中的第一个音素/k/,就是以C来表示的。 在化学中,C是碳元素的化学符号,它是地球上最常见和最丰富的元素之一,构成了许多有机化合物的基础。 最后,C也可以表示一些重要的概念,如创新、合作和社区。创新(Creativity)是指创造和提出新想法和方法的能力。合作(Collaboration)是指多人共同努力以达到共同目标的行为。社区(Community)是指人们共同生活、学习和工作的社会集体。 总之,“C”有许多不同的用途和含义,涵盖了语言、科学、技术、音乐和社会等多个领域,展示了它的广泛和多样化的意义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值