你的位置:首页 > 操作系统

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



 

《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     @Override107     public int getCount() {108       return data.size();109     }110 111     @Override112     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 }

 1 <LinearLayout ="http://schemas.android.com/apk/res/android" 2   ="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 <??> 2 <LinearLayout ="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   <TextView14     android:id="@+id/tv"15     android:layout_width="wrap_content"16     android:layout_height="wrap_content" />17 18 </LinearLayout>


运行效果图: