《Android SwipeToDismiss:左右滑动删除ListView条目Item》

Android的SwipeToDismiss是github上一个第三方开源框架(github上的项目链接地址:https://github.com/romannurik/Android-SwipeToDismiss )。该开源项目旨在:使得一个ListView的item在用户的手指在屏幕上左滑或者右滑时候,删除当前的这个ListView Item。

下载地址:点此下载

将开源框架文件加入这里:

将图片圆形化处理的类:CircleImageView

  1 package com.lixu.qqchehua;
  2
  3 import android.content.Context;
  4 import android.content.res.TypedArray;
  5 import android.graphics.Bitmap;
  6 import android.graphics.BitmapShader;
  7 import android.graphics.Canvas;
  8 import android.graphics.Color;
  9 import android.graphics.Matrix;
 10 import android.graphics.Paint;
 11 import android.graphics.Paint.Align;
 12 import android.graphics.Rect;
 13 import android.graphics.RectF;
 14 import android.graphics.Shader;
 15 import android.graphics.SweepGradient;
 16 import android.graphics.drawable.BitmapDrawable;
 17 import android.graphics.drawable.ColorDrawable;
 18 import android.graphics.drawable.Drawable;
 19 import android.net.Uri;
 20 import android.text.TextPaint;
 21 import android.util.AttributeSet;
 22 import android.util.FloatMath;
 23 import android.widget.ImageView;
 24
 25 /**
 26  * @author Phil
 27  *
 28  */
 29 public class CircleImageView extends ImageView {
 30
 31     private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
 32
 33     private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
 34     private static final int COLORDRAWABLE_DIMENSION = 2;
 35
 36     // 圆形边框的厚度默认值。
 37     // 如果是0,则没有天蓝色渐变的边框。
 38     private static final int DEFAULT_BORDER_WIDTH = 0;
 39
 40     private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
 41
 42     private final RectF mDrawableRect = new RectF();
 43     private final RectF mBorderRect = new RectF();
 44
 45     private final Matrix mShaderMatrix = new Matrix();
 46     private final Paint mBitmapPaint = new Paint();
 47     private final Paint mBorderPaint = new Paint();
 48
 49     private int mBorderColor = DEFAULT_BORDER_COLOR;
 50     private int mBorderWidth = DEFAULT_BORDER_WIDTH;
 51
 52     private Bitmap mBitmap;
 53     private BitmapShader mBitmapShader;
 54     private int mBitmapWidth;
 55     private int mBitmapHeight;
 56
 57     private float mDrawableRadius;
 58     private float mBorderRadius;
 59
 60     private boolean mReady;
 61     private boolean mSetupPending;
 62     private final Paint mFlagBackgroundPaint = new Paint();
 63     private final TextPaint mFlagTextPaint = new TextPaint();
 64     private String mFlagText;
 65     private boolean mShowFlag = false;
 66     private Rect mFlagTextBounds = new Rect();
 67
 68     Shader mSweepGradient = null;
 69
 70     public CircleImageView(Context context) {
 71         super(context);
 72
 73         init();
 74     }
 75
 76     public CircleImageView(Context context, AttributeSet attrs) {
 77         this(context, attrs, 0);
 78     }
 79
 80     public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
 81         super(context, attrs, defStyle);
 82
 83         // TypedArray a = context.obtainStyledAttributes(attrs,
 84         // R.styleable.CircleImageView, defStyle, 0);
 85         //
 86         // mBorderWidth =
 87         // a.getDimensionPixelSize(R.styleable.CircleImageView_border_width,
 88         // DEFAULT_BORDER_WIDTH);
 89         // mBorderColor = a.getColor(R.styleable.CircleImageView_border_color,
 90         // DEFAULT_BORDER_COLOR);
 91         //
 92         // a.recycle();
 93
 94         init();
 95     }
 96
 97     private void init() {
 98         super.setScaleType(SCALE_TYPE);
 99         mReady = true;
100
101         if (mSetupPending) {
102             setup();
103             mSetupPending = false;
104         }
105     }
106
107     @Override
108     public ScaleType getScaleType() {
109         return SCALE_TYPE;
110     }
111
112     @Override
113     public void setScaleType(ScaleType scaleType) {
114         if (scaleType != SCALE_TYPE) {
115             throw new IllegalArgumentException(String.format(
116                     "ScaleType %s not supported.", scaleType));
117         }
118     }
119
120     @Override
121     public void setAdjustViewBounds(boolean adjustViewBounds) {
122         if (adjustViewBounds) {
123             throw new IllegalArgumentException(
124                     "adjustViewBounds not supported.");
125         }
126     }
127
128     @SuppressWarnings("deprecation")
129     @Override
130     protected void onDraw(Canvas canvas) {
131         if (getDrawable() == null) {
132             return;
133         }
134
135         canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius,
136                 mBitmapPaint);
137         if (mBorderWidth != 0) {
138             canvas.save();
139             canvas.rotate(20, getWidth() / 2, getHeight() / 2);
140             canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius,
141                     mBorderPaint);
142             canvas.restore();
143         }
144
145         if (mShowFlag && mFlagText != null) {
146             canvas.drawArc(mBorderRect, 40, 100, false, mFlagBackgroundPaint);
147             mFlagTextPaint.getTextBounds(mFlagText, 0, mFlagText.length(),
148                     mFlagTextBounds);
149             canvas.drawText(mFlagText, getWidth() / 2,
150                     (3 + FloatMath.cos((float) (Math.PI * 5 / 18)))
151                             * getHeight() / 4 + mFlagTextBounds.height() / 3,
152                     mFlagTextPaint);
153         }
154
155     }
156
157     @Override
158     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
159         super.onSizeChanged(w, h, oldw, oldh);
160         setup();
161     }
162
163     public int getBorderColor() {
164         return mBorderColor;
165     }
166
167     public void setBorderColor(int borderColor) {
168         if (borderColor == mBorderColor) {
169             return;
170         }
171
172         mBorderColor = borderColor;
173         mBorderPaint.setColor(mBorderColor);
174         invalidate();
175     }
176
177     public int getBorderWidth() {
178         return mBorderWidth;
179     }
180
181     /**
182      * @param borderWidth
183      *            圆形的边框厚度。
184      */
185     public void setBorderWidth(int borderWidth) {
186         if (borderWidth == mBorderWidth) {
187             return;
188         }
189
190         mBorderWidth = borderWidth;
191         setup();
192     }
193
194     @Override
195     public void setImageBitmap(Bitmap bm) {
196         super.setImageBitmap(bm);
197         mBitmap = bm;
198         setup();
199     }
200
201     @Override
202     public void setImageDrawable(Drawable drawable) {
203         super.setImageDrawable(drawable);
204         mBitmap = getBitmapFromDrawable(drawable);
205         setup();
206     }
207
208     @Override
209     public void setImageResource(int resId) {
210         super.setImageResource(resId);
211         mBitmap = getBitmapFromDrawable(getDrawable());
212         setup();
213     }
214
215     @Override
216     public void setImageURI(Uri uri) {
217         super.setImageURI(uri);
218         mBitmap = getBitmapFromDrawable(getDrawable());
219         setup();
220     }
221
222     private Bitmap getBitmapFromDrawable(Drawable drawable) {
223         if (drawable == null) {
224             return null;
225         }
226
227         if (drawable instanceof BitmapDrawable) {
228             return ((BitmapDrawable) drawable).getBitmap();
229         }
230
231         try {
232             Bitmap bitmap;
233
234             if (drawable instanceof ColorDrawable) {
235                 bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION,
236                         COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
237             } else {
238                 bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
239                         drawable.getIntrinsicHeight(), BITMAP_CONFIG);
240             }
241
242             Canvas canvas = new Canvas(bitmap);
243             drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
244             drawable.draw(canvas);
245             return bitmap;
246         } catch (OutOfMemoryError e) {
247             return null;
248         }
249     }
250
251     private void setup() {
252         if (!mReady) {
253             mSetupPending = true;
254             return;
255         }
256
257         if (mBitmap == null) {
258             return;
259         }
260
261         mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP,
262                 Shader.TileMode.CLAMP);
263
264         mBitmapPaint.setAntiAlias(true);
265         mBitmapPaint.setShader(mBitmapShader);
266
267         mBorderPaint.setStyle(Paint.Style.STROKE);
268         mBorderPaint.setAntiAlias(true);
269         mBorderPaint.setColor(mBorderColor);
270         mBorderPaint.setStrokeWidth(mBorderWidth);
271
272         mBitmapHeight = mBitmap.getHeight();
273         mBitmapWidth = mBitmap.getWidth();
274
275         mBorderRect.set(0, 0, getWidth(), getHeight());
276         mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2,
277                 (mBorderRect.width() - mBorderWidth) / 2);
278
279         mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width()
280                 - mBorderWidth, mBorderRect.height() - mBorderWidth);
281         mDrawableRadius = Math.min(mDrawableRect.height() / 2,
282                 mDrawableRect.width() / 2);
283
284         mFlagBackgroundPaint.setColor(Color.BLACK & 0x66FFFFFF);
285         mFlagBackgroundPaint.setFlags(TextPaint.ANTI_ALIAS_FLAG);
286
287         mFlagTextPaint.setFlags(TextPaint.ANTI_ALIAS_FLAG);
288         mFlagTextPaint.setTextAlign(Align.CENTER);
289         mFlagTextPaint.setColor(Color.WHITE);
290         mFlagTextPaint
291                 .setTextSize(getResources().getDisplayMetrics().density * 18);
292
293         mSweepGradient = new SweepGradient(getWidth() / 2, getHeight() / 2,
294                 new int[] { Color.rgb(255, 255, 255), Color.rgb(1, 209, 255) },
295                 null);
296
297         mBorderPaint.setShader(mSweepGradient);
298
299         updateShaderMatrix();
300         invalidate();
301     }
302
303     private void updateShaderMatrix() {
304         float scale;
305         float dx = 0;
306         float dy = 0;
307
308         mShaderMatrix.set(null);
309
310         if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width()
311                 * mBitmapHeight) {
312             scale = mDrawableRect.height() / (float) mBitmapHeight;
313             dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
314         } else {
315             scale = mDrawableRect.width() / (float) mBitmapWidth;
316             dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
317         }
318
319         mShaderMatrix.setScale(scale, scale);
320         mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth,
321                 (int) (dy + 0.5f) + mBorderWidth);
322
323         mBitmapShader.setLocalMatrix(mShaderMatrix);
324     }
325
326     public void setShowFlag(boolean show) {
327         mShowFlag = show;
328         invalidate();
329     }
330
331     public void setFlagText(String text) {
332         mFlagText = text;
333         invalidate();
334     }
335 }

代码如下:

  1 package com.lixu.qqchehua;
  2
  3 import java.util.ArrayList;
  4 import com.baoyz.swipemenulistview.SwipeMenu;
  5 import com.baoyz.swipemenulistview.SwipeMenuCreator;
  6 import com.baoyz.swipemenulistview.SwipeMenuItem;
  7 import com.baoyz.swipemenulistview.SwipeMenuListView;
  8 import com.baoyz.swipemenulistview.SwipeMenuListView.OnMenuItemClickListener;
  9 import android.app.Activity;
 10 import android.content.Context;
 11 import android.graphics.Color;
 12 import android.graphics.drawable.ColorDrawable;
 13 import android.os.Bundle;
 14 import android.view.LayoutInflater;
 15 import android.view.View;
 16 import android.view.ViewGroup;
 17 import android.widget.ArrayAdapter;
 18 import android.widget.ImageView;
 19 import android.widget.TextView;
 20 import android.widget.Toast;
 21
 22 public class MainActivity extends Activity {
 23     private ArrayList<String> data;
 24     private MyAdapter mMyAdapter;
 25
 26     @Override
 27     protected void onCreate(Bundle savedInstanceState) {
 28         super.onCreate(savedInstanceState);
 29         setContentView(R.layout.activity_main);
 30         // 添加文字数据模拟QQ对话
 31         String[] str = { "今天天气不错!", "你好啊,在吗?", "朋友有空出来完。", "走,出去嗨!", "帅哥有空吗?", "来家里玩。", "QQ群有新动态。", "腾讯新闻:伊拉克发动战争!",
 32                 "QQ红包,快来领", "QQ健康", "QQ邮箱" };
 33         data = new ArrayList<String>();
 34
 35         for (String n : str)
 36             data.add(n);
 37         // 创建侧滑提示框
 38         SwipeMenuCreator creator = new SwipeMenuCreator() {
 39
 40             @Override
 41             public void create(SwipeMenu menu) {
 42                 // 设置置顶框
 43                 SwipeMenuItem zhidingitem = new SwipeMenuItem(getApplicationContext());
 44                 zhidingitem.setBackground(new ColorDrawable(Color.GRAY));
 45                 zhidingitem.setWidth(dp2px(90));
 46                 zhidingitem.setTitle("置顶");
 47                 zhidingitem.setTitleSize(15);
 48                 zhidingitem.setTitleColor(Color.WHITE);
 49                 menu.addMenuItem(zhidingitem);
 50                 // 设置删除框
 51                 SwipeMenuItem deleteitem = new SwipeMenuItem(getApplicationContext());
 52                 deleteitem.setBackground(new ColorDrawable(Color.RED));
 53                 deleteitem.setWidth(dp2px(90));
 54                 deleteitem.setTitle("删除");
 55                 deleteitem.setTitleSize(15);
 56                 deleteitem.setTitleColor(Color.WHITE);
 57                 menu.addMenuItem(deleteitem);
 58             }
 59         };
 60         SwipeMenuListView smlv = (SwipeMenuListView) findViewById(R.id.smlv);
 61         // 设置滑动菜单
 62         smlv.setMenuCreator(creator);
 63         // 设置菜单触摸事件
 64         smlv.setOnMenuItemClickListener(new OnMenuItemClickListener() {
 65
 66             @Override
 67             public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
 68                 // int index 这个获取到提示框 int position获取列的下标
 69                 switch (index) {
 70                 case 0:
 71                     // 获取某一列数据后添加到集合头部
 72                     String str = data.get(position);
 73                     data.remove(position);
 74                     data.add(0, str);
 75                     // 刷新适配器
 76                     mMyAdapter.notifyDataSetChanged();
 77                     Toast.makeText(getApplicationContext(), "置顶成功!", 0).show();
 78                     break;
 79                 case 1:
 80                     // 删除某一列数据
 81                     data.remove(position);
 82                     // 刷新适配器
 83                     mMyAdapter.notifyDataSetChanged();
 84                     Toast.makeText(getApplicationContext(), "删除成功!", 0).show();
 85                     break;
 86
 87                 default:
 88                     break;
 89                 }
 90                 return false;
 91             }
 92         });
 93
 94         mMyAdapter = new MyAdapter(this, -1);
 95         smlv.setAdapter(mMyAdapter);
 96     }
 97
 98     private class MyAdapter extends ArrayAdapter {
 99         LayoutInflater flater;
100
101         public MyAdapter(Context context, int resource) {
102             super(context, resource);
103             flater = LayoutInflater.from(context);
104         }
105
106         @Override
107         public int getCount() {
108             return data.size();
109         }
110
111         @Override
112         public View getView(int position, View convertView, ViewGroup parent) {
113             if (convertView == null)
114                 convertView = flater.inflate(R.layout.list, null);
115
116             ImageView iv = (ImageView) convertView.findViewById(R.id.iv);
117             iv.setImageResource(R.drawable.qqq);
118
119             TextView tv = (TextView) convertView.findViewById(R.id.tv);
120             tv.setText(data.get(position));
121             return convertView;
122         }
123
124     }
125
126     public int dp2px(float dipValue) {
127         final float scale = this.getResources().getDisplayMetrics().density;
128         return (int) (dipValue * scale + 0.5f);
129     }
130
131 }

