Android自定义View实现点赞控件

Android自定义View实现点赞控件,第1张

概述Android自定义View实现点赞控件 本文实例为大家分享了Android点赞控件的具体代码,供大家参考,具体内容如下 预览效果 目录 图片类:LikeImageView 文字类:LikeCharTextView 整合类:LikeView.java 自定义属性:attrs.xml 代码 LikeCharTextView public class LikeCharTextView extends View { public static final int DEFAULT_TEXTCOLOR = Color.BLACK; public

本文实例为大家分享了AndroID点赞控件的具体代码,供大家参考,具体内容如下

预览效果


目录

图片类:likeImageVIEw
文字类:likeCharTextVIEw
整合类:likeVIEw.java
自定义属性:attrs.xml

代码

likeCharTextVIEw

public class likeCharTextVIEw extends VIEw { public static final int DEFAulT_TEXTcolor = color.BLACK; public static final int DEFAulT_TEXTSIZE = 36; private TextPaint newTextPaint,oldTextPaint; private AnimatorSet addAnimator; private AnimatorSet minusAnimator; private int  measureWIDth; private int  measureHeight; private int  textcolor  = DEFAulT_TEXTcolor; private int  textSize  = DEFAulT_TEXTSIZE; private int  num; private int  oldNum; private int  newNum; private int  animatoroldY; private float  animatoroldAlpha = 1; private int  animatorNewY; private float  animatorNewAlpha = 0; private int  baseline; public likeCharTextVIEw(Context context) { super(context); init(); } public likeCharTextVIEw(Context context,@Nullable AttributeSet attrs) { super(context,attrs); initAttr(context,attrs); init(); } public likeCharTextVIEw(Context context,@Nullable AttributeSet attrs,int defStyleAttr) { super(context,attrs,defStyleAttr); initAttr(context,attrs); init(); } /** * 初始化属性 * * @param context * @param attrs */ private voID initAttr(Context context,@Nullable AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.likeCharTextVIEw); textcolor = typedArray.getcolor(R.styleable.likeCharTextVIEw_textcolor,DEFAulT_TEXTcolor); textSize = typedArray.getDimensionPixelSize(R.styleable.likeCharTextVIEw_textSize,DEFAulT_TEXTSIZE); num = typedArray.getInt(R.styleable.likeCharTextVIEw_number,0); if (0 > num || num > 10) {  throw new IllegalArgumentException("Number is only 0-9"); } oldNum = num; typedArray.recycle(); } /** * 初始化 */ private voID init() { initPaints(); initParams(); } /** * 初始化画笔 */ private voID initPaints() { newTextPaint = new TextPaint(Paint.ANTI_AliAS_FLAG); newTextPaint.setStyle(Paint.Style.FILL); newTextPaint.setTextSize(textSize); newTextPaint.setcolor(textcolor); newTextPaint.setTextAlign(Paint.Align.CENTER); oldTextPaint = new TextPaint(Paint.ANTI_AliAS_FLAG); oldTextPaint.set(newTextPaint); } /** * 初始化参数 */ private voID initParams() { Paint.FontMetrics FontMetrics = newTextPaint.getFontMetrics(); measureWIDth = (int) newTextPaint.measureText(String.valueOf(num)); measureHeight = (int) (FontMetrics.bottom - FontMetrics.top); float distance = (FontMetrics.bottom - FontMetrics.top) / 2 - FontMetrics.bottom; baseline = (int) (measureHeight * 1.0f / 2 + distance); animatoroldY = baseline; } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { super.onMeasure(wIDthMeasureSpec,heightmeasureSpec); int wIDthMode = MeasureSpec.getMode(wIDthMeasureSpec); int wIDthSize = MeasureSpec.getSize(wIDthMeasureSpec); switch (wIDthMode) {  case MeasureSpec.UnspecIFIED:  break;  case MeasureSpec.AT_MOST:  wIDthSize = measureWIDth;  break;  case MeasureSpec.EXACTLY:  break; } int heightmode = MeasureSpec.getMode(wIDthMeasureSpec); int heightSize = MeasureSpec.getSize(wIDthMeasureSpec); switch (heightmode) {  case MeasureSpec.UnspecIFIED:  break;  case MeasureSpec.AT_MOST:  heightSize = measureHeight;  break;  case MeasureSpec.EXACTLY:  break; } setMeasuredDimension(wIDthSize,heightSize); } @OverrIDe protected voID onDraw(Canvas canvas) { super.onDraw(canvas); int wIDth = getWIDth(); int height = getHeight(); oldTextPaint.setAlpha((int) (255 * animatoroldAlpha)); canvas.drawText(String.valueOf(oldNum),wIDth / 2,animatoroldY,oldTextPaint); newTextPaint.setAlpha((int) (255 * animatorNewAlpha)); canvas.drawText(String.valueOf(newNum),animatorNewY,newTextPaint); } public voID setTextcolor(int textcolor) { this.textcolor = textcolor; init(); invalIDate(); } public voID setTextSize(int textSize) { this.textSize = textSize; init(); invalIDate(); } public voID setAnimatoroldY(int animatoroldY) { this.animatoroldY = animatoroldY; invalIDate(); } public voID setAnimatoroldAlpha(float animatoroldAlpha) { this.animatoroldAlpha = animatoroldAlpha; invalIDate(); } public voID setAnimatorNewY(int animatorNewY) { this.animatorNewY = animatorNewY; invalIDate(); } public voID setAnimatorNewAlpha(float animatorNewAlpha) { this.animatorNewAlpha = animatorNewAlpha; invalIDate(); } public voID setNum(int num) { this.num = num; if (0 > num || num > 10) {  throw new IllegalArgumentException("Number is only 0-9"); } oldNum = num; invalIDate(); } public voID add() { Logger.e("执行加动画.基线:" + baseline); ObjectAnimator oldYAnimator = ObjectAnimator.ofInt(this,"animatoroldY",baseline,0); ObjectAnimator oldAlphaAnimator = ObjectAnimator.offloat(this,"animatoroldAlpha",1,0); ObjectAnimator newYAnimator = ObjectAnimator.ofInt(this,"animatorNewY",baseline * 2,baseline); ObjectAnimator newAlphaAnimator = ObjectAnimator.offloat(this,"animatorNewAlpha",1); addAnimator = new AnimatorSet(); addAnimator.playTogether(oldYAnimator,oldAlphaAnimator,newYAnimator,newAlphaAnimator); addAnimator.setInterpolator(new linearInterpolator()); addAnimator.setDuration(300); addAnimator.start(); } public voID minus() { Logger.e("执行减动画.基线:" + baseline); ObjectAnimator oldYAnimator = ObjectAnimator.ofInt(this,baseline * 2); ObjectAnimator oldAlphaAnimator = ObjectAnimator.offloat(this,1); minusAnimator = new AnimatorSet(); minusAnimator.playTogether(oldYAnimator,newAlphaAnimator); minusAnimator.setInterpolator(new linearInterpolator()); minusAnimator.setDuration(300); minusAnimator.start(); } public voID change(boolean isAdd) { Logger.e("charTextVIE.点击事件:" + isAdd); if (isAdd) {  if (null != addAnimator && addAnimator.isstarted()) {  Logger.e("charTextVIE.加动画已执行.取消");  addAnimator.cancel();  }  if (null != minusAnimator && minusAnimator.isstarted()) {  Logger.e("charTextVIE.减动画已执行.取消");  minusAnimator.cancel();  }  sumNum(false);  minus(); } else {  if (null != minusAnimator && minusAnimator.isstarted()) {  Logger.e("charTextVIE.减动画已执行.取消");  minusAnimator.cancel();  }  if (null != addAnimator && addAnimator.isstarted()) {  Logger.e("charTextVIE.加动画已执行.取消");  addAnimator.cancel();  }  sumNum(true);  add(); } } /** * 重新计算绘画的值 * * @param isAdd */ private voID sumNum(boolean isAdd) { Logger.e("计算值开始"); oldNum = num; newNum = num + (isAdd ? 1 : -1); if (newNum < 0) {  newNum = 9; } else if (newNum > 9) {  newNum = 0; } num = newNum; Logger.e("计算值结束:" + num); }}

likeImageVIEw

public class likeImageVIEw extends VIEw { private Paint imagePaint,shiningPaint; private int shiningMoveX; private int shiningMoveY; private int measureWIDth; private int measureHeight; private Bitmap selectedBtimap; private Bitmap selectedShiningBtimap; private Bitmap unSelectedBtimap; private boolean isAdd = false; private float shiningAlpha = isAdd ? 1f : 0f; public likeImageVIEw(Context context) { super(context); init(); } public likeImageVIEw(Context context,attrs); init(); } public likeImageVIEw(Context context,defStyleAttr); init(); } private voID init() { imagePaint = new Paint(Paint.ANTI_AliAS_FLAG); shiningPaint = new Paint(Paint.ANTI_AliAS_FLAG); selectedBtimap = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_like_selected); selectedShiningBtimap = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_like_selected_shining); unSelectedBtimap = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_like_unselected); } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,heightmeasureSpec); int wIDthMode = MeasureSpec.getMode(wIDthMeasureSpec); int wIDthSize = MeasureSpec.getSize(wIDthMeasureSpec); switch (wIDthMode) {  case MeasureSpec.UnspecIFIED:  break;  case MeasureSpec.AT_MOST:  wIDthSize = Math.max(selectedBtimap.getWIDth(),unSelectedBtimap.getWIDth());  shiningMoveX = (int) (wIDthSize * 1.0f - selectedShiningBtimap.getWIDth()) - 2;  break;  case MeasureSpec.EXACTLY:  break; } int heightmode = MeasureSpec.getMode(wIDthMeasureSpec); int heightSize = MeasureSpec.getSize(wIDthMeasureSpec); switch (heightmode) {  case MeasureSpec.UnspecIFIED:  break;  case MeasureSpec.AT_MOST:  heightSize = Math.max(selectedBtimap.getHeight(),unSelectedBtimap.getHeight());  shiningMoveY = (int) (selectedShiningBtimap.getHeight() * 1.0f / 3);  heightSize += shiningMoveY;  break;  case MeasureSpec.EXACTLY:  break; } setMeasuredDimension(wIDthSize,heightSize); } @OverrIDe protected voID onDraw(Canvas canvas) { super.onDraw(canvas); int wIDth = getWIDth(); int height = getHeight(); Rect src = new Rect(0,wIDth,height); Rect selectDst = new Rect(0,shiningMoveY,selectedBtimap.getWIDth(),height); if (isAdd) {  //画红赞  canvas.drawBitmap(selectedBtimap,src,selectDst,imagePaint);  //画阴影  shiningPaint.setAlpha((int) (255 * shiningAlpha));  Rect shiningDst = new Rect(shiningMoveX,shiningMoveX + selectedShiningBtimap.getWIDth(),selectedShiningBtimap.getHeight());  canvas.drawBitmap(selectedShiningBtimap,shiningDst,shiningPaint); } else {  //画灰赞  canvas.drawBitmap(unSelectedBtimap,imagePaint); } } public voID setShiningAlpha(float shiningAlpha) { this.shiningAlpha = shiningAlpha; invalIDate(); } public voID setAdd(boolean add) { isAdd = add; shiningAlpha = 1.0f; invalIDate(); } public voID changelike(boolean isAdd) { this.isAdd = !isAdd; invalIDate(); anim(); } private voID anim() { ObjectAnimator scaleXAnim = ObjectAnimator.offloat(this,"scaleX",0.7f,1f); scaleXAnim.setDuration(500); ObjectAnimator scaleYAnim = ObjectAnimator.offloat(this,"scaleY",1f); scaleYAnim.setDuration(500); ObjectAnimator AlphaAnim = ObjectAnimator.offloat(this,"shiningAlpha",0f,1f); AlphaAnim.setDuration(500); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(scaleXAnim,scaleYAnim,AlphaAnim); animatorSet.setInterpolator(new BounceInterpolator()); animatorSet.start(); }}

likeVIEw

public class likeVIEw extends linearLayout { private final int IMAGEpadding = 4; private boolean isAdd = false; private int num; private int textSize; private int textcolor; private int imagepadding; private List<likeCharTextVIEw> charTvs = new ArrayList<>(); private likeImageVIEw likeImageVIEw; public likeVIEw(Context context) { super(context); init(); } public likeVIEw(Context context,attrs); init(); } public likeVIEw(Context context,attrs); init(); } private voID initAttr(Context context,AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.likeVIEw); textcolor = typedArray.getcolor(R.styleable.likeVIEw_textcolor,likeCharTextVIEw.DEFAulT_TEXTcolor); textSize = typedArray.getDimensionPixelSize(R.styleable.likeVIEw_textSize,likeCharTextVIEw.DEFAulT_TEXTSIZE); num = typedArray.getInt(R.styleable.likeVIEw_number,0); imagepadding = typedArray.getDimensionPixelSize(R.styleable.likeVIEw_imagepadding,IMAGEpadding); typedArray.recycle(); } /** * 初始化 */ private voID init() { initVIEw(); } protected voID initVIEw() { removeAllVIEws(); likeImageVIEw = new likeImageVIEw(getContext()); likeImageVIEw.setAdd(isAdd); linearLayout.LayoutParams layoutParams = new linearLayout.LayoutParams(VIEwGroup.LayoutParams.WRAP_CONTENT,VIEwGroup.LayoutParams.WRAP_CONTENT); layoutParams.rightmargin = imagepadding; likeImageVIEw.setLayoutParams(layoutParams); addVIEw(likeImageVIEw); charTvs.clear(); String str_num = String.valueOf(num); for (int i = 0; i < str_num.length(); i++) {  likeCharTextVIEw textVIEw = new likeCharTextVIEw(getContext());  int show_num = Integer.valueOf(str_num.substring(i,i + 1));  Log.e("zanvIEw","show_num:" + show_num);  textVIEw.setTextSize(textSize);  textVIEw.setTextcolor(textcolor);  textVIEw.setNum(show_num);  addVIEw(textVIEw);  charTvs.add(textVIEw); } } public voID setNum(int num) { this.num = num; init(); invalIDate(); } public voID setAdd(boolean add) { isAdd = add; } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,heightmeasureSpec); //计算出所有的childVIEw的宽高 measureChildren(wIDthMeasureSpec,heightmeasureSpec); setMeasuredDimension(measureWIDth(wIDthMeasureSpec),measureHeight(heightmeasureSpec)); } /** * 测量宽度 * * @param wIDthMeasureSpec * @return */ private int measureWIDth(int wIDthMeasureSpec) { int wIDthMode = MeasureSpec.getMode(wIDthMeasureSpec); int wIDthSize = MeasureSpec.getSize(wIDthMeasureSpec); switch (wIDthMode) {  case MeasureSpec.UnspecIFIED:  break;  case MeasureSpec.AT_MOST:  wIDthSize = 0;  for (int i = 0; i < getChildCount(); i++) {   VIEw childVIEw = getChildAt(i);   //获取子vIEw的宽   int cWIDth = childVIEw.getMeasureDWIDth();   marginLayoutParams params = (marginLayoutParams) childVIEw.getLayoutParams();   wIDthSize += cWIDth + params.leftmargin + params.rightmargin;  }  break;  case MeasureSpec.EXACTLY:  break; } return wIDthSize; } /** * 测量高度 * * @param wIDthMeasureSpec * @return */ private int measureHeight(int wIDthMeasureSpec) { int heightmode = MeasureSpec.getMode(wIDthMeasureSpec); int heightSize = MeasureSpec.getSize(wIDthMeasureSpec); switch (heightmode) {  case MeasureSpec.UnspecIFIED:  break;  case MeasureSpec.AT_MOST:  heightSize = 0;  for (int i = 0; i < getChildCount(); i++) {   VIEw childVIEw = getChildAt(i);   //获取子vIEw的宽   int cWIDth = childVIEw.getMeasuredHeight();   marginLayoutParams params = (marginLayoutParams) childVIEw.getLayoutParams();   int height = cWIDth + params.leftmargin + params.rightmargin;   heightSize = Math.max(heightSize,height);  }  break;  case MeasureSpec.EXACTLY:  break; } return heightSize; } private boolean click = false; private final int MOHUFANWEI = 10; private float lastX = 0; private float lastY = 0; @OverrIDe public boolean ontouchEvent(MotionEvent event) { super.ontouchEvent(event); float x = event.getX(); float y = event.getY(); switch (event.getAction()) {  case MotionEvent.ACTION_DOWN:  if (1 == event.getPointerCount()) {   click = true;  }  break;  case MotionEvent.ACTION_UP:  if (click) {   onClick();  }  break;  case MotionEvent.ACTION_MOVE:  if (Math.abs(lastX - x) > MOHUFANWEI || Math.abs(lastY - y) > MOHUFANWEI) {   click = false;  }  break; } lastX = x; lastY = y; return true; } private voID onClick() { Logger.e("点击事件" + isAdd); String str_num = String.valueOf(num); Logger.e("点击事件,str_num:" + str_num); boolean nextAnim = false; if (isAdd) {  likeImageVIEw.changelike(true);  for (int i = (str_num.length() - 1); i >= 0; i--) {  int chr_num = Integer.valueOf(str_num.substring(i,i + 1));  Logger.e("点击事件,chr_num:%d,charTvs.size:%d,i:%d",chr_num,charTvs.size(),i);  Logger.e("是否执行动画:" + (charTvs.size() > i));  if (charTvs.size() > i) {   if (i == (str_num.length() - 1) || nextAnim) {   Logger.e("点击事件,执行个位动画||%b执行执行上%d位动画",nextAnim,i);   charTvs.get(i).change(true);   chr_num--;   Logger.e("chr_num:%d,是否执行上一位动画:",(chr_num < 0));   if (chr_num < 0) {    nextAnim = true;   } else {    nextAnim = false;   }   Logger.e("nextAnim:" + nextAnim);   }  }  }  num--;  isAdd = !isAdd; } else {  likeImageVIEw.changelike(false);  for (int i = (str_num.length() - 1); i >= 0; i--) {  int chr_num = Integer.valueOf(str_num.substring(i,i);   charTvs.get(i).change(false);   chr_num++;   Logger.e("chr_num:%d,是否执行上一位动画:",(chr_num > 9));   if (chr_num > 9) {    nextAnim = true;   } else {    nextAnim = false;   }   Logger.e("nextAnim:" + nextAnim);   }  }  }  num++;  isAdd = !isAdd; } }}

attrs.xml

<attr name="textSize" format="dimension" /> <attr name="textcolor" format="color" /> <attr name="number" format="integer" /> <attr name="imageWIDth" format="dimension" /> <attr name="imageHeight" format="dimension" /> <declare-styleable name="likeVIEw"> <attr name="textSize" /> <attr name="textcolor" /> <attr name="number" /> <attr name="imageWithd" /> <attr name="imageHeight" /> <attr name="imagepadding" format="dimension" /> </declare-styleable> <declare-styleable name="likeCharTextVIEw"> <attr name="textSize" /> <attr name="textcolor" /> <attr name="number" /> </declare-styleable> <declare-styleable name="likeImageVIEw"> <attr name="imageWithd" /> <attr name="imageHeight" /></declare-styleable>

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

总结

以上是内存溢出为你收集整理的Android自定义View实现点赞控件全部内容,希望文章能够帮你解决Android自定义View实现点赞控件所遇到的程序开发问题。

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

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存