1,前天在鸿洋的公众号上看到一款不错的点赞效果,是仿最美有物的点赞,再加上自己最近学习状态很差,自己想着通过这个效果练手一下,果然,花了整整两天的时间,按照以前的效率的话一天就够了,哎,已经调整了一个多月了,希望自己状态早点找回来吧,早点给大家多写写博客。

2,回到正题上来,今天我们实现的效果如下:

  其实上面的效果很简单,都是使用动画效果,基本上可以拆分为三部分,两个圆拉升变长变成一个四边圆角的矩形-->播放帧动画点头或者摇头的效果--->动画回收效果

① 、动画两个圆拉升变长变成一个四边圆角的矩形效果

按照我们上面解析的三个步骤,我们首先是要实现拉伸变长效果,要实现的效果如下:

  当时自己写这个效果的时候也是先在这个地方犹豫了一下,我们知道上面的效果首先是由圆变成带圆角的矩形,所以这里我开始想到的实现效果是首先创建一个圆角很大的shape文件,分别颜色值分别是白色和黄色。然后设置一个喜欢和不喜欢的view每一个其实是一个ImageView 然后设置gravity设置为top,使用我们刚创建的shape文件为背景,使用笑脸当做src的文件,然后使用属性动画不停的增大ImageView的paddingBottom属性,这样就可以把我们的布局不断的撑大,从而实现这个阶段的效果。

  既然我们有了这样的思路开撸开撸,但是现实很悲催ImageView 没有gravity属性,不过没事,我们可以使用一个Relatation或者LinearLayout包裹ImageView不断地设置Relatation或者LinearLayout的paddingBottom属性就可以解决,我之后去看了一下原作者的思路和我的很想,不过他是设置里面的ImageView的MarginBottom的边距。

  这里我们是自定义view,分析了一下我们还是继承LinearLayout,主要的大界面分为三部分左边不喜欢的view、右边喜欢的view、中间的短分割线,如下图:

  当动画开始的时候,上面显示“60%” “无感”等字样的,这里我们每一个喜欢或不喜欢的view其实都也还是一个LinearLayout,里面包含三个部分:两个头部的TextView还有下面的我们上面分析过的拉长的矩形

所以这里我们先创建LikeSmileView.java 继承LinearLayout

  1. public class LikeSmileView extends LinearLayout {
  2. private static String TAG = "LikeSmileView" ;
  3. private Context mContext ;
  4.  
  5. private int dividerMargin ;
  6.  
  7. //喜欢和不喜欢的图标
  8. private ImageView mImageViewLike ;
  9. private ImageView mImageViewDisLike ;
  10. private TextView mTextViewLike ;
  11. private TextView mTextViewDisLike ;
  12. private TextView mTextViewLikeCharacter;
  13. private TextView mTextViewDisLikeCharacter;
  14. private LinearLayout mLinearLikeBg ;
  15. private LinearLayout mLinearDisLikeBg ;
  16. private LinearLayout mLinearAlllike ;
  17. private LinearLayout mLinearAllDisLike ;
  18.  
  19. //喜欢和不喜欢的文字
  20. private String defaultLikeString ;
  21. private String defaultDisLikeString ;
  22.  
  23. //动画出来时候的背景颜色
  24. private int shadowColor ;
  25.  
  26. //设置默认的点赞数和差评数
  27. private int likeCount = 10 ;
  28. private int dislikeCount = 20 ;
  29. //喜欢和不喜欢所占比例
  30. private float fLikePercentage;
  31. private float fDisLikePercentage;
  32.  
  33. //帧动画
  34. private AnimationDrawable likeFrameAnimation ;
  35. private AnimationDrawable disLikeFrameAnimation ;
  36.  
  37. //默认文字的颜色
  38. private int defaultTextColor ;
  39. //默认文字的大小
  40. private float defaultTextSize ;
  41.  
  42. //默认图片背景的大小
  43. private int defaultBackGroundSize ;
  44.  
  45. //扩展动画
  46. private ValueAnimator mAnimatorScrollLarge ;
  47.  
  48. //收回动画
  49. private ValueAnimator mAnimatorBack;
  50.  
  51. //执行动画分类
  52. private int type ;
  53.  
  54. //记录动画是否完成
  55. private boolean isClosed ;
  56.  
  57. public LikeSmileView(Context context) {
  58. this(context,null);
  59. }
  60.  
  61. public LikeSmileView(Context context, @Nullable AttributeSet attrs) {
  62. this(context, attrs,0);
  63. }
  64.  
  65. public LikeSmileView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  66. super(context, attrs, defStyleAttr);
  67. this.mContext = context ;
  68. init();
  69. }
  70. }

  然后再init()方法里面来初始化一些基本数值、初始化一些控件,然后创建view添加到主布局里面去,代码如下:

  1. private void init() {
  2. //设置LinearLayout的一些属性
  3. setOrientation(HORIZONTAL);
  4. setGravity(Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM);
  5. setBackgroundColor(Color.TRANSPARENT);
  6.  
  7. //初始化一些数据值
  8. defaultLikeString = getResources().getString(like);
  9. defaultDisLikeString = getResources().getString(R.string.dislike);
  10. shadowColor = getResources().getColor(R.color.shadow);
  11. defaultTextColor =getResources().getColor(R.color.white);
  12. defaultTextSize = getResources().getDimension(R.dimen.dimen_16);
  13. defaultBackGroundSize = (int)getResources().getDimension(R.dimen.dimen_25);
  14.  
  15. dividerMargin = 30 ;
  16.  
  17. //计算动画开始高度的百分比
  18. float sunCount = likeCount+dislikeCount;
  19. fLikePercentage = likeCount / sunCount;
  20. fDisLikePercentage = dislikeCount /sunCount ;
  21.  
  22. //初始化图片
  23. mImageViewLike = new ImageView(mContext);
  24. mImageViewLike.setBackgroundResource(R.drawable.animation_like);
  25. likeFrameAnimation = (AnimationDrawable) mImageViewLike.getBackground();
  26.  
  27. mImageViewDisLike = new ImageView(mContext);
  28. mImageViewDisLike.setBackgroundResource(R.drawable.animation_dislike);
  29. disLikeFrameAnimation = (AnimationDrawable) mImageViewDisLike.getBackground();
  30.  
  31. //初始化文字
  32. mTextViewLike = new TextView(mContext);
  33. mTextViewLike.setText((int)(fLikePercentage * 100)+"%");
  34. mTextViewLike.setTextColor(defaultTextColor);
  35.  
  36. mTextViewLikeCharacter = new TextView(getContext());
  37. mTextViewLikeCharacter.setText(defaultLikeString);
  38. mTextViewLikeCharacter.setTextColor(defaultTextColor);
  39.  
  40. mTextViewDisLike = new TextView(mContext);
  41. mTextViewDisLike.setText((int)(fDisLikePercentage * 100)+"%");
  42. mTextViewDisLike.setTextColor(defaultTextColor);
  43.  
  44. mTextViewDisLikeCharacter = new TextView(getContext());
  45. mTextViewDisLikeCharacter.setText(defaultDisLikeString);
  46. mTextViewDisLikeCharacter.setTextColor(defaultTextColor);
  47.  
  48. //初始化背景view
  49. mLinearLikeBg = new LinearLayout(mContext);
  50. LayoutParams params = new LayoutParams(defaultBackGroundSize, defaultBackGroundSize);
  51. mLinearLikeBg.addView(mImageViewLike,params);
  52. mLinearLikeBg.setBackgroundResource(R.drawable.ic_select_yellow);
  53.  
  54. mLinearDisLikeBg = new LinearLayout(mContext);
  55. mLinearDisLikeBg.addView(mImageViewDisLike,params);
  56. mLinearDisLikeBg.setBackgroundResource(R.drawable.ic_select_white);
  57.  
  58. //初始化单个喜欢/不喜欢的view
  59. mLinearAlllike = new LinearLayout(mContext);
  60. mLinearAlllike.setOrientation(VERTICAL);
  61. mLinearAlllike.setGravity(Gravity.CENTER_HORIZONTAL);
  62. mLinearAlllike.setBackgroundColor(Color.TRANSPARENT);
  63.  
  64. mLinearAllDisLike = new LinearLayout(mContext);
  65. mLinearAllDisLike.setOrientation(VERTICAL);
  66. mLinearAllDisLike.setGravity(Gravity.CENTER_HORIZONTAL);
  67. mLinearAllDisLike.setBackgroundColor(Color.TRANSPARENT);
  68.  
  69. //将文字放入LinearLayout中
  70. LayoutParams paramsAll = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  71. paramsAll.setMargins(0, 10, 0, 0);
  72. paramsAll.gravity = Gravity.CENTER;
  73.  
  74. mLinearAlllike.addView(mTextViewLike,paramsAll);
  75. mLinearAlllike.addView(mTextViewLikeCharacter,paramsAll);
  76. mLinearAlllike.addView(mLinearLikeBg,paramsAll);
  77.  
  78. mLinearAllDisLike.addView(mTextViewDisLike,paramsAll);
  79. mLinearAllDisLike.addView(mTextViewDisLikeCharacter,paramsAll);
  80. mLinearAllDisLike.addView(mLinearDisLikeBg,paramsAll);
  81.  
  82. //添加中间的分割线
  83. ImageView imageView = new ImageView(getContext());
  84. imageView.setBackground(new ColorDrawable(Color.GRAY));
  85. LayoutParams params4 = new LayoutParams(3, 60);
  86. params4.setMargins(dividerMargin, 10, dividerMargin, 40);
  87. params4.gravity = Gravity.BOTTOM;
  88.  
  89. LayoutParams params3 = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  90. params3.setMargins(30, 20, 30, 20);
  91. params3.gravity = Gravity.BOTTOM;
  92.  
  93. //添加到总的布局
  94. addView(mLinearAllDisLike,params3);
  95. addView(imageView,params4);
  96. addView(mLinearAlllike,params3);
  97.  
  98. setVisibities(GONE);
  99. }

  有了上面的代码我们可以运行一下,可以实现我们基本的视图效果了,如下:

这时候到了我们最关键的一步了,就是监听用户点击喜欢和不喜欢两个ImageView的事件,从而触发我们的动画效果,大致代码如下:

  1. //添加监听
  2. mImageViewLike.setOnClickListener(new OnClickListener() {
  3. @Override
  4. public void onClick(View view) {
  5. type = 1 ;
  6. //首先拉伸背景
  7. animScrollLarge();
  8. //展示文字
  9. setVisibities(VISIBLE);
  10. //改变被选择的背景
  11. mLinearLikeBg.setBackgroundResource(R.drawable.ic_select_yellow);
  12. mLinearDisLikeBg.setBackgroundResource(R.drawable.ic_select_white);
  13. //改变整个view的背景颜色
  14. setBackgroundColor(shadowColor);
  15. }
  16. });
  17.  
  18. mImageViewDisLike.setOnClickListener(new OnClickListener() {
  19. @Override
  20. public void onClick(View view) {
  21. type = 2 ;
  22. //首先拉伸背景
  23. animScrollLarge();
  24. //展示文字
  25. setVisibities(VISIBLE);
  26. //改变被选择的背景
  27. mLinearLikeBg.setBackgroundResource(R.drawable.ic_select_white);
  28. mLinearDisLikeBg.setBackgroundResource(R.drawable.ic_select_yellow);
  29. //改变整个view的背景颜色
  30. setBackgroundColor(shadowColor);
  31. }
  32. });

  这里用过type来记录用户点击的是喜欢和不喜欢,然后就是点击之后一些静态的视图上面的改变,到了我们第一个关键的方法animScrollLarge()是实现布局拉长的具体实现方法,这里卧室使用属性动画来实现了,让imageview的marginBottom属性在5px-300px之间改变,这里的数值大家可以根据自己的实际情况来改变,代码如下:

  1. private void animScrollLarge() {
  2. //在动画执行的时候不予许点击
  3. mImageViewDisLike.setClickable(false);
  4. mImageViewLike.setClickable(false);
  5.  
  6. isClosed = false ;
  7.  
  8. //计算两者比例的最大值
  9. int max = Math.max(likeCount * 15 ,dislikeCount *15) ;
  10. mAnimatorScrollLarge = ValueAnimator.ofInt(5,max);
  11. mAnimatorScrollLarge.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  12. @Override
  13. public void onAnimationUpdate(ValueAnimator valueAnimator) {
  14. int margin = (int) valueAnimator.getAnimatedValue();
  15. LayoutParams paramsLike
  16. = (LayoutParams) mImageViewLike.getLayoutParams();
  17. paramsLike.bottomMargin = margin;
  18.  
  19. if (margin <= likeCount * 15) {
  20. mImageViewLike.setLayoutParams(paramsLike);
  21. }
  22. if (margin <= dislikeCount * 15) {
  23. mImageViewDisLike.setLayoutParams(paramsLike);
  24. }
  25. }
  26. });
  27.  
  28. mAnimatorScrollLarge.setDuration(500);
  29. mAnimatorScrollLarge.start();
  30. }

  ok,这样我们第一阶段的效果就实现了,来看看实现的效果:

② 播放帧动画点头或者摇头的效果

  先看一下我们要实现的效果

这里主要是一个帧动画的播放,但是,如果只播放帧动画的的话就只有以下效果:

可以看到,如果只播放帧动画的话,就没有点头的二维效果,所以在播放帧动画的同时我们要继续加上一个上下小范围的移动动画,从而实现那种立体的点头效果,代码如下:

  1. private void changeY(View view){
  2. ObjectAnimator animator = ObjectAnimator.ofFloat(view,"translationY",-10.0f,0f,10.0f,0f,-10f,0f,10.0f,0f);
  3. animator.setRepeatMode(ObjectAnimator.RESTART);//重复模式
  4. animator.setDuration(1500);
  5. animator.start();
  6. animator.addListener(new AnimatorListenerAdapter() {
  7. @Override
  8. public void onAnimationEnd(Animator animator) {
  9.  
  10. }
  11.  
  12. });
  13. }

  同理,当点击不喜欢的时候,我们的帧动画也没有那种立体的效果,而我们平常在表示不同意的时候是摇头,所以不同于我们上面的代码我们这里是左右小范围的移动动画

  1. private void changeX(View view ){
  2. ObjectAnimator animator = ObjectAnimator.ofFloat(view,"translationX",-10.0f,0f,10.0f,0f,-10f,0f,10.0f,0f);
  3. animator.setRepeatMode(ObjectAnimator.RESTART);//重复模式
  4. animator.setDuration(1500);
  5. animator.start();
  6. animator.addListener(new AnimatorListenerAdapter() {
  7. @Override
  8. public void onAnimationEnd(Animator animator) {
  9. }
  10.  
  11. });
  12. }

  ok,这样我们的点头摇头效果就实现了,很简单有没有,就是两个简单的动画

③、动画回收效果

  这个效果很简单,就是动画回收的效果,和我们步骤一的动画效果很想,我们步骤一的效果是撑大,而这个是缩小,所以只需要把ImageView的marginBottom的值由350px变成5px就行

  1. private void setBackAnim() {
  2. isClosed = true ;
  3.  
  4. //计算两者比例的最大值
  5. int max = Math.max(likeCount * 15 ,dislikeCount *15) ;
  6. mAnimatorBack = ValueAnimator.ofInt(max,5);
  7. mAnimatorBack.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  8. @Override
  9. public void onAnimationUpdate(ValueAnimator valueAnimator) {
  10. int margin = (int) valueAnimator.getAnimatedValue();
  11. LayoutParams paramsLike
  12. = (LayoutParams) mImageViewLike.getLayoutParams();
  13. paramsLike.bottomMargin = margin;
  14.  
  15. if (margin <= likeCount * 15) {
  16. mImageViewLike.setLayoutParams(paramsLike);
  17. }
  18. if (margin <= dislikeCount * 15) {
  19. mImageViewDisLike.setLayoutParams(paramsLike);
  20. }
  21. }
  22. });
  23.  
  24. mAnimatorBack.addListener(this);
  25. mAnimatorBack.setDuration(500);
  26. mAnimatorBack.start();
  27. }

  再监听这个动画的完成,当回缩动画完成时候,将上面的文字消失,背景设置成透明,imageview图片设置成初始图片操作

  1. //文字消失
  2. setVisibities(GONE);
  3. //恢复透明
  4. setBackgroundColor(Color.TRANSPARENT);
  5. //播放完成之后恢复到原始图片
  6. if (type == 1){
  7. mImageViewLike.setBackground(null);
  8. mImageViewLike.setBackgroundResource(R.drawable.animation_like);
  9. likeFrameAnimation = (AnimationDrawable) mImageViewLike.getBackground();
  10. }else {
  11. mImageViewDisLike.setBackground(null);
  12. mImageViewDisLike.setBackgroundResource(R.drawable.animation_dislike);
  13. disLikeFrameAnimation = (AnimationDrawable) mImageViewDisLike.getBackground();
  14. }

  ok,到这里我们的效果基本上都实现了,这里贴一下LikeSmileView的整个代码

  1. package com.ysten.likesmilebar;
  2.  
  3. import android.animation.Animator;
  4. import android.animation.AnimatorListenerAdapter;
  5. import android.animation.ObjectAnimator;
  6. import android.animation.ValueAnimator;
  7. import android.content.Context;
  8. import android.graphics.Color;
  9. import android.graphics.drawable.AnimationDrawable;
  10. import android.graphics.drawable.ColorDrawable;
  11. import android.support.annotation.Nullable;
  12. import android.util.AttributeSet;
  13. import android.view.Gravity;
  14. import android.view.View;
  15. import android.view.ViewGroup;
  16. import android.widget.ImageView;
  17. import android.widget.LinearLayout;
  18. import android.widget.TextView;
  19.  
  20. import static com.ysten.likesmilebar.R.string.like;
  21.  
  22. /**
  23. * author : wangjitao
  24. * e-mail : 543441727@qq.com
  25. * time : 2017/08/10
  26. * desc :
  27. * version: 1.0
  28. */
  29. public class LikeSmileView extends LinearLayout implements Animator.AnimatorListener{
  30. private static String TAG = "LikeSmileView" ;
  31. private Context mContext ;
  32.  
  33. private int dividerMargin ;
  34.  
  35. //喜欢和不喜欢的图标
  36. private ImageView mImageViewLike ;
  37. private ImageView mImageViewDisLike ;
  38. private TextView mTextViewLike ;
  39. private TextView mTextViewDisLike ;
  40. private TextView mTextViewLikeCharacter;
  41. private TextView mTextViewDisLikeCharacter;
  42. private LinearLayout mLinearLikeBg ;
  43. private LinearLayout mLinearDisLikeBg ;
  44. private LinearLayout mLinearAlllike ;
  45. private LinearLayout mLinearAllDisLike ;
  46.  
  47. //喜欢和不喜欢的文字
  48. private String defaultLikeString ;
  49. private String defaultDisLikeString ;
  50.  
  51. //动画出来时候的背景颜色
  52. private int shadowColor ;
  53.  
  54. //设置默认的点赞数和差评数
  55. private int likeCount = 10 ;
  56. private int dislikeCount = 20 ;
  57. //喜欢和不喜欢所占比例
  58. private float fLikePercentage;
  59. private float fDisLikePercentage;
  60.  
  61. //帧动画
  62. private AnimationDrawable likeFrameAnimation ;
  63. private AnimationDrawable disLikeFrameAnimation ;
  64.  
  65. //默认文字的颜色
  66. private int defaultTextColor ;
  67. //默认文字的大小
  68. private float defaultTextSize ;
  69.  
  70. //默认图片背景的大小
  71. private int defaultBackGroundSize ;
  72.  
  73. //扩展动画
  74. private ValueAnimator mAnimatorScrollLarge ;
  75.  
  76. //收回动画
  77. private ValueAnimator mAnimatorBack;
  78.  
  79. //执行动画分类
  80. private int type ;
  81.  
  82. //记录动画是否完成
  83. private boolean isClosed ;
  84.  
  85. public LikeSmileView(Context context) {
  86. this(context,null);
  87. }
  88.  
  89. public LikeSmileView(Context context, @Nullable AttributeSet attrs) {
  90. this(context, attrs,0);
  91. }
  92.  
  93. public LikeSmileView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  94. super(context, attrs, defStyleAttr);
  95. this.mContext = context ;
  96. init();
  97. }
  98.  
  99. private void init() {
  100. //设置LinearLayout的一些属性
  101. setOrientation(HORIZONTAL);
  102. setGravity(Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM);
  103. setBackgroundColor(Color.TRANSPARENT);
  104.  
  105. //初始化一些数据值
  106. defaultLikeString = getResources().getString(like);
  107. defaultDisLikeString = getResources().getString(R.string.dislike);
  108. shadowColor = getResources().getColor(R.color.shadow);
  109. defaultTextColor =getResources().getColor(R.color.white);
  110. defaultTextSize = getResources().getDimension(R.dimen.dimen_16);
  111. defaultBackGroundSize = (int)getResources().getDimension(R.dimen.dimen_25);
  112.  
  113. dividerMargin = 30 ;
  114.  
  115. //计算动画开始高度的百分比
  116. float sunCount = likeCount+dislikeCount;
  117. fLikePercentage = likeCount / sunCount;
  118. fDisLikePercentage = dislikeCount /sunCount ;
  119.  
  120. //初始化图片
  121. mImageViewLike = new ImageView(mContext);
  122. mImageViewLike.setBackgroundResource(R.drawable.animation_like);
  123. likeFrameAnimation = (AnimationDrawable) mImageViewLike.getBackground();
  124.  
  125. mImageViewDisLike = new ImageView(mContext);
  126. mImageViewDisLike.setBackgroundResource(R.drawable.animation_dislike);
  127. disLikeFrameAnimation = (AnimationDrawable) mImageViewDisLike.getBackground();
  128.  
  129. //初始化文字
  130. mTextViewLike = new TextView(mContext);
  131. mTextViewLike.setText((int)(fLikePercentage * 100)+"%");
  132. mTextViewLike.setTextColor(defaultTextColor);
  133.  
  134. mTextViewLikeCharacter = new TextView(getContext());
  135. mTextViewLikeCharacter.setText(defaultLikeString);
  136. mTextViewLikeCharacter.setTextColor(defaultTextColor);
  137.  
  138. mTextViewDisLike = new TextView(mContext);
  139. mTextViewDisLike.setText((int)(fDisLikePercentage * 100)+"%");
  140. mTextViewDisLike.setTextColor(defaultTextColor);
  141.  
  142. mTextViewDisLikeCharacter = new TextView(getContext());
  143. mTextViewDisLikeCharacter.setText(defaultDisLikeString);
  144. mTextViewDisLikeCharacter.setTextColor(defaultTextColor);
  145.  
  146. //初始化背景view
  147. mLinearLikeBg = new LinearLayout(mContext);
  148. LayoutParams params = new LayoutParams(defaultBackGroundSize, defaultBackGroundSize);
  149. mLinearLikeBg.addView(mImageViewLike,params);
  150. mLinearLikeBg.setBackgroundResource(R.drawable.ic_select_yellow);
  151.  
  152. mLinearDisLikeBg = new LinearLayout(mContext);
  153. mLinearDisLikeBg.addView(mImageViewDisLike,params);
  154. mLinearDisLikeBg.setBackgroundResource(R.drawable.ic_select_white);
  155.  
  156. //初始化单个喜欢/不喜欢的view
  157. mLinearAlllike = new LinearLayout(mContext);
  158. mLinearAlllike.setOrientation(VERTICAL);
  159. mLinearAlllike.setGravity(Gravity.CENTER_HORIZONTAL);
  160. mLinearAlllike.setBackgroundColor(Color.TRANSPARENT);
  161.  
  162. mLinearAllDisLike = new LinearLayout(mContext);
  163. mLinearAllDisLike.setOrientation(VERTICAL);
  164. mLinearAllDisLike.setGravity(Gravity.CENTER_HORIZONTAL);
  165. mLinearAllDisLike.setBackgroundColor(Color.TRANSPARENT);
  166.  
  167. //将文字放入LinearLayout中
  168. LayoutParams paramsAll = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  169. paramsAll.setMargins(0, 10, 0, 0);
  170. paramsAll.gravity = Gravity.CENTER;
  171.  
  172. mLinearAlllike.addView(mTextViewLike,paramsAll);
  173. mLinearAlllike.addView(mTextViewLikeCharacter,paramsAll);
  174. mLinearAlllike.addView(mLinearLikeBg,paramsAll);
  175.  
  176. mLinearAllDisLike.addView(mTextViewDisLike,paramsAll);
  177. mLinearAllDisLike.addView(mTextViewDisLikeCharacter,paramsAll);
  178. mLinearAllDisLike.addView(mLinearDisLikeBg,paramsAll);
  179.  
  180. //添加中间的分割线
  181. ImageView imageView = new ImageView(getContext());
  182. imageView.setBackground(new ColorDrawable(Color.GRAY));
  183. LayoutParams params4 = new LayoutParams(3, 60);
  184. params4.setMargins(dividerMargin, 10, dividerMargin, 40);
  185. params4.gravity = Gravity.BOTTOM;
  186.  
  187. LayoutParams params3 = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  188. params3.setMargins(30, 20, 30, 20);
  189. params3.gravity = Gravity.BOTTOM;
  190.  
  191. //添加到总的布局
  192. addView(mLinearAllDisLike,params3);
  193. addView(imageView,params4);
  194. addView(mLinearAlllike,params3);
  195.  
  196. setVisibities(GONE);
  197.  
  198. //添加监听
  199. mImageViewLike.setOnClickListener(new OnClickListener() {
  200. @Override
  201. public void onClick(View view) {
  202. type = 1 ;
  203. //首先拉伸背景
  204. animScrollLarge();
  205. //展示文字
  206. setVisibities(VISIBLE);
  207. //改变被选择的背景
  208. mLinearLikeBg.setBackgroundResource(R.drawable.ic_select_yellow);
  209. mLinearDisLikeBg.setBackgroundResource(R.drawable.ic_select_white);
  210. //改变整个view的背景颜色
  211. setBackgroundColor(shadowColor);
  212. }
  213. });
  214.  
  215. mImageViewDisLike.setOnClickListener(new OnClickListener() {
  216. @Override
  217. public void onClick(View view) {
  218. type = 2 ;
  219. //首先拉伸背景
  220. animScrollLarge();
  221. //展示文字
  222. setVisibities(VISIBLE);
  223. //改变被选择的背景
  224. mLinearLikeBg.setBackgroundResource(R.drawable.ic_select_white);
  225. mLinearDisLikeBg.setBackgroundResource(R.drawable.ic_select_yellow);
  226. //改变整个view的背景颜色
  227. setBackgroundColor(shadowColor);
  228. }
  229. });
  230.  
  231. //设置初始化界面
  232. }
  233.  
  234. private void animScrollLarge() {
  235. //在动画执行的时候不予许点击
  236. mImageViewDisLike.setClickable(false);
  237. mImageViewLike.setClickable(false);
  238.  
  239. isClosed = false ;
  240.  
  241. //计算两者比例的最大值
  242. int max = Math.max(likeCount * 15 ,dislikeCount *15) ;
  243. mAnimatorScrollLarge = ValueAnimator.ofInt(5,max);
  244. mAnimatorScrollLarge.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  245. @Override
  246. public void onAnimationUpdate(ValueAnimator valueAnimator) {
  247. int margin = (int) valueAnimator.getAnimatedValue();
  248. LayoutParams paramsLike
  249. = (LayoutParams) mImageViewLike.getLayoutParams();
  250. paramsLike.bottomMargin = margin;
  251.  
  252. if (margin <= likeCount * 15) {
  253. mImageViewLike.setLayoutParams(paramsLike);
  254. }
  255. if (margin <= dislikeCount * 15) {
  256. mImageViewDisLike.setLayoutParams(paramsLike);
  257. }
  258. }
  259. });
  260.  
  261. mAnimatorScrollLarge.addListener(this);
  262. mAnimatorScrollLarge.setDuration(500);
  263. mAnimatorScrollLarge.start();
  264.  
  265. }
  266.  
  267. private void setVisibities(int mode){
  268. mTextViewDisLikeCharacter.setVisibility(mode);
  269. mTextViewDisLike.setVisibility(mode);
  270. mTextViewLike.setVisibility(mode);
  271. mTextViewLikeCharacter.setVisibility(mode);
  272. }
  273.  
  274. @Override
  275. public void onAnimationStart(Animator animator) {
  276.  
  277. }
  278.  
  279. @Override
  280. public void onAnimationEnd(Animator animator) {
  281. //重置帧动画
  282. likeFrameAnimation.stop();
  283. disLikeFrameAnimation.stop();
  284.  
  285. //收回后可点击
  286. if (isClosed){
  287. mImageViewLike.setClickable(true);
  288. mImageViewDisLike.setClickable(true);
  289. //文字消失
  290. setVisibities(GONE);
  291. //恢复透明
  292. setBackgroundColor(Color.TRANSPARENT);
  293. //播放完成之后恢复到原始图片
  294. if (type == 1){
  295. mImageViewLike.setBackground(null);
  296. mImageViewLike.setBackgroundResource(R.drawable.animation_like);
  297. likeFrameAnimation = (AnimationDrawable) mImageViewLike.getBackground();
  298. }else {
  299. mImageViewDisLike.setBackground(null);
  300. mImageViewDisLike.setBackgroundResource(R.drawable.animation_dislike);
  301. disLikeFrameAnimation = (AnimationDrawable) mImageViewDisLike.getBackground();
  302. }
  303.  
  304. return;
  305. }
  306.  
  307. //根据type判断执行的是哪个动画
  308. if(type ==1 ){
  309. //开始帧动画
  310. likeFrameAnimation.start();
  311. //开始点头动画
  312. changeY(mImageViewLike);
  313.  
  314. }else {
  315. //开始帧动画
  316. disLikeFrameAnimation.start();
  317. //开始摇头动画
  318. changeX(mImageViewDisLike);
  319. }
  320. }
  321.  
  322. private void changeY(View view){
  323. ObjectAnimator animator = ObjectAnimator.ofFloat(view,"translationY",-10.0f,0f,10.0f,0f,-10f,0f,10.0f,0f);
  324. animator.setRepeatMode(ObjectAnimator.RESTART);//重复模式
  325. animator.setDuration(1500);
  326. animator.start();
  327. animator.addListener(new AnimatorListenerAdapter() {
  328. @Override
  329. public void onAnimationEnd(Animator animator) {
  330. setBackAnim();//执行回弹动画
  331. }
  332.  
  333. });
  334. }
  335.  
  336. private void changeX(View view ){
  337. ObjectAnimator animator = ObjectAnimator.ofFloat(view,"translationX",-10.0f,0f,10.0f,0f,-10f,0f,10.0f,0f);
  338. animator.setRepeatMode(ObjectAnimator.RESTART);//重复模式
  339. animator.setDuration(1500);
  340. animator.start();
  341. animator.addListener(new AnimatorListenerAdapter() {
  342. @Override
  343. public void onAnimationEnd(Animator animator) {
  344. setBackAnim();//执行回弹动画
  345. }
  346.  
  347. });
  348. }
  349.  
  350. @Override
  351. public void onAnimationCancel(Animator animator) {
  352.  
  353. }
  354.  
  355. @Override
  356. public void onAnimationRepeat(Animator animator) {
  357.  
  358. }
  359.  
  360. private void setBackAnim() {
  361. isClosed = true ;
  362.  
  363. //计算两者比例的最大值
  364. int max = Math.max(likeCount * 15 ,dislikeCount *15) ;
  365. mAnimatorBack = ValueAnimator.ofInt(max,5);
  366. mAnimatorBack.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  367. @Override
  368. public void onAnimationUpdate(ValueAnimator valueAnimator) {
  369. int margin = (int) valueAnimator.getAnimatedValue();
  370. LayoutParams paramsLike
  371. = (LayoutParams) mImageViewLike.getLayoutParams();
  372. paramsLike.bottomMargin = margin;
  373.  
  374. if (margin <= likeCount * 15) {
  375. mImageViewLike.setLayoutParams(paramsLike);
  376. }
  377. if (margin <= dislikeCount * 15) {
  378. mImageViewDisLike.setLayoutParams(paramsLike);
  379. }
  380. }
  381. });
  382.  
  383. mAnimatorBack.addListener(this);
  384. mAnimatorBack.setDuration(500);
  385. mAnimatorBack.start();
  386. }
  387. }

  最后实现的效果如下:

Android -- 《 最美有物》好看的点赞效果的更多相关文章

  1. Android -- 自定义ViewGroup+贝塞尔+属性动画实现仿QQ点赞效果

    1,昨天我们写了篇简单的贝塞尔曲线的应用,今天和大家一起写一个QQ名片上常用的给别人点赞的效果,实现效果图如下: 红心的图片比较丑,见谅见谅(哈哈哈哈哈哈).... 2,实现的思路和原理 从上面的效果 ...

  2. Android类似Periscope点赞效果

    原文   https://github.com/AlanCheen/PeriscopeLayout 主题 安卓开发 PeriscopeLayout A layout with animation li ...

  3. android shape的使用详解以及常用效果(渐变色、分割线、边框、半透明阴影效果等)

    shape使用.渐变色.分割线.边框.半透明.半透明阴影效果. 首先简单了解一下shape中常见的属性.(详细介绍参看  api文档 ) 转载请注明:Rflyee_大飞: http://blog.cs ...

  4. Android实现渐显按钮的左右滑动效果

    本示例演示在Android中实现带渐显按钮的左右滑动效果. 关于滑动效果,在我的上一篇博文中提到过,有兴趣的朋友可以访问: http://www.cnblogs.com/hanyonglu/archi ...

  5. Android实训案例(三)——实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果!

    Android实训案例(三)--实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果! 感叹离春节将至,也同时感叹时间不等人,一年又一年,可是我依然是android道路上的小菜鸟,这篇讲 ...

  6. Android给控件添加默认点击效果

    Android控件点击效果 Android中Button控件是有点击效果的,但是像TextView.ImageView.各种Layout是没有点击效果的,给TextView设置点击事件后,加个点击效果 ...

  7. Android使用ToolBar+DrawerLayout+NavigationView实现侧滑抽屉效果

    学会使用DrawerLayout 学会使用NavigationView 学会使用ToolBar+DrawerLayout+NavigationView实现侧滑抽屉效果 学会实现Toolbar在顶部以及 ...

  8. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之游戏效果预览(一)

    今天看完了李刚老师的<疯狂Android讲义>一书中的第18章<疯狂连连看>,从而学会了如何编写一个简单的Android疯狂连连看游戏. 开发这个流行的小游戏,难度适中,而且能 ...

  9. Android平台中的三种翻页效果机器实现原理

    本文给开发者集中展现了Android平台中的三种翻页效果机器实现原理,希望能够对开发者有实际的帮助价值! 第一种翻页效果如下:     实现原理: 当前手指触摸点为a,则 a点坐标为(ax,ay), ...

随机推荐

  1. js 30Dom应用

    1.open() 方法用于打开一个新的浏览器窗口或查找一个已命名的窗口. 给open传网址 如果是外站就加个http  <input type="button" value= ...

  2. 独立使用Asp.net Core 的razor模板 (一):Razor引擎的一些细节

    由于最近需要写一些界面稍微好看点的Winform程序,如果用原生控件,,想要达到好看的程度,需要花费比较大的功夫,因为之前使用过CefSharp,因此发觉如果是使用CEF+Html的方式,界面可以相对 ...

  3. Android中的Application类在应用程序中的应用

    Application类 每次应用程序运行时,应用程序的Application类都保持实例化状态(都会持有该Application实例).与Activity不同的是,配置改变并不会导致应用程序重启.在 ...

  4. Asia-Tsukuba 2017

    A. Secret of Chocolate Poles DP,$f[i][j]$表示高度为$i$,顶层颜色为$j$的方案数. 时间复杂度$O(l)$. #include<cstdio> ...

  5. Linux内核笔记:epoll实现原理(一)

    一.说明 针对的内核版本为4.4.10. 本文只是我自己看源码的简单笔记,如果想了解epoll的实现,强烈推荐下面的文章: The Implementation of epoll(1) The Imp ...

  6. 总结-Linux

    linux基本操作 系统设置 创建用户 useradd -d /home/liaolongjun -m liaolongjun 设置密码 passwd liaolongjun 查看主机名 uname ...

  7. 换目标啦,初识PHP

    一.初识PHP脚步程序 1.PHP开始标记 <?php 2.PHP结束标记 ?> <?php?> 3.我们的页面最终是通过html,css,js来展示出一个炫丽的界面 4.PH ...

  8. DjangoRestFramework 学习之restful规范 APIview 解析器组件 Postman等

    DjangoRestFramework学习一之restful规范.APIview.解析器组件.Postman等 本节目录 一 预备知识 二 restful规范 三 DRF的APIView和解析器组件 ...

  9. 微信小程序调用高德地图

    index.wxml: longitude:经度 latitude:维度 地图所定位的区域 index.js 地图所定位的点

  10. Sybase IQ 的基础

    Sybase IQ 的基础   Sybase IQ的一些基础总结: 1.IQ跟其它的关系型数据库相比,它的主要特征是:查询快.数据压缩比高.Load快,但是插入更新慢,不太适应数据老是变化,它是按列存 ...