通过继承ListView然后结合PopupWindow实现

首先是布局文件:
delete_btn.xml:这里只需要一个Button

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:orientation="vertical" >  <Button   android:id="@+id/id_item_btn"  android:layout_width="60dp"  android:singleLine="true"  android:layout_height="wrap_content"  android:text="删除"  android:background="@drawable/d_delete_btn"  android:textColor="#ffffff"  android:paddingLeft="15dp"  android:paddingRight="15dp"  android:layout_alignParentRight="true"  android:layout_centerVertical="true"  android:layout_marginRight="15dp"  />
</LinearLayout>  

主布局文件:activity_main.xml,ListView的每个Item的样式直接使用了系统的android.R.layout.simple_list_item_1

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent" >  <com.example.listviewitemslidedeletebtnshow.QQListView  android:id="@+id/id_listview"  android:layout_width="fill_parent"  android:layout_height="wrap_content" >  </com.example.listviewitemslidedeletebtnshow.QQListView>  </RelativeLayout>  

接下来看看QQListView的实现:

package com.example.listviewitemslidedeletebtnshow;import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;public class QQListView extends ListView
{private static final String TAG = "QQlistView";// private static final int VELOCITY_SANP = 200;// private VelocityTracker mVelocityTracker;/*** 用户滑动的最小距离*/private int touchSlop;/*** 是否响应滑动*/private boolean isSliding;/*** 手指按下时的x坐标*/private int xDown;/*** 手指按下时的y坐标*/private int yDown;/*** 手指移动时的x坐标*/private int xMove;/*** 手指移动时的y坐标*/private int yMove;private LayoutInflater mInflater;private PopupWindow mPopupWindow;private int mPopupWindowHeight;private int mPopupWindowWidth;private Button mDelBtn;/*** 为删除按钮提供一个回调接口*/private DelButtonClickListener mListener;/*** 当前手指触摸的View*/private View mCurrentView;/*** 当前手指触摸的位置*/private int mCurrentViewPos;/*** 必要的一些初始化* * @param context* @param attrs*/public QQListView(Context context, AttributeSet attrs){super(context, attrs);mInflater = LayoutInflater.from(context);touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();View view = mInflater.inflate(R.layout.delete_btn, null);mDelBtn = (Button) view.findViewById(R.id.id_item_btn);mPopupWindow = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);/*** 先调用下measure,否则拿不到宽和高*/mPopupWindow.getContentView().measure(0, 0);mPopupWindowHeight = mPopupWindow.getContentView().getMeasuredHeight();mPopupWindowWidth = mPopupWindow.getContentView().getMeasuredWidth();}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev){int action = ev.getAction();int x = (int) ev.getX();int y = (int) ev.getY();switch (action){case MotionEvent.ACTION_DOWN:xDown = x;yDown = y;/*** 如果当前popupWindow显示,则直接隐藏,然后屏蔽ListView的touch事件的下传*/if (mPopupWindow.isShowing()){dismissPopWindow();return false;}// 获得当前手指按下时的item的位置mCurrentViewPos = pointToPosition(xDown, yDown);// 获得当前手指按下时的itemView view = getChildAt(mCurrentViewPos - getFirstVisiblePosition());mCurrentView = view;break;case MotionEvent.ACTION_MOVE:xMove = x;yMove = y;int dx = xMove - xDown;int dy = yMove - yDown;/*** 判断是否是从右到左的滑动*/if (xMove < xDown && Math.abs(dx) > touchSlop && Math.abs(dy) < touchSlop){// Log.e(TAG, "touchslop = " + touchSlop + " , dx = " + dx +// " , dy = " + dy);isSliding = true;}break;}return super.dispatchTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent ev){int action = ev.getAction();/*** 如果是从右到左的滑动才相应*/if (isSliding){switch (action){case MotionEvent.ACTION_MOVE:int[] location = new int[2];// 获得当前item的位置x与ymCurrentView.getLocationOnScreen(location);// 设置popupWindow的动画mPopupWindow.setAnimationStyle(R.style.popwindow_delete_btn_anim_style);mPopupWindow.update();mPopupWindow.showAtLocation(mCurrentView, Gravity.LEFT | Gravity.TOP,location[0] + mCurrentView.getWidth(), location[1] + mCurrentView.getHeight() / 2- mPopupWindowHeight / 2);Log.i("test", "location="+location[0]+","+location[1]);// 设置删除按钮的回调mDelBtn.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){if (mListener != null){mListener.clickHappend(mCurrentViewPos);mPopupWindow.dismiss();}}});// Log.e(TAG, "mPopupWindow.getHeight()=" + mPopupWindowHeight);break;case MotionEvent.ACTION_UP:isSliding = false;}// 相应滑动期间屏幕itemClick事件,避免发生冲突return true;}return super.onTouchEvent(ev);}/*** 隐藏popupWindow*/private void dismissPopWindow(){if (mPopupWindow != null && mPopupWindow.isShowing()){mPopupWindow.dismiss();}}public void setDelButtonClickListener(DelButtonClickListener listener){mListener = listener;}interface DelButtonClickListener{public void clickHappend(int position);}}

代码注释写得很详细,简单说一下,在dispatchTouchEvent中设置当前是否响应用户滑动,然后在onTouchEvent中判断是否响应,如果响应则popupWindow以动画的形式展示出来。当然屏幕上如果存在PopupWindow则屏幕ListView的滚动与Item的点击,以及从右到左滑动时屏幕Item的click事件。

点击时记录下当前的位置,再判断是否右滑,如果右滑则出现popupWindow,根据按下时记录下的位置判断出popuwindow出现的位置。

MainActivity.java

package com.example.listviewitemslidedeletebtnshow;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Toast;import com.example.listviewitemslidedeletebtnshow.QQListView.DelButtonClickListener;public class MainActivity extends Activity
{private QQListView mListView;private ArrayAdapter<String> mAdapter;private List<String> mDatas;@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mListView = (QQListView) findViewById(R.id.id_listview);// 不要直接Arrays.asListmDatas = new ArrayList<String>(Arrays.asList("HelloWorld", "Welcome", "Java", "Android", "Servlet", "Struts","Hibernate", "Spring", "HTML5", "Javascript", "Lucene"));mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mDatas);mListView.setAdapter(mAdapter);mListView.setDelButtonClickListener(new DelButtonClickListener(){@Overridepublic void clickHappend(final int position){Toast.makeText(MainActivity.this, position + " : " + mAdapter.getItem(position), 1).show();mAdapter.remove(mAdapter.getItem(position));}});mListView.setOnItemClickListener(new OnItemClickListener(){@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id){Toast.makeText(MainActivity.this, position + " : " + mAdapter.getItem(position), 1).show();}});}
}

注意,这里使用了一种设计方法

在QQListView中定义了接口

public void setDelButtonClickListener(DelButtonClickListener listener){mListener = listener;}interface DelButtonClickListener{public void clickHappend(int position);}

在MainActivity中实例化,然后listView中会调用

mListView.setDelButtonClickListener(new DelButtonClickListener(){@Overridepublic void clickHappend(final int position){Toast.makeText(MainActivity.this, position + " : " + mAdapter.getItem(position), 1).show();mAdapter.remove(mAdapter.getItem(position));}});

实例化的clickHappend方法。

参考资料

ListView滑动删除 ,仿腾讯QQ - Hongyang - 博客频道 - CSDN.NET

Android PopupWindow的使用和分析 - 圣骑士wind - 博客园

PopUpWindow使用详解(一)——基本使用 - 启舰 - 博客频道 - CSDN.NET

完成

ListView滑动删除效果实现相关推荐

  1. 高仿微信对话列表滑动删除效果

    前言 用过微信的都知道.微信对话列表滑动删除效果是非常不错的,这个效果我们也能够有. 思路事实上非常easy,弄个ListView.然后里面的每一个item做成一个能够滑动的自己定义控件就可以.由于L ...

  2. android微信列表滑动删除,Android仿微信对话列表滑动删除效果

    微信对话列表滑动删除效果很不错的,借鉴了github上SwipeListView(项目地址:https://github.com/likebamboo/SwipeListView),在其上进行了一些重 ...

  3. Android ListView滑动删除及响应事件详解

    目标:实现类似QQ,微信的消息列表滑动删除 具体操作: 1. 主页面布局 首先在布局文件(本例是activity_main.xml)中引入ListView控件,并指定id(如下代码中黑体部分). &l ...

  4. ListView滑动删除 ,仿腾讯QQ

    转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/22961279 在CSDN上开了很多大神们的文章,感觉受益良多,也非常欣赏大家的分 ...

  5. SwipeListView 详解 实现微信,QQ等滑动删除效果

    为什么80%的码农都做不了架构师?>>>    今天看别人项目,看到别人使用了SwipeListView,Google一把,果然github上的,也参考了csdn上的几篇文章,然后自 ...

  6. html5滑动删除置顶,js实现移动端向左滑动删除效果

    使用插件alloy_finger.js (vue方法使用) 1.引用js 2.html方法的使用 3.js方法的使用 Vue.use(AlloyFingerVue); var vm=new Vue({ ...

  7. Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877),请尊重他人的辛勤劳动成果,谢谢! 今天还是 ...

  8. Android开发学习之仿手机QQ消息列表侧滑删除效果

    今天想和大家分享的是手机QQ消息列表侧滑删除效果,这种效果在IOS中被封装为一个列表控件,而手机QQ则是将这个功能移植到了Android上,换言之,这并非是手机QQ的独创.尽管如此,用户体验依然得到了 ...

  9. Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199) 我在上一篇文章中Android 带你从源码的角度解析 ...

最新文章

  1. 这是预编译工具生成的文件_组件化架构 10.编译优化
  2. python第三方库排行-Python模块汇总(常用第三方库)
  3. hyperopt中文文档:Interfacing-With-Other-Languages(在其他语言中使用hyperopt)
  4. 计算机专业复试线380,445名400+的科软复试线388分,计算机学硕380分,卷炸了
  5. Connections between cities
  6. java中Comparable实现对象的比较
  7. ESP32驱动LCD液晶屏选型、262K什么意思?SPI写LCD的GRAM时序、MCU液晶屏驱动IC的寄存器功能
  8. xcode5切换IOS7,IOS6,IOS5模拟器
  9. python selenuim使用代理的方式
  10. 施耐德编程软件Unity Pro XL授权步骤
  11. 记账时对收支、借还款进行分类记录
  12. 弹出USB大容量存储设备时出问题 的解决方法
  13. vue 解决控制台Prop being mutated: “placement“报错
  14. word刷子刷格式_Word文档中格式刷怎么用?
  15. linux修改时区为UTC
  16. 郭霖:手把手教你实现 App 360 度旋转看车效果
  17. 如何将caj转换成word?caj转Word工具
  18. C++ 模板函数 二分查找
  19. Codeforces 855G Harry Vs Voldemort 边双连通分量+并查集
  20. 人工智能在医学影像中的研究与应用

热门文章

  1. EMNLP'21 | 让压缩语言模型自动搜索最优结构!
  2. 互联网(IT)大厂面试技巧(面经)
  3. LayerNorm是Transformer的最优解吗?
  4. 他与她,一个两年前的故事
  5. Android自定义Lint实践
  6. 前端渲染引擎doT.js解析
  7. 直通BAT必考题系列:深入剖析JVM之G1收集器、及回收流程、与推荐用例
  8. Java经典基础与高级面试36题和答案
  9. 论文浅尝 - ACL2022 | 面向推理阅读理解的神经符号方法
  10. pip加速+百度镜像|清华镜像