android 笔记:Android 开发仿映客送礼物效果,这篇文章主要介绍了 Android 开发仿映客送礼物效果的实现代码,本文介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起学习吧。
这里写链接内容仿映客送小礼物的特效,顺便复习一下属性动画,话不多说先看效果图。
需求分析
可以看到整个动画有几部分组成,那我们就把每个部分拆分出来各个击破。
1. 要显示那些内容以及内容间的位置关系?
可以看到我们要显示用户头像,昵称,礼物图标以及数量。所以这里我选择用 FrameLayout 来作为根布局。
2. 需要哪些动画以及动画的执行顺序?
a. 首先是整体从左到右飞入并有一个回弹(translationX + OvershootInterpolatZ 喎?/kf/ware/vc/"target="_blank"class="keylink">vcqOpPGJyIC8+DQpiLsi7uvPKx8Dxzu+009fztb3T0rfJyOu2+MfSysfSu7j2tPi89cvZ0Ke5+7XEo6h0cmFuc2xhdGlvblggKyBEZWNlbGVyYXRlSW50ZXJwb2xhdG9yo6k8YnIgLz4NCmMuwPHO78r9wb/SwLTOwNu8082syrGw6cvm18XL9bfFo6hzY2FsZStyZXBlYXSjqTxiciAvPg0KZC6688PmtcTBo9fT0Ke5+6Oo1qG2r7uto6k8YnIgLz4NCmUu1fvM5c/yyc/GvdLGsqLH0tbwvaXP+8qno6h0cmFuc2xhdGlvblkgKyBhbHBoYaOpPGJyIC8+DQozLsvNwPG1xMf40/LT0MG9v+mjqEGjrEKjqaOsyOe6zrfWxeSjvzxiciAvPg0K0vLOqtPDu6fLzcDxtcTK/cG/sru5zLaoo6zL+dLUtq+7rbPW0Pi1xMqxvOTSsrK70ru2qKGjtavKx87Sw8fPo8371eLBvb/px/jT8sTctcO1vbPkt9a1xMq508OjrLy0ztLDx9Do0qrSu7j2ttPB0LTmt8XV4tCpwPHO78q1wP2jrEG6zULLrb/Vz9CjrL7Nt9bF5Lj4y620psDtoaM8YnIgLz4NCjQu0tTJz8v509DE2sjdyse38cq508PUrcn6tcS/1bzkvs3E3Mq1z9ajvzxiciAvPg0K1f3I58nPw+a1xLfWzvajrM7Sw8fT0MqxstnX99X7zOWjrNPQyrGy2df3vtayv6Gj1eLKsc7Sw8fX7rrDxNzX1Lao0uXSu7j2sry+1rzMs9BGcmFtZUxheW91dKOsxuTKtdKyvs3Kx7fi17DSu7Ljo6zV4tH5ztLDx77Nv8nS1LrcusO1xL/Y1sbV+7j2sry+1qGjs/20y9auzeKjrLu509DO0sPH16LS4rW9wPHO78r9wb/Kx7T4w+ix37XEo6zDssvG0OjSqs7Sw8fX1Lao0uXKtc/WwcuhozxiciAvPg0KuabE3Mq1z9Y8YnIgLz4NCtDox/O31s72zerBy6OsvdPPwsC0ztLDx8u1y7W5psTctcTKtc/WoaM8YnIgLz4NCsrXz8jAtLTyztLDx7XE1fvM5bK8vtahozwvcD4NCjxwcmUgY2xhc3M9"brush:java;">
这里比较简单不多说了,重点看下 StrokeTextView,带描边的 textview,其实就是重写了 ondraw 方法先绘制外层,在绘制内层。
- @Overrideprotected void onDraw(Canvas canvas) {
- if (m_bDrawSideLine) { // 描外层setTextColorUseReflection(mOuterColor);m_TextPaint.setStrokeWidth(5);m_TextPaint.setStyle(Paint.Style.FILL_AND_STROKE);super.onDraw(canvas);// 描内层,恢复原先的画笔setTextColorUseReflection(mInnerColor);m_TextPaint.setStrokeWidth(0);m_TextPaint.setStyle(Paint.Style.FILL_AND_STROKE);}super.onDraw(canvas);}/*** 使用反射的方法进行字体颜色的设置* @param color*/private void setTextColorUseReflection(int color) {Field textColorField;try {textColorField = TextView.class.getDeclaredField("mCurTextColor");textColorField.setAccessible(true);textColorField.set(this, color);textColorField.setAccessible(false);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}m_TextPaint.setColor(color);}
定义礼物的实体类
- public class GiftSendModel {
- private int giftCount;
- private String userAvatarRes;
- private String nickname;
- private String sig;
- private int giftRes;
- private String gift_id;
- private int star;
- public GiftSendModel(int giftCount) {
- this.giftCount = giftCount;
- }
- public int getGiftCount() {
- return giftCount;
- }
- public void setGiftCount(int giftCount) {
- this.giftCount = giftCount;
- }......
封装整体布局
- public class GiftFrameLayout extends FrameLayout {
- private LayoutInflater mInflater;
- RelativeLayout anim_rl;
- ImageView anim_gift,
- anim_light,
- anim_header;
- TextView anim_nickname,
- anim_sign;
- StrokeTextView anim_num;
- /*** 礼物数量的起始值*/
- int starNum = 1;
- int repeatCount = 0;
- private boolean isShowing = false;
- public GiftFrameLayout(Context context) {
- this(context, null);
- }
- public GiftFrameLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- mInflater = LayoutInflater.from(context);
- initView();
- }
- private void initView() {
- View view = mInflater.inflate(R.layout.animation, this, false);
- anim_rl = (RelativeLayout) view.findViewById(R.id.animation_person_rl);
- anim_gift = (ImageView) view.findViewById(R.id.animation_gift);
- anim_light = (ImageView) view.findViewById(R.id.animation_light);
- anim_num = (StrokeTextView) view.findViewById(R.id.animation_num);
- anim_header = (ImageView) view.findViewById(R.id.gift_userheader_iv);
- anim_nickname = (TextView) view.findViewById(R.id.gift_usernickname_tv);
- anim_sign = (TextView) view.findViewById(R.id.gift_usersign_tv);
- this.addView(view);
- }
- public void hideView() {
- anim_gift.setVisibility(INVISIBLE);
- anim_light.setVisibility(INVISIBLE);
- anim_num.setVisibility(INVISIBLE);
- }
- public void setModel(GiftSendModel model) {
- if (0 != model.getGiftCount()) {
- this.repeatCount = model.getGiftCount();
- }
- if (!TextUtils.isEmpty(model.getNickname())) {
- anim_nickname.setText(model.getNickname());
- }
- if (!TextUtils.isEmpty(model.getSig())) {
- anim_sign.setText(model.getSig());
- }
- }
- public boolean isShowing() {
- return isShowing;
- }
- public AnimatorSet startAnimation(final int repeatCount) {
- hideView(); //布局飞入ObjectAnimator flyFromLtoR = GiftAnimationUtil.createFlyFromLtoR(anim_rl, -getWidth(), 0, 400,new OvershootInterpolator());flyFromLtoR.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationStart(Animator animation) {super.onAnimationStart(animation);GiftFrameLayout.this.setVisibility(View.VISIBLE);GiftFrameLayout.this.setAlpha(1f);isShowing = true;anim_num.setText("x " + 1);Log.i("TAG", "flyFromLtoR A start");}});//礼物飞入ObjectAnimator flyFromLtoR2 = GiftAnimationUtil.createFlyFromLtoR(anim_gift, -getWidth(), 0, 400,new DecelerateInterpolator());flyFromLtoR2.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationStart(Animator animation) {anim_gift.setVisibility(View.VISIBLE);}@Overridepublic void onAnimationEnd(Animator animation) {GiftAnimationUtil.startAnimationDrawable(anim_light);anim_num.setVisibility(View.VISIBLE);}});//数量增加ObjectAnimator scaleGiftNum = GiftAnimationUtil.scaleGiftNum(anim_num, repeatCount);scaleGiftNum.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationRepeat(Animator animation) {anim_num.setText("x " + (++starNum));}});//向上渐变消失ObjectAnimator fadeAnimator = GiftAnimationUtil.createFadeAnimator(GiftFrameLayout.this, 0, -100, 300, 400);fadeAnimator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {GiftFrameLayout.this.setVisibility(View.INVISIBLE);}});// 复原ObjectAnimator fadeAnimator2 = GiftAnimationUtil.createFadeAnimator(GiftFrameLayout.this, 100, 0, 20, 0);AnimatorSet animatorSet = GiftAnimationUtil.startAnimation(flyFromLtoR, flyFromLtoR2, scaleGiftNum, fadeAnimator, fadeAnimator2);animatorSet.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {starNum = 1;isShowing = false;}});return animatorSet;
我们将所有的动画方法都写到了 GiftAnimationUtil 中便于管理
- public class GiftAnimationUtil {
- /*** @param target* @param star 动画起始坐标* @param end 动画终止坐标* @param duration 持续时间* @return* 创建一个从左到右的飞入动画* 礼物飞入动画*/
- public static ObjectAnimator createFlyFromLtoR(final View target, float star, float end, int duration, TimeInterpolator interpolator) { //1.个人信息先飞出来ObjectAnimator anim1 = ObjectAnimator.ofFloat(target, "translationX",star, end);anim1.setInterpolator(interpolator);anim1.setDuration(duration);return anim1;}/*** @param target* @return* 播放帧动画*/public static AnimationDrawable startAnimationDrawable(ImageView target){AnimationDrawable animationDrawable = (AnimationDrawable) target.getDrawable();if(animationDrawable!=null) {target.setVisibility(View.VISIBLE);animationDrawable.start();}return animationDrawable;}/*** @param target* @param drawable* 设置帧动画*/public static void setAnimationDrawable(ImageView target, AnimationDrawable drawable){target.setBackground(drawable);}/*** @param target* @param num* @return* 送礼数字变化*/public static ObjectAnimator scaleGiftNum(final TextView target , int num){PropertyValuesHolder anim4 = PropertyValuesHolder.ofFloat("scaleX",1.7f, 0.8f,1f);PropertyValuesHolder anim5 = PropertyValuesHolder.ofFloat("scaleY",1.7f, 0.8f,1f);PropertyValuesHolder anim6 = PropertyValuesHolder.ofFloat("alpha",1.0f, 0f,1f);ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(target, anim4, anim5, anim6).setDuration(480);animator.setRepeatCount(num);return animator;}/*** @param target* @param star* @param end* @param duration* @param startDelay* @return* 向上飞 淡出*/public static ObjectAnimator createFadeAnimator(final View target, float star, float end, int duration, int startDelay){PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", star,end);PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f,0f);ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(target, translationY, alpha);animator.setStartDelay(startDelay);animator.setDuration(duration);return animator;}/*** @param animators* @return* 按顺序播放动画*/public static AnimatorSet startAnimation(ObjectAnimator animator1, ObjectAnimator animator2, ObjectAnimator animator3, ObjectAnimator animator4, ObjectAnimator animator5){AnimatorSet animSet = new AnimatorSet();// animSet.playSequentially(animators);animSet.play(animator1).before(animator2);animSet.play(animator3).after(animator2);animSet.play(animator4).after(animator3);animSet.play(animator5).after(animator4);animSet.start();return animSet;}}
所有的动画效果均是用属性动画完成,其中不仅有单个的动画,还有组合动画。属性动画用起来方面而且功能十分强大!
最后看下 MainActivity 中的实现
- public class MainActivity extends AppCompatActivity {
- private GiftFrameLayout giftFrameLayout1;
- private GiftFrameLayout giftFrameLayout2;
- List giftSendModelList = new ArrayList();@Overrideprotected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- giftFrameLayout1 = (GiftFrameLayout) findViewById(R.id.gift_layout1);
- giftFrameLayout2 = (GiftFrameLayout) findViewById(R.id.gift_layout2);
- findViewById(R.id.action).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {
- starGiftAnimation(createGiftSendModel());
- }
- });
- }
- private GiftSendModel createGiftSendModel() {
- return new GiftSendModel((int)(Math.random() * 10));
- }
- private void starGiftAnimation(GiftSendModel model) {
- if (!giftFrameLayout1.isShowing()) {
- sendGiftAnimation(giftFrameLayout1, model);
- } else if (!giftFrameLayout2.isShowing()) {
- sendGiftAnimation(giftFrameLayout2, model);
- } else {
- giftSendModelList.add(model);
- }
- }
- private void sendGiftAnimation(final GiftFrameLayout view, GiftSendModel model) {
- view.setModel(model);
- AnimatorSet animatorSet = view.startAnimation(model.getGiftCount());
- animatorSet.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- synchronized(giftSendModelList) {
- if (giftSendModelList.size() > 0) {
- view.startAnimation(giftSendModelList.get(giftSendModelList.size() - 1).getGiftCount());
- giftSendModelList.remove(giftSendModelList.size() - 1);
- }
- }
- }
- });
- }@Overridepublic boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.menu_main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();//noinspection SimplifiableIfStatementif (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}}
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/03-17/18933632.html