自定义点赞效果

1.自定义布局

package com.example.administrator.test;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.TranslateAnimation;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;

/**
 * Created by Administrator on 2018/6/27.
 */

public class MyView extends View implements View.OnClickListener {
        public static final String TAG = "AgreeView";
        //默认动画移动距离
        private static final int DEFAULT_DISTANCE = 60;
        //默认动画起始点
        private static final int DEFAULT_FROM_Y = 0;
        //动画起始点距离
        private static final int DEFAULT_TO_Y = DEFAULT_DISTANCE;
        //动画起始透明度
        private static final float DEFAULT_FROM_ALPHA = 1.0f;
        //动画默认透明度
        private static final float DEFAULT_TO_ALPHA = 0.0f;
        //动画时长
        private static final int DEFAULT_DURATION = 700;
        //默认文字大小
        private static final int DEFAULT_TEXT_SIZE = 16;
        //默认文字颜色
        private static final int DEFAULT_TEXT_COLOR = Color.BLACK;
        //默认 文字
        private static final String DEFAULT_TEXT = "+1";
        //默认点赞图片
        private static final int DEFAULT_IMG = R.drawable.donghua;
        //动画 文字
        private static final int ANIMATION_MODE_TEXT = 0;
        //动画图片
        private static final int ANIMATION_MODE_IMG = 1;

        //默认文字模式动画
        private static final int DEFAULT_ANIMATION_MODE = ANIMATION_MODE_TEXT;


        //移动距离
        private int distance;
        //Y轴起始偏移量
        private int from_y;
        //Y轴移动距离
        private int to_y;
        //起始透明度
        private float from_alpha;
        //结束透明度
        private float to_alpha;
        //动画时长
        private int duration;
        //动画文本
        private String text = "";
        //文本大小
        private int text_size;
        //文本颜色
        private int text_color;
        //动画
        private AppCompatTextView tvAnimation;

        //动画图片
        private Drawable animalDrawable;

        //点赞图片
        private Drawable agreeDrawable;

        private Context mContext;

        private int animationMode;

        /**
         * PopupWindow来显示点击动画
         */
        private PopupWindow mPW;
        /**
         * 动画组合
         */
        private AnimationSet mAnimationSet;
        /**
         * 是否改变了属性
         */
        private boolean isChanged = true;

        private Animation animation;

        public MyView(Context context) {
            super(context);
            mContext = context;
            initView(null);
        }

        public MyView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            mContext = context;
            initView(attrs);
        }

        public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            mContext = context;
            initView(attrs);
        }

        private void initView(AttributeSet attrs) {
            if (attrs != null) {
                TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.MyView);
                distance = typedArray.getInt(R.styleable.MyView_distance, DEFAULT_DISTANCE);
                from_y = typedArray.getInt(R.styleable.MyView_from_y, DEFAULT_FROM_Y);
                to_y = distance;
                from_alpha = typedArray.getFloat(R.styleable.MyView_from_alpha, DEFAULT_FROM_ALPHA);
                to_alpha = typedArray.getFloat(R.styleable.MyView_to_alpha, DEFAULT_TO_ALPHA);
                duration = typedArray.getInt(R.styleable.MyView_duration, DEFAULT_DURATION);
                text = typedArray.getString(R.styleable.MyView_text);
                if (text == null) {
                    text = DEFAULT_TEXT;
                }
                text_size = typedArray.getInt(R.styleable.MyView_text_size, DEFAULT_TEXT_SIZE);
                text_color = typedArray.getColor(R.styleable.MyView_text_color, DEFAULT_TEXT_COLOR);
                animalDrawable = typedArray.getDrawable(R.styleable.MyView_animation_img);
                agreeDrawable = typedArray.getDrawable(R.styleable.MyView_picture);
                animationMode = typedArray.getInt(R.styleable.MyView_animation, ANIMATION_MODE_TEXT);
                if (agreeDrawable == null) {
                    agreeDrawable = ContextCompat.getDrawable(getContext(), R.drawable.donghua);
                }
                //资源释放
                typedArray.recycle();
            }

            //我们将PopupWindow作为动画View
            //初始化我们的PopupWindow
            mPW = new PopupWindow();
            //PopupWindow创建相对布局
            RelativeLayout layout = new RelativeLayout(mContext);
            //布局参数
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            tvAnimation = new AppCompatTextView(mContext);
            tvAnimation.setIncludeFontPadding(false);
            tvAnimation.setTextSize(TypedValue.COMPLEX_UNIT_DIP, text_size);
            tvAnimation.setTextColor(text_color);
            if (animationMode == ANIMATION_MODE_TEXT) {
                tvAnimation.setText(text);
            } else {
                tvAnimation.setText("");
                tvAnimation.setBackgroundDrawable(animalDrawable);
            }
            tvAnimation.setLayoutParams(layoutParams);
            layout.addView(tvAnimation);
            mPW.setContentView(layout);

            //量测我们的动画的宽高
            int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            tvAnimation.measure(w, h);
            mPW.setWidth(tvAnimation.getMeasuredWidth());
            mPW.setHeight(distance + tvAnimation.getMeasuredHeight());
            mPW.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            mPW.setFocusable(false);
            mPW.setTouchable(false);
            mPW.setOutsideTouchable(false);

            this.setOnClickListener(this);

            //设置文字、图片移动动画
            setPopAnimation();
            //点击缩放动画
            setScaleAnimation();

        }

        /**
         * 缩放动画
         */
        private void setScaleAnimation() {
            ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, "scaleX", 1f, 0.8f, 1.2f, 1f);
            ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 1f, 0.8f, 1.2f, 1f);
            scaleX.setDuration(duration);
            scaleY.setDuration(duration);
            scaleX.setInterpolator(new AccelerateDecelerateInterpolator());
            scaleY.setInterpolator(new AccelerateDecelerateInterpolator());
            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.play(scaleX).with(scaleY);
            animatorSet.start();
        }


        @Override
        public void onClick(View v) {
            if (mPW != null && !mPW.isShowing()) {
                int offsetY = -getHeight() - mPW.getHeight();
                mPW.showAsDropDown(this, getWidth() / 2 - mPW.getWidth() / 2, offsetY);
                mPW.update();
                if (mAnimationSet == null) {
                    setPopAnimation();
                }
                tvAnimation.startAnimation(mAnimationSet);
                setScaleAnimation();
                //外部点击事件
                if (clickListener != null) {
                    clickListener.onAgreeClick(v);
                }
            }
        }

        /**
         * 动画组合
         */
        private void setPopAnimation() {
            mAnimationSet = new AnimationSet(true);
            TranslateAnimation translateAnim = new TranslateAnimation(0, 0, from_y, -to_y);
            AlphaAnimation alphaAnim = new AlphaAnimation(from_alpha, to_alpha);
            mAnimationSet.addAnimation(translateAnim);
            mAnimationSet.addAnimation(alphaAnim);
            mAnimationSet.setDuration(duration);
            mAnimationSet.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    if (mPW != null && mPW.isShowing()) {
                        new Handler().post(new Runnable() {
                            @Override
                            public void run() {
                                mPW.dismiss();
                            }
                        });
                    }
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }
            });
        }


        @Override
        protected void onDraw(Canvas canvas) {
            //将我们的Drawable画到画布
            agreeDrawable.draw(canvas);
        }

        /**
         * 量测点击控件的大小
         *
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int width;
            int height;
            int w_mode = MeasureSpec.getMode(widthMeasureSpec);
            int w_size = MeasureSpec.getSize(widthMeasureSpec);

            int h_mode = MeasureSpec.getMode(heightMeasureSpec);
            int h_size = MeasureSpec.getSize(heightMeasureSpec);

            if (w_mode == MeasureSpec.AT_MOST || w_mode == MeasureSpec.UNSPECIFIED) {
                width = agreeDrawable.getIntrinsicWidth();
            } else {
                width = w_size;
            }

            if (h_mode == MeasureSpec.AT_MOST || h_mode == MeasureSpec.UNSPECIFIED) {
                height = agreeDrawable.getIntrinsicHeight();
            } else {
                height = h_size;
            }
            setMeasuredDimension(width, height);

            //根据量测的宽高,设置我们画的Drawable的大小
            @SuppressLint("DrawAllocation")
            Rect rect = new Rect(0, 0, width, height);
            agreeDrawable.setBounds(rect);
        }

        public void setClickListener(MyViewClickListener clickListener) {
            this.clickListener = clickListener;
        }

        private MyViewClickListener clickListener;

        public interface MyViewClickListener {
            void onAgreeClick(View view);
        }

    }
2.资源donghua
 
 
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#c6115f"
        android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
</vector>
3.values中的arrays.xml
 
 
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyView">
        <!--动画颜色-->
        <attr name="text_color" format="color"/>
        <!--点赞图片-->
        <attr name="picture" format="reference"/>
        <!--动画图片-->
        <attr name="animation_img" format="reference"/>
        <!--动画移动最终距离-->
        <attr name="distance" format="integer"/>
        <!--动画起始位置-->
        <attr name="from_y" format="integer"/>
        <!--动画开始透明度-->
        <attr name="from_alpha" format="float"/>
        <!--动画结束透明度-->
        <attr name="to_alpha" format="float"/>
        <!--持续时间-->
        <attr name="duration" format="integer"/>
        <!--动画显示的文字-->
        <attr name="text" format="string"/>
        <!--动画文字大小-->
        <attr name="text_size" format="integer"/>
        <!--动画选择是图片还是文字-->
        <attr name="animation" format="enum">
            <enum name="text" value="0"/>
            <enum name="picture" value="1"/>
        </attr>
    </declare-styleable>
</resources>

4.activity布局
 
 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <com.example.administrator.test.MyView
        android:id="@+id/myview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="208dp"
        android:layout_gravity="center_horizontal"
        view:animation="text"
        view:animation_img="@drawable/donghua"
        view:distance="100"
        view:from_y="60"
        view:text="点赞+1"
        view:text_color="@color/colorAccent">
    </com.example.administrator.test.MyView>



    <android.support.constraint.Group
        android:id="@+id/group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

5.activity
 
 
package com.example.administrator.test;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    private MyView txtAgreeView;
    public static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtAgreeView = findViewById(R.id.myview);
        txtAgreeView.setClickListener(new MyView.MyViewClickListener() {
            @Override
            public void onAgreeClick(View view) {
                Log.e(TAG, "onAgreeClick: " + "IMG");
            }
        });
    }
}

猜你喜欢

转载自blog.csdn.net/ydc0128/article/details/80825385