xml文件:

 1 <LinearLayout 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     android:orientation="vertical" >
 6
 7     <com.baoyz.swipemenulistview.SwipeMenuListView
 8         android:id="@+id/smlv"
 9         android:layout_width="match_parent"
10         android:layout_height="match_parent" />
11
12 </LinearLayout>

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="horizontal"
 6     android:padding="10dp">
 7
 8     <com.lixu.qqchehua.CircleImageView
 9         android:id="@+id/iv"
10         android:layout_width="50dp"
11         android:layout_height="50dp" />
12
13     <TextView
14         android:id="@+id/tv"
15         android:layout_width="wrap_content"
16         android:layout_height="wrap_content" />
17
18 </LinearLayout>

运行效果图:

转载于:https://www.cnblogs.com/labixiaoxin/p/4995497.html

Android的SwipeToDismiss第三方开源框架模拟QQ对话列表侧滑删除,置顶,将头像图片圆形化处理。...相关推荐

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

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

  2. 仿QQ对话列表滑动删除与置顶的原理及实现

    接下来,我们将完成QQ聊天界面的ListView滑动效果,大家可能都用过ListView,知道ListView是上下滑动的,并不会产生左右滑动的效果,如果想让ListView变成左右滑动的效果,必须对 ...

  3. OS开发-常用第三方开源框架介绍

    为什么80%的码农都做不了架构师?>>>    OS开发-常用第三方开源框架介绍 http://blog.csdn.net/meiwenjie110/article/details/ ...

  4. iOS开发 常用第三方开源框架

    iOS开发-常用第三方开源框架介绍(你了解的ios只是冰山一角) 2015-04-05 15:25 2482人阅读 评论(1) 收藏 举报 开源框架 图像: 1.图片浏览控件MWPhotoBrowse ...

  5. IOS-常用第三方开源框架介绍

    iOS开发-常用第三方开源框架介绍(你了解的ios只是冰山一角) 时间:2015-05-06 16:43:34      阅读:533      评论:0      收藏:0      [点我收藏+] ...

  6. iOS开发常用第三方开源框架

    iOS开发-常用第三方开源框架倾情整理!简书:https://www.jianshu.com/p/29cb22b13d79 iOS第三方库大全:https://blog.csdn.net/kanggu ...

  7. Android APK的主流开源框架

    主流开源框架 View框架 1.ButterKnife 2.ViewBinding 图片框架 1.Glide 快速高效的Android图片加载库,注重于平滑的滚动 2.Picasso Square 开 ...

  8. qq好友列表获取数据并导出 - 用curl类 模拟QQ好友列表获取

    qq好友列表获取数据并导出 - 用cur类l 模拟QQ好友列表获取 这里我们利用curl类去实现这个功能. 代码如下: //模拟浏览器查找好友列表 $url = "http://cgi.fi ...

  9. Android 编程下代码之(QQ消息列表滑动删除)

       这份代码写出来有些时候了,一直没共享,现在把它共享给大家.简单列一下代码中你可以学到的知识点: 自定义控件的实现方式: 事件的拦截分发消费机制: QQ会话列表滑动删除原理: 最后附上源码链接:Q ...

最新文章

  1. 重装华为服务器系统软件,服务器系统重装软件
  2. srm 593 dv2 1000pt
  3. html中小于和大于怎么判断,html – CSS nth-child大于和小于
  4. 数据库查找出list数据,进行处理
  5. SAP Netweaver EACTT介绍
  6. 定时器_Qt定时器小坑
  7. 使用新的 apt 命令在 Ubuntu 16.04 LTS 下管理软件包
  8. 在word中添加内容控件,报错未实现该方法或操作
  9. (MathType)公式编号(1)和(2a)(2b)混编
  10. 机场三字代码和四字代码的资料汇编
  11. 【python 保存生成的图片 (plt;opencv;PIL)】
  12. 8.docker run --rm
  13. 怎么彻底关闭UAC(user account control)?
  14. 移动安全-IOS逆向第三天——实战HOOK RSA/DES加密
  15. 计算机网络——CSMA协议
  16. 删除linux系统 mbr,Windows 10 下安全删除 Linux 系统
  17. 什么是个人热点?安卓手机怎么开启个人热点?
  18. txt文档在html中乱码怎么办,txt文件打开显示乱码怎么办?
  19. MATLAB算法实战应用案例精讲-【深度学习】扩散模型(DM)(附python代码实现)
  20. 知识蒸馏(Distillation)

热门文章

  1. 让不能上网的机器借能上网的机器上网
  2. Nginx玩法 — 反向代理
  3. python制作中秋贺卡_使用Python为中秋节绘制一块美味的月饼
  4. 行业分析| 为什么uni-app在音视频领域这么火?
  5. 过一遍HTML标签(三)
  6. Flutter页面布局:Wrap组件
  7. 人类历史上首次,完全无人的谷歌无人车上路了!
  8. 计算机网络RSI,严为民:干货!RSI主升浪选择法的实战案例(下篇)
  9. 计算机概述.ppt,一计算机概述.ppt
  10. Python改变图片EXIF信息(修复图片上传后方向改变的BUG)