Android实现动态圆环的图片头像控件

Android实现动态圆环的图片头像控件,第1张

概述先看效果图:现在大部分的app上难免会使用到圆形头像,所以今天我给大家分享一个单独使用的,并且周围带有圆环动画的花哨圆形头像控件,本控件是在圆形头像控件基础上实现的,只是在其周围再画一些不同大小的圆而已

先看效果图:

现在大部分的app上难免会使用到圆形头像,所以今天我给大家分享一个单独使用的,并且周围带有圆环动画的花哨圆形头像控件,本控件是在圆形头像控件基础上实现的,只是在其周围再画一些不同大小的圆而已,就可以实现如图的效果。

圆形头像的基本原理是将设置的资源文件转化成Bitmap,然后通过BitmapShader类将Bitmap成为Paint的渲染器,然后在onDraw()中通过canvas.drawCircle(rx,ry,radius,paint);画布上画圆,而这个圆就是形成了圆形头像。

在xml中通过src设置的资源文件在ImageVIEw的setimageDrawable(drawable)方法中可以得到Drawable类型的图像,然后再将Drawable转成Bitmap就可以了

public voID setimageDrawable(Drawable drawable) {   super.setimageDrawable(drawable);   mBitmap = getBitmapFromDrawable(drawable);   setup(); } private Bitmap getBitmapFromDrawable(Drawable drawable) {    if (drawable == null) {    return null;   }    if (drawable instanceof BitmapDrawable) {    //从bitmap中间裁剪出最大的正方形    Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();    return getMaxSquareCenter(bitmap);    //return ((BitmapDrawable) drawable).getBitmap();   }    try {    Bitmap bitmap;     if (drawable instanceof colorDrawable) {     bitmap = Bitmap.createBitmap(colorDRAWABLE_DIMENSION,colorDRAWABLE_DIMENSION,BITMAP_CONfig);    } else {     int min = Math.min(drawable.getIntrinsicWIDth(),drawable.getIntrinsicHeight());     bitmap = Bitmap.createBitmap(min,min,BITMAP_CONfig);    }     Canvas canvas = new Canvas(bitmap);    int left,top,right,buttom;    int wIDth = canvas.getWIDth();    int height = canvas.getHeight();    int abs = Math.abs(wIDth - height);    if(wIDth <= height){     left = 0;     top = (height - abs) / 2;     right = wIDth;     buttom = height - top;    }else{     left = (wIDth - abs) / 2;     top = 0;     right = wIDth - left;     buttom = height;    }    //drawable.setBounds(0,canvas.getWIDth(),canvas.getHeight());    drawable.setBounds(left,buttom);    drawable.draw(canvas);    return bitmap;   } catch (OutOfMemoryError e) {    return null;   }  } /**   * 从bitmap中间裁剪出最大的正方形   * @param bitmap   * @return   */  private Bitmap getMaxSquareCenter(Bitmap bitmap){   int w = bitmap.getWIDth(); // 得到图片的宽,高   int h = bitmap.getHeight();   int cropWIDth = w >= h ? h : w;// 裁切后所取的正方形区域边长   return Bitmap.createBitmap(bitmap,(w - cropWIDth)/2,(h - cropWIDth)/2,cropWIDth,null,false);  } 

获取到Bitmap对象后就可以将Bitmap缩小一倍后,在将其画在画布上,这样就有地方来画周围的圆环了。

private voID updateShaderMatrix() {   float scale;   float dx = 0;   float dy = 0;    mShaderMatrix.set(null);    if (mBitmapWIDth * mDrawableRect.height() > mDrawableRect.wIDth() * mBitmapHeight) {    scale = mDrawableRect.height() / (float) mBitmapHeight / 2; //将图片缩放在正中间 缩小一倍    dx = (mDrawableRect.wIDth() - mBitmapWIDth * scale) * 0.5f;   } else {    scale = mDrawableRect.wIDth() / (float) mBitmapWIDth / 2; //将图片缩放在正中间 缩小一倍    dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;   }    mShaderMatrix.setScale(scale,scale );  //在x轴上平移mDrawableRadius,就在正中间了   mShaderMatrix.postTranslate((int) (dx + 0.5f) + mborderWIDth + mDrawableRadius,(int) (dy + 0.5f) + mborderWIDth);    mBitmapShader.setLocalMatrix(mShaderMatrix);  } 

下面就是画图片周围的圆环了,就是在图片的外围画两个圆,一个半径大点,颜色浅点,一个半径小点,颜色深点就可以了,然后通过Handler通过延时 *** 作,不断的改变两个圆的半径大小和颜色的深浅,重绘就可以了

 private float mChangeRateborder;//记录外圆执行动画时半径变化率  private float mChangeRateOuter;//记录内圆执行动画时半径变化率  private float mChangeRateInner;//记录图片边框执行动画时半径变化率  private float mChangeRange;//变化范围,VIEw半径的1/6 //*******执行动画*******//  //外圆执行动画时半径变化率  private float mRateOuter[] = {    -1,-1,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f,0.92f,0.88f,0.85f,0.82f,0.76f,0.72f,0.68f,0.60f,0.54f,0.48f,0.40f,0.33f,0.28f,0.20f};  //内圆执行动画时半径变化率  private float mRateInner[] = {    -1,0.84f,0.80f,0.67f,-1f,-1f};  //图片边框执行动画时半径变化率  private float mRateborder[] = {    0,0.90f,0.78f,0.64f,0.58f,-1f};   private int mRateIndex;//动画变化率的索引 

Handler不断改变半径的变化率和画笔的颜色

/**   * 按住执行动画   */  private Handler mHandler = new Handler(){   @OverrIDe   public voID handleMessage(Message msg) {    super.handleMessage(msg);    int index = mRateIndex ++;    mChangeRateborder = mRateborder[(index)% mRateborder.length];    setPaintCorlor(mborderPaint,mChangeRateborder,DEFAulT_border_color);    setPaintAlpha(mborderPaint,(index)% mRateborder.length,mRateborder);    mChangeRateOuter = mRateOuter[(index) % mRateOuter.length];    setPaintCorlor(mOuterPaint,mChangeRateOuter,mOuterPaintcolor);    setPaintAlpha(mOuterPaint,(index) % mRateOuter.length,mRateOuter);    mChangeRateInner = mRateInner[(index) % mRateInner.length];    setPaintCorlor(mInnerPaint,mChangeRateInner,mInnerPaintcolor);    setPaintAlpha(mInnerPaint,(index) % mRateInner.length,mRateInner);     //System.out.println("---------mChangeRate:"+mChangeRateborder);    invalIDate();    mHandler.removeCallbacksAndMessages(null);    mHandler.sendEmptyMessageDelayed(0,30);   }  }; 

每执行一次handleMessage()就会触发(invalIDate())VIEw重绘,onDraw中不断的重绘,只需改变每个Circle的半径即可

@OverrIDe  protected voID onDraw(Canvas canvas) {    if (getDrawable() == null) {    return;   }    //画动画的图形   canvas.drawCircle(getWIDth() / 2,getHeight() / 2,getChangeRadiusOuter(mOuterRadius),mOuterPaint);   canvas.drawCircle(getWIDth() / 2,getChangeRadiusInner(mInnerRadius),mInnerPaint);    canvas.drawCircle(getWIDth() / 2,mDrawableRadius,mBitmapPaint);   canvas.drawCircle(getWIDth() / 2,getChangeRadiusborder(mborderRadius),mborderPaint);  } 

根据Handler中给的变化率来计算每个Circle的半径

private float getChangeRadiusborder(float radius){    return mChangeRateborder * mChangeRange + radius;   }  private float getChangeRadiusOuter(float radius){    return mChangeRateOuter * mChangeRange + radius;   }  private float getChangeRadiusInner(float radius){    return mChangeRateInner * mChangeRange + radius;   } 

这样在不断的向Handler发送消息时,也就会不断的触发重绘,不断改变外围圆的大小,形成上图所见的动画效果
如下四个方法,就是来控制圆环所展示的不同状态

/**   * 开始动画   */  public voID startAnim(){  //让外围的圆环动起来   mHandler.sendEmptyMessageDelayed(0,30);   }  /**   * 停止动画   */  public voID stopAnim(){  //停止外圆环的动画,展示默认的大小   mHandler.removeCallbacksAndMessages(null);   mChangeRateborder = 0;   mChangeRateOuter = 0;   mChangeRateInner = 0;    initAnimcolor();    enteranim();  }  /**   * 进入动画   */  public voID enteranim(){  //展示外圆环,显示默认大小   mHandlerEnter.sendEmptyMessage(0);  }   /**   * 退出动画   */  public voID exitAnim(){  //隐藏外圆环   mHandlerExit.sendEmptyMessage(0);  } 

好了,动态头像到这基本就实现了,进入动画和退出动画的代码就不贴出来分析了,如果发现BUG或者有任何意见欢迎留言。

完整源码 

import androID.content.Context; import androID.graphics.Bitmap; import androID.graphics.BitmapShader; import androID.graphics.Canvas; import androID.graphics.color; import androID.graphics.Matrix; import androID.graphics.Paint; import androID.graphics.RectF; import androID.graphics.Shader; import androID.graphics.drawable.BitmapDrawable; import androID.graphics.drawable.colorDrawable; import androID.graphics.drawable.Drawable; import androID.os.Handler; import androID.os.Message; import androID.util.AttributeSet; import androID.Widget.ImageVIEw;  /**  * Created by cj_28 on 2016/10/15.  */ public class DynamicAvatarVIEw extends ImageVIEw {   private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;   private static final int colorDRAWABLE_DIMENSION = 1;  private static final Bitmap.Config BITMAP_CONfig = Bitmap.Config.ARGB_8888;   private Bitmap mBitmap;  private BitmapShader mBitmapShader;   private final Matrix mShaderMatrix = new Matrix();  private final Paint mBitmapPaint = new Paint();  private final Paint mborderPaint = new Paint();  private final Paint mOuterPaint = new Paint();  private final Paint mInnerPaint = new Paint();   private static final int DEFAulT_border_WIDTH = 3;  private static final int DEFAulT_border_color = color.WHITE;  private static final int OUTER_PAINT_color = color.parsecolor("#55FFFFFF");  private static final int INNER_PAINT_color = color.parsecolor("#66FFFFFF");   private int mbordercolor = DEFAulT_border_color;  private int mborderWIDth = DEFAulT_border_WIDTH;   private int mOuterPaintcolor = OUTER_PAINT_color;  private int mInnerPaintcolor = INNER_PAINT_color;   private int mBitmapWIDth;  private int mBitmapHeight;   private final RectF mDrawableRect = new RectF();  private final RectF mborderRect = new RectF();   private float mDrawableRadius;//显示的图片  private float mborderRadius;//..//显示的图片上的边框  private float mOuterRadius;//外层动画  private float mInnerRadius;//..//内层动画   private float mRealDrawableRadius;//这是VIEw没有被缩放之前的mDrawableRadius的半径  private float mRealborderRadius;//..   private boolean mReady;  private boolean mSetupPending;   private float mChangeRateborder;//记录外圆执行动画时半径变化率  private float mChangeRateOuter;//记录内圆执行动画时半径变化率  private float mChangeRateInner;//记录图片边框执行动画时半径变化率  private float mChangeRange;//变化范围,VIEw半径的1/6   //*******执行动画*******//  //外圆执行动画时半径变化率  private float mRateOuter[] = {    -1,-1f};   //private int mcolor[] = {0x55FFFFFF,0x44FFFFFF,0x33FFFFFF,0x22FFFFFF,0x11FFFFFF,0x00FFFFFF,0x00FFFFFF};  private int mRateIndex;//动画变化率的索引   //*******进入动画*******//  //外圆执行动画时半径变化率  private float mRateOuterEnter[] = {    -2,-2,//外圆要缩小2个mChangeRange才会完全隐藏    -2,-0.8f,-0.6f,-0.4f,-0.2f,-0.1f,0.44f,0.35f,0.25f,0.20f,0.15f,0.0f};  //内圆执行动画时半径变化率  private float mRateInnerEnter[] = {    -1,//外圆要缩小1个mChangeRange才会完全隐藏    -0.8f,0.45f,0.05f,0f,0f};  private int mRateIndexEnter;//进入动画变化率的索引   //*******退出动画*******//  //外圆执行动画时半径变化率  private float mRateOuterExit[] = {     0.0f,-1.2f,-1.4f,-1.6f,-1.8f,-2f};  //内圆执行动画时半径变化率  private float mRateInnerExit[] = {     0.0f,-0.3f,-0.5f,-0.7f,-0.9f,-1f};  private int mRateIndexExit;//进入动画变化率的索引    /**   * 按住执行动画   */  private Handler mHandler = new Handler(){   @OverrIDe   public voID handleMessage(Message msg) {    super.handleMessage(msg);    int index = mRateIndex ++;    mChangeRateborder = mRateborder[(index)% mRateborder.length];    setPaintCorlor(mborderPaint,30);   }  };   private Handler mHandlerEnter = new Handler(){   @OverrIDe   public voID handleMessage(Message msg) {    super.handleMessage(msg);    int index = mRateIndexEnter ++;    if(index >= mRateOuterEnter.length) {     mRateIndexEnter = 0;     mHandlerEnter.removeCallbacksAndMessages(null);     return;    }     mChangeRateOuter = mRateOuterEnter[(index) % mRateOuterEnter.length];     mChangeRateInner = mRateInnerEnter[(index) % mRateInnerEnter.length];     invalIDate();    mHandlerEnter.removeCallbacksAndMessages(null);    mHandlerEnter.sendEmptyMessageDelayed(0,20);   }  };   private Handler mHandlerExit = new Handler(){   @OverrIDe   public voID handleMessage(Message msg) {    super.handleMessage(msg);    int index = mRateIndexExit ++;    if(index >= mRateOuterExit.length) {     mRateIndexExit = 0;     mHandlerExit.removeCallbacksAndMessages(null);     return;    }     mChangeRateOuter = mRateOuterExit[(index) % mRateOuterExit.length];     mChangeRateInner = mRateInnerExit[(index) % mRateInnerExit.length];     invalIDate();    mHandlerExit.removeCallbacksAndMessages(null);    mHandlerExit.sendEmptyMessageDelayed(0,20);   }  };   /**   * 设置outer和inner的画笔颜色   * @param paint   * @param rate   * @param color   */  private voID setPaintCorlor(Paint paint,float rate,int color){   if(rate < 0){    paint.setcolor(color.transparent);   }else{    paint.setcolor(color);   }  }   /**   * 设置透明度   * @param paint   * @param index   * @param rate   */  private voID setPaintAlpha(Paint paint,int index,float[] rate){   int pre = index -1;   if(pre >= 0 ){    if(rate[pre] > rate[index] && rate[index] > 0){     int color = paint.getcolor();      int colortransparent = color & 0xff000000;     int colorValue = color & 0x00ffffff;     colortransparent = colortransparent >>> 7;     paint.setcolor((int)(rate[index] * colortransparent) << 7 | colorValue);     }   }  }   public DynamicAvatarVIEw(Context context) {   this(context,null);  }   public DynamicAvatarVIEw(Context context,AttributeSet attrs) {   this(context,attrs,0);   }   public DynamicAvatarVIEw(Context context,AttributeSet attrs,int defStyleAttr) {   super(context,defStyleAttr);   super.setScaleType(SCALE_TYPE);    //可以执行了   mReady = true;    if (mSetupPending) {    setup();    mSetupPending = false;   }  }   @OverrIDe  protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) {    int wIDthMode = MeasureSpec.getMode(wIDthMeasureSpec);   int wIDthSize = MeasureSpec.getSize(wIDthMeasureSpec);   int heightmode = MeasureSpec.getMode(heightmeasureSpec);   int heightSize = MeasureSpec.getSize(heightmeasureSpec);    int size = Math.min(wIDthSize,heightSize);    super.onMeasure(MeasureSpec.makeMeasureSpec(size,wIDthMode),MeasureSpec.makeMeasureSpec(size,heightmode));  }   @OverrIDe  protected voID onLayout(boolean changed,int left,int top,int right,int bottom) {    super.onLayout(changed,left,bottom);   enteranim();  }   @OverrIDe  protected voID onDraw(Canvas canvas) {    if (getDrawable() == null) {    return;   }    //画动画的图形   canvas.drawCircle(getWIDth() / 2,mborderPaint);  }   private float getChangeRadiusborder(float radius){    return mChangeRateborder * mChangeRange + radius;   }  private float getChangeRadiusOuter(float radius){    return mChangeRateOuter * mChangeRange + radius;   }  private float getChangeRadiusInner(float radius){    return mChangeRateInner * mChangeRange + radius;   }   private voID initAnimcolor(){   mOuterPaint.setStyle(Paint.Style.FILL);   mOuterPaint.setAntiAlias(true);   mOuterPaint.setcolor(mOuterPaintcolor);   mInnerPaint.setStyle(Paint.Style.FILL);   mInnerPaint.setAntiAlias(true);   mInnerPaint.setcolor(mInnerPaintcolor);   //图片边框(默认白色)   mborderPaint.setcolor(mbordercolor);    mOuterRadius = mRealborderRadius / 6 * 5;   mInnerRadius = mRealborderRadius / 6 * 4;   mChangeRange = mRealborderRadius / 6;   mRateIndex = 0;  }   /**   * 开始动画   */  public voID startAnim(){   mHandler.sendEmptyMessageDelayed(0,30);   }  /**   * 停止动画   */  public voID stopAnim(){   mHandler.removeCallbacksAndMessages(null);   mChangeRateborder = 0;   mChangeRateOuter = 0;   mChangeRateInner = 0; //  mborderPaint.setcolor(DEFAulT_border_color); //  mOuterPaint.setcolor(mOuterPaintcolor); //  mInnerPaint.setcolor(mInnerPaintcolor); //  mRateIndex = 0;   initAnimcolor();    //invalIDate();   enteranim();  }  /**   * 进入动画   */  public voID enteranim(){   mHandlerEnter.sendEmptyMessage(0);  }   /**   * 退出动画   */  public voID exitAnim(){   mHandlerExit.sendEmptyMessage(0);  }   /**   * 设置外圆动画的颜色   * @param outerPaintcolor   */  public voID setouterPaintcolor(int outerPaintcolor) {   if (outerPaintcolor == mOuterPaintcolor) {    return;   }   mOuterPaintcolor = outerPaintcolor;   mOuterPaint.setcolor(mOuterPaintcolor);   invalIDate();  }   /**   * 设置内圆动画的颜色   * @param innerPaintcolor   */  public voID setInnerPaintcolor(int innerPaintcolor) {   if (innerPaintcolor == mInnerPaintcolor) {    return;   }   mInnerPaintcolor = innerPaintcolor;   mInnerPaint.setcolor(mInnerPaintcolor);   invalIDate();  }   /**   * 设置图片边框的颜色   * @param bordercolor   */  public voID setbordercolor(int bordercolor) {   if (bordercolor == mbordercolor) {    return;   }    mbordercolor = bordercolor;   mborderPaint.setcolor(mbordercolor);   invalIDate();  }   /**   * 设置图片边框的宽度   * @param borderWIDth   */  public voID setborderWIDth(int borderWIDth) {   if (borderWIDth == mborderWIDth) {    return;   }    mborderWIDth = borderWIDth;   setup();  }   @OverrIDe  public ScaleType getScaleType() {   return SCALE_TYPE;  }   @OverrIDe  public voID setScaleType(ScaleType scaleType) {   if (scaleType != SCALE_TYPE) {    throw new IllegalArgumentException(String.format("ScaleType %s not supported.",scaleType));   }  }   @OverrIDe  protected voID onSizeChanged(int w,int h,int olDW,int oldh) {   super.onSizeChanged(w,h,olDW,oldh);   //只有在此方法中调用setup,setup中的getWIDth方法得到的值才不会是0,   setup();  }   @OverrIDe  public voID setimageBitmap(Bitmap bm) {   super.setimageBitmap(bm);   mBitmap = getMaxSquareCenter(bm);   setup();  }   /**   * mxl中设置src就会走此方法   * @param drawable   */  @OverrIDe  public voID setimageDrawable(Drawable drawable) {   super.setimageDrawable(drawable);   mBitmap = getBitmapFromDrawable(drawable);   setup();  }   @OverrIDe  public voID setimageResource(int resID) {   super.setimageResource(resID);   mBitmap = getBitmapFromDrawable(getDrawable());   setup();  }   /**   * 从bitmap中间裁剪出最大的正方形   * @param bitmap   * @return   */  private Bitmap getMaxSquareCenter(Bitmap bitmap){   int w = bitmap.getWIDth(); // 得到图片的宽,高   int h = bitmap.getHeight();   int cropWIDth = w >= h ? h : w;// 裁切后所取的正方形区域边长   return Bitmap.createBitmap(bitmap,false);  }   private Bitmap getBitmapFromDrawable(Drawable drawable) {    if (drawable == null) {    return null;   }    if (drawable instanceof BitmapDrawable) {    //从bitmap中间裁剪出最大的正方形    Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();    return getMaxSquareCenter(bitmap);    //return ((BitmapDrawable) drawable).getBitmap();   }    try {    Bitmap bitmap;     if (drawable instanceof colorDrawable) {     bitmap = Bitmap.createBitmap(colorDRAWABLE_DIMENSION,buttom);    drawable.draw(canvas);    return bitmap;   } catch (OutOfMemoryError e) {    return null;   }  }   private voID setup() {   //只有执行过构造函数之后,所有的成员才被初始化完毕   if (!mReady) {    mSetupPending = true;    return;   }    if (mBitmap == null) {    return;   }    mBitmapShader = new BitmapShader(mBitmap,Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);    mBitmapPaint.setAntiAlias(true);   mBitmapPaint.setShader(mBitmapShader);    mborderPaint.setStyle(Paint.Style.stroke);   mborderPaint.setAntiAlias(true);   mborderPaint.setcolor(mbordercolor);   mborderPaint.setstrokeWIDth(mborderWIDth);    mBitmapHeight = mBitmap.getHeight();   mBitmapWIDth = mBitmap.getWIDth();   //图片边框设置的范围   mborderRect.set(0,getWIDth(),getHeight());   mborderRadius = Math.min((mborderRect.height() - mborderWIDth) / 2,(mborderRect.wIDth() - mborderWIDth) / 2) / 2;   mRealborderRadius = 2 * mborderRadius;   //图片显示的范围   mDrawableRect.set(mborderWIDth,mborderWIDth,mborderRect.wIDth() - mborderWIDth,mborderRect.height() - mborderWIDth);   //让图片显示的范围是控件大小的一半   mDrawableRadius = Math.min(mDrawableRect.height() / 2,mDrawableRect.wIDth() / 2) / 2;   mRealDrawableRadius = 2 * mDrawableRadius;    updateShaderMatrix();   initAnimcolor();   invalIDate();  }   private voID updateShaderMatrix() {   float scale;   float dx = 0;   float dy = 0;    mShaderMatrix.set(null);    if (mBitmapWIDth * mDrawableRect.height() > mDrawableRect.wIDth() * mBitmapHeight) {    scale = mDrawableRect.height() / (float) mBitmapHeight / 2; //将图片缩放在正中间    dx = (mDrawableRect.wIDth() - mBitmapWIDth * scale) * 0.5f;   } else {    scale = mDrawableRect.wIDth() / (float) mBitmapWIDth / 2;    dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;   }    mShaderMatrix.setScale(scale,scale );   mShaderMatrix.postTranslate((int) (dx + 0.5f) + mborderWIDth + mDrawableRadius,(int) (dy + 0.5f) + mborderWIDth);    mBitmapShader.setLocalMatrix(mShaderMatrix);  }  } 

参考:https://github.com/hdodenhof/CircleImageView

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android实现动态圆环的图片头像控件全部内容,希望文章能够帮你解决Android实现动态圆环的图片头像控件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147807.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存