[安卓/Android] 仿微信拍一拍功能实现及代码

主要介绍拍一拍图标的实现以及应用。

注:为了偷懒,圆形ImageView用的是我自己的一个ShapeImageView控件实现的,以及RecyclerView的适配器,

这些都封装在libs下的aar包里边。

底部有传送门 。

视频展示

1.图标抖动

//摆幅动画
private ValueAnimator mValAnim;
//摆幅大小
private float mPatPower = 8;
//摆幅次数
private int mPatCount = 3;
//震动时间
private long[] mVibratorTimings = new long[] { 0, 50, 150, 50 };

public void init() {
    mValAnim = new ValueAnimator();
    //动画更新事件监听器
    mValAnim.addUpdateListener(anim -> {
        float val = (float) anim.getAnimatedValue();
        //左右旋转
        setRotation( val );
        //左右移动
        setTranslationX( val );
    });
}

/**
 * 构建设置
 */
public void build() {
     loat[] val = new float[ ( mPatCount * 2 ) + 1 ];
    for (int i = 0; i < val.length; i++) {
        if( i < val.length - 1 ) {
            //左右摆幅( -5, 5, -5, 5 )
            val[ i ] = i % 2 == 0 ? -mPatPower : mPatPower;
        }else {
            //最后一帧复位
            val[ i ] = 0;
        }
    }
   mValAnim.setFloatValues( val );
}

/**
 * 拍一拍
 */
public void startPat() {
    //拍一拍动画
    mValAnim.start();
    //设置震动
    Utils.startVibrator( getContext(), -1, mVibratorTimings );
}

2.双击

private static long firstTime = 0;

/**
 * 双击操作
 * @param time    间隔时间
 * @param call    回调。false:第一次单击,true:双击
 */
public static void doubleTouch(long time, Consumer<Boolean> call) {
    long secondTime = System.currentTimeMillis();
    if( secondTime - firstTime > time ) {
        firstTime = secondTime;
        //第一次通知
        if( call != null ) call.accept( false );
    } else {
        //第二次通知
        if( call != null ) call.accept( true );
    }
}

3.3D震动

在manifest清单中添加震动权限
<!-- 震动权限 -->
<uses-permission android:name="android.permission.VIBRATE" />

/**
 * 开始震动
 * @param context       上下文
 * @param repeat        循环次数。-1:仅一次
 * @param timings       [0]:震动延迟、[1]:震动时长、[2]:震动延迟、[3]:震动时长...
 */
public static void startVibrator(@NonNull Context context, int repeat, long... timings) {
    Vibrator v = (Vibrator) context.getSystemService( Context.VIBRATOR_SERVICE );
    if( v == null ) return;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        v.vibrate( VibrationEffect.createWaveform( timings, repeat ) );
    }else {
        v.vibrate( timings, repeat );
    }
}

4.拍一拍间隔

//间隔时长
private long mIntervalMillis = 5000;
//当前间隔
private long mCurrentMillis = 0;

/**
 * 间隔检查
 * @return      间隔是否超时
 */
private boolean checkInterval() {
    if( mIntervalMillis <= 0 ) return true;
    //间隔时间初始化
    if( mCurrentMillis == 0 ) mCurrentMillis = System.currentTimeMillis() - mIntervalMillis;
    //在间隔时间内
    if( mCurrentMillis + mIntervalMillis > System.currentTimeMillis() ) {
        return false;
    }
    mCurrentMillis = System.currentTimeMillis();
    return true;
}

Demo传送门:拍一拍Demo

拍一拍控件传送门:PatView

ShapeImageView传送门:ShapeImageView

Adapter传送门:BaseRecyclerViewAdapter

猜你喜欢

转载自blog.csdn.net/u013599928/article/details/106987389