Android仿抖音点击效果
2019-07-27 本文已影响19人
落雨敏
**1.概述 **
点击效果==》
短视频抖音*App非常火 ,视频点击效果红心效果也不错。其实不难就是一些动画效果的结合使用,这里将具体一步一步实现。copy本代码可直接使用。
老规矩,先看女神效果图:
2.效果分析
2.1:首先是构建一张红心图片 new ImageView(mContext);
2.2:设置红心图片X与Y坐标位置
2.2:添加属性动画效果集,包含缩放、透明度、旋转、向上平移(按一定顺序重复)
3.代码实现
3.1、自定义布局,我这里重写RelativeLayout
3.2、自定义属性attrs.xml
<!--attrs文件 属性-->
<declare-styleable name="HeartLayout">
<attr name="heart_width" format="integer" />
<attr name="heart_height" format="integer" />
<attr name="heart_image_resId" format="reference" />
</declare-styleable>
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);
image.gif
3.3、创建ImageView,并设置坐标
** 默认图片或者自定义**
ImageView imageView=new ImageView(mContext);
imageView.setImageResource(image_resId);
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);
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);
}
}
image.gif
4、布局使用
4.1、使用默认配置(推荐直接使用)
<com.lzj.douyin.redheart.library.RedHeartLayout
android:layout_width="match_parent"
android:layout_height="match_parent"/>
image.gif
4.2、自定义宽、高、引入其他图片作为效果
<com.lzj.douyin.redheart.library.RedHeartLayout
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" />
image.gif
5、Demo地址github**
怎么使用:
只需copy, RedHeartLayout文件、自定义属性attrs.xml 即可使用。