**1.概述 **

点击效果==》

短视频抖音*App非常火 ,视频点击效果红心效果也不错。其实不难就是一些动画效果的结合使用,这里将具体一步一步实现。使用简单,欢迎前往github。

老规矩,先看女神效果图:

19032eac7a9c

douyin.gif

2.效果分析

2.1:首先是构建一张红心图片 new ImageView(mContext);

2.2:设置红心图片X与Y坐标位置

2.2:添加属性动画效果集,包含缩放、透明度、旋转、向上平移(按一定顺序重复)

3.代码实现

3.1、自定义布局,我这里重写RelativeLayout

3.2、自定义属性attrs.xml

19032eac7a9c

image.gif

//自定义属性 宽、高、图片

TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.HeartLayout);

mWidth=typedArray.getInteger(R.styleable.HeartLayout_heart_width,mWidth);

mHeight=typedArray.getInteger(R.styleable.HeartLayout_heart_height,mHeight);

image_resId=typedArray.getResourceId(R.styleable.HeartLayout_heart_image_resId,image_resId);

19032eac7a9c

image.gif

3.3、创建ImageView,并设置坐标

** 默认图片或者自定义**

ImageView imageView=new ImageView(mContext);

imageView.setImageResource(image_resId);

19032eac7a9c

image.gif

因为**图片位置在手指正上方**,所以得到触摸坐标后进行左移动自身宽度一半,向上移动自身高度。

RelativeLayout.LayoutParams layoutParams=new RelativeLayout.LayoutParams(mWidth, mHeight);

int xLeft=(int)event.getX()- mWidth/2;

int yTop=(int)event.getY() - mHeight;

layoutParams.setMargins(xLeft,yTop,0,0);

imageView.setLayoutParams(layoutParams);

19032eac7a9c

image.gif

3.4、动画效果ObjectAnimator

通过属性动画ObjectAnimator进行缩放、旋转、渐变透明度、平移等操作ImageView心图片。

3.5、RedHeartLayout自定义布局的整体代码

/**

* 仿抖音红心效果

*/

public class RedHeartLayout extends RelativeLayout {

private Context mContext;

private float[] mRandomAngle = {-25, -15, 0, 15, 25};//随机心形图片角度

private int image_resId=R.drawable.ic_heart;//默认图片

private int mWidth=120; //默认图片宽

private int mHeight=120;//默认图片高

/**

* new 使用

* @param context

*/

public RedHeartLayout(Context context) {

super(context);

initView(context);

}

/**

* 当有style自定义样式时候 使用

* @param context

* @param attrs

* @param defStyleAttr

*/

public RedHeartLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initView(context);

}

/**

* 布局使用

* @param context

* @param attrs

*/

public RedHeartLayout(Context context, AttributeSet attrs) {

super(context, attrs);

//自定义属性 宽、高、图片

TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.HeartLayout);

mWidth=typedArray.getInteger(R.styleable.HeartLayout_heart_width,mWidth);

mHeight=typedArray.getInteger(R.styleable.HeartLayout_heart_height,mHeight);

image_resId=typedArray.getResourceId(R.styleable.HeartLayout_heart_image_resId,image_resId);

initView(context);

}

/**

* 将宽高dp转化为px

* @param context

*/

private void initView(Context context) {

this.mContext = context;

this.mHeight=dip2px(mContext,mHeight);

this.mWidth=dip2px(mContext,mWidth);

}

/**

* 触摸事件处理

* @param event

* @return

*/

@Override

public boolean onTouchEvent(MotionEvent event) {

//第一步,创建心形ImageView

final ImageView imageView=new ImageView(mContext);

imageView.setImageResource(image_resId);

RelativeLayout.LayoutParams layoutParams=new RelativeLayout.LayoutParams(mWidth, mHeight);

int xLeft=(int)event.getX()- mWidth/2;

int yTop=(int)event.getY() - mHeight;

layoutParams.setMargins(xLeft,yTop,0,0);

imageView.setLayoutParams(layoutParams);

addView(imageView);

//第二步,添加动画效果集

AnimatorSet animatorSet = new AnimatorSet();

//缩放动画,X轴2倍缩小至0.9倍

animatorSet.play(scaleXY(imageView, "scaleX", 2f, 0.9f, 100, 0))

//缩放动画 , Y轴2倍缩小至0.9倍

.with(scaleXY(imageView, "scaleY", 2f, 0.9f, 100, 0))

//旋转动画 , 随机旋转角度

.with(rotation(imageView, 0, 0))

//透明度动画 , 透明度从0-1

.with(alpha(imageView, 0, 1, 100, 0))

//缩放动画 , X轴0.9倍缩小至1倍

.with(scaleXY(imageView, "scaleX", 0.9f, 1, 50, 150))

//缩放动画 , Y轴0.9倍缩小至1倍

.with(scaleXY(imageView, "scaleY", 0.9f, 1, 50, 150))

//平移动画 , Y轴从0向上移动700单位

.with(translationY(imageView, "translationY", 0, -700, 800, 400))

//透明度动画 , 透明度从1-0

.with(alpha(imageView, 1, 0, 400, 400))

//缩放动画 , X轴1倍放大至3倍

.with(scaleXY(imageView, "scaleX", 1, 3f, 800, 400))

//缩放动画 , Y轴1倍放大至3倍

.with(scaleXY(imageView, "scaleY", 1, 3f, 800, 400));

animatorSet.start();

//动画移除

animatorSet.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

super.onAnimationEnd(animation);

removeViewInLayout(imageView);

}

});

return super.onTouchEvent(event);

}

/**

* X轴或Y轴 缩放

* @param view

* @param propertyName

* @param from

* @param to

* @param time

* @param delayTime

* @return

*/

public ObjectAnimator scaleXY(View view, String propertyName, float from, float to, long time, long delayTime) {

ObjectAnimator _scaleXY= ObjectAnimator.ofFloat(view,propertyName,from,to);

设置插值器为 匀速(补充:有加速、先加后减等)

_scaleXY.setInterpolator(new LinearInterpolator());

//设置开始前延迟

_scaleXY.setStartDelay(delayTime);

//设置动画持续时间

_scaleXY.setDuration(time);

_scaleXY.start();

return _scaleXY;

}

/**

* X轴或Y轴 平移

* @param view

* @param from

* @param to

* @param time

* @param delayTime

* @return

*/

public ObjectAnimator translationY(View view, String propertyName,float from, float to, long time, long delayTime) {

ObjectAnimator translation = ObjectAnimator.ofFloat(view, propertyName, from, to);

translation.setInterpolator(new LinearInterpolator());

translation.setStartDelay(delayTime);

translation.setDuration(time);

return translation;

}

/**

* 透明化处理

* @param view

* @param from

* @param to

* @param time

* @param delayTime

* @return

*/

public ObjectAnimator alpha(View view, float from, float to, long time, long delayTime) {

ObjectAnimator alpha = ObjectAnimator.ofFloat(view, "alpha", from, to);

alpha.setInterpolator(new LinearInterpolator());

alpha.setStartDelay(delayTime);

alpha.setDuration(time);

return alpha;

}

/**

* 旋转

* @param view

* @param time

* @param delayTime

* @return

*/

public ObjectAnimator rotation(View view, long time, long delayTime) {

//随机旋转角度

float angle= mRandomAngle[new Random().nextInt(4)];

ObjectAnimator rotation = ObjectAnimator.ofFloat(view, "rotation", angle);

rotation.setDuration(time);

rotation.setStartDelay(delayTime);

rotation.setInterpolator(new TimeInterpolator() {

@Override

public float getInterpolation(float input) {

//抖动系数越小幅度越大 0-1

return input;

}

});

return rotation;

}

/**

* 根据手机的分辨率从 dp 的单位 转成为 px(像素)

*/

public int dip2px(Context context, float dpValue) {

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (dpValue * scale + 0.5f);

}

}

19032eac7a9c

image.gif

4、布局使用

4.1、使用默认配置(推荐直接使用)

android:layout_width="match_parent"

android:layout_height="match_parent"/>

19032eac7a9c

image.gif

4.2、自定义宽、高、引入其他图片作为效果

android:layout_width="match_parent"

android:layout_height="match_parent"

app:heart_image_resId="@drawable/ic_heart"

app:heart_width="120"

app:heart_height="120" />

19032eac7a9c

image.gif

5、Demo地址github**

觉得还行的老铁,双击66。源码地址欢迎前往

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