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

时间:2022-09-15 22:12:17

 

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

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

下载地址:点此下载

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

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

将图片圆形化处理的类: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>


运行效果图:

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