在开发中其实不论前台、后台都会留一些后门,方便管理人员操作(有点超级权限的意思),但是这样的入口我们又不能让用户直接看到,所以就有一些芝麻开门的操作 ~
今天真是个好日子啊 – 2020.5.20, 计划终究还是赶不上变化 ~
后门效果
长按监听 (原生版)
Android系统自带的一种长按监听,长按时间差不多在0.5秒-1.5秒左右,如果入口想做的深一点,其实不必考虑这种,因为有的用户可能无意就会触发到 ~ 同时不太利于扩展,例如领导说做个5秒响应,那就凉凉了~
当然 – 如果说要求没有那么严格,那么可以直接使用这种方式,毕竟系统自带,分秒实现 ~
findViewById(R.id.btn_1).setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Toast.makeText(MainActivity.this, "触发:隐藏入口", Toast.LENGTH_LONG).show();
return true;
}
});
长按时长监听(乞丐版)
此种方式主要利用了Android中onTouch机制,在手指Down的时候记录当前时间,UP的时候计算时间差 ~
但是有一些瑕疵,因为你要一直不抬起手指的话,岂不是一直进不去隐藏入口 …
Long startTime;
Long endTime;
findViewById(R.id.btn_2).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//记录起始时间
startTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_UP:
//获取手指抬起时间,然后计算按压操作的时间差
endTime = System.currentTimeMillis();
if (endTime - startTime > 3 * 1000) {
Log.e("tag", "触发:隐藏入口");
Toast.makeText(MainActivity.this, "触发:隐藏入口", Toast.LENGTH_LONG).show();
} else {
Log.e("tag", "未超过5秒");
Toast.makeText(MainActivity.this, "未超过5秒", Toast.LENGTH_LONG).show();
}
break;
default:
break;
}
return true;
}
});
长按时长监听(主推:土豪版)
起初我想着通过onTouch的Down事件记录时间和按压状态,开启计时器,当满足条件则开启入口,同时UP的时候判断是时间差,取消计时器,看是否满足开启入口条件,但是果断使用TimerTask 后如果第二次去创建调用schedule会报错 ~ 一时间想不到什么好的方式去处理,就直接搜索到了成型的方法 … 当然也是通过OnTouch这种方式执行的 ~ 但是有Handler的使用哈 ~
以下方法,早已流传多时,使用也确实没什么问题
长按时长监听
LongClickUtils(此类可直接copy)
package nk.com.hideentrance;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
/** * @author MrLiu * @date 2020/5/20 * desc */
public class LongClickUtils {
private static final String TAG = "LongClickUtils";
/** * @param handler 外界handler(为了减少handler的泛滥使用,最好全局传handler引用,如果没有就直接传 new Handler()) * @param longClickView 被长按的视图(任意控件) * @param delayMillis 长按时间,毫秒 * @param longClickListener 长按回调的返回事件 */
public static void setLongClick(final Handler handler, final View longClickView, final long delayMillis, final View.OnLongClickListener longClickListener) {
longClickView.setOnTouchListener(new View.OnTouchListener() {
private int TOUCH_MAX = 50;
private int mLastMotionX;
private int mLastMotionY;
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 每次按下重新计时
// 按下前,先移除 已有的Runnable回调,防止用户多次单击导致多次回调长按事件的bug
handler.removeCallbacks(r);
mLastMotionX = x;
mLastMotionY = y;
// 按下时,开始计时
handler.postDelayed(r, delayMillis);
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(mLastMotionX - x) > TOUCH_MAX || Math.abs(mLastMotionY - y) > TOUCH_MAX) {
// 移动误差阈值
// xy方向判断
// 移动超过阈值,则表示移动了,就不是长按(看需求),移除 已有的Runnable回调
handler.removeCallbacks(r);
}
break;
case MotionEvent.ACTION_UP:
// 抬起时,移除已有Runnable回调,抬起就算长按了(不需要考虑用户是否长按了超过预设的时间)
handler.removeCallbacks(r);
break;
}
//onclick等其他事件不能用请改这里
return true;
}
private Runnable r = new Runnable() {
@Override
public void run() {
// 回调给用户,用户可能传null,需要判断null
if (longClickListener != null) {
longClickListener.onLongClick(longClickView);
}
}
};
});
}
}
使用方式
LongClickUtils.setLongClick(new Handler(), view, 3000, new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Toast.makeText(MainActivity.this, "触发:隐藏入口", Toast.LENGTH_LONG).show();
return true;
}
});
规定时间,点击次数(主推:土豪版)
这份功能代码其实网上早就有了,主要是在一个时间差内记录用户的点击次数是否达标,如果满足条件即出发入口,反之重置时间与次数 ~
//临时时间
private long mTempTime;
//点击次数
private int mClickNum;
/*规定时间内:点击次数的方式*/
findViewById(R.id.btn_3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
long time = System.currentTimeMillis();
//第一次点击隐藏入口,保存临时时间
if (mTempTime == 0) {
mTempTime = time;
} else {
//这里设置两秒的超时时间,如果超过两秒,重置状态
if (time - mTempTime > 2000) {
//给临时时间和点击次数进行初始化
mTempTime = time;
mClickNum = 0;
return;
}
mClickNum++;
mTempTime = time;
//因为一次点击走if语句,这里可以设置对应的点击次数,但是最少也要2次,不然用这个没有意义,mClickNum == 连续点击数-1
if (mClickNum == 4) {
Toast.makeText(MainActivity.this, "连续点击五次", Toast.LENGTH_SHORT).show();
//给临时时间和点击次数进行初始化
mTempTime = 0;
mClickNum = 0;
}
}
}
});
基于实践 – Demo
监听方式
LongClickUtils(针对时长监听,此类可直接copy)
package nk.com.hideentrance;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
/** * @author MrLiu * @date 2020/5/20 * desc */
public class LongClickUtils {
private static final String TAG = "LongClickUtils";
/** * @param handler 外界handler(为了减少handler的泛滥使用,最好全局传handler引用,如果没有就直接传 new Handler()) * @param longClickView 被长按的视图(任意控件) * @param delayMillis 长按时间,毫秒 * @param longClickListener 长按回调的返回事件 */
public static void setLongClick(final Handler handler, final View longClickView, final long delayMillis, final View.OnLongClickListener longClickListener) {
longClickView.setOnTouchListener(new View.OnTouchListener() {
private int TOUCH_MAX = 50;
private int mLastMotionX;
private int mLastMotionY;
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 每次按下重新计时
// 按下前,先移除 已有的Runnable回调,防止用户多次单击导致多次回调长按事件的bug
handler.removeCallbacks(r);
mLastMotionX = x;
mLastMotionY = y;
// 按下时,开始计时
handler.postDelayed(r, delayMillis);
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(mLastMotionX - x) > TOUCH_MAX || Math.abs(mLastMotionY - y) > TOUCH_MAX) {
// 移动误差阈值
// xy方向判断
// 移动超过阈值,则表示移动了,就不是长按(看需求),移除 已有的Runnable回调
handler.removeCallbacks(r);
}
break;
case MotionEvent.ACTION_UP:
// 抬起时,移除已有Runnable回调,抬起就算长按了(不需要考虑用户是否长按了超过预设的时间)
handler.removeCallbacks(r);
break;
}
//onclick等其他事件不能用请改这里
return true;
}
private Runnable r = new Runnable() {
@Override
public void run() {
// 回调给用户,用户可能传null,需要判断null
if (longClickListener != null) {
longClickListener.onLongClick(longClickView);
}
}
};
});
}
}
MainActivity
package nk.com.hideentrance;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
//Down按下时间
Long startTime;
//UP抬起时间
Long endTime;
//临时时间
private long mTempTime;
//点击次数
private int mClickNum;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/** *长按监听 (原生版) */
findViewById(R.id.btn_1).setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Toast.makeText(MainActivity.this, "触发:隐藏入口", Toast.LENGTH_LONG).show();
return true;
}
});
/** *长按时长监听(乞丐版) */
findViewById(R.id.btn_2).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startTime = System.currentTimeMillis();
Log.e("tag", "startTime:" + startTime);
break;
case MotionEvent.ACTION_UP:
endTime = System.currentTimeMillis();
Log.e("tag", "开始:" + startTime);
Log.e("tag", "结束:" + endTime);
if (endTime - startTime > 3 * 1000) {
Log.e("tag", "触发:隐藏入口");
Toast.makeText(MainActivity.this, "触发:隐藏入口", Toast.LENGTH_LONG).show();
} else {
Log.e("tag", "未超过5秒");
Toast.makeText(MainActivity.this, "未超过5秒", Toast.LENGTH_LONG).show();
}
break;
default:
break;
}
return true;
}
});
/** *长按时长监听(主推:土豪版) */
LongClickUtils.setLongClick(new Handler(), findViewById(R.id.btn_3), 3000, new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Toast.makeText(MainActivity.this, "触发:隐藏入口", Toast.LENGTH_LONG).show();
return true;
}
});
/** *规定时间,点击次数(主推:土豪版) */
findViewById(R.id.btn_4).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
long time = System.currentTimeMillis();
//第一次点击隐藏入口,保存临时时间
if (mTempTime == 0) {
mTempTime = time;
} else {
//这里设置两秒的超时时间,如果超过两秒,重置状态
if (time - mTempTime > 2000) {
//给临时时间和点击次数进行初始化
mTempTime = time;
mClickNum = 0;
return;
}
mClickNum++;
mTempTime = time;
//因为一次点击走if语句
if (mClickNum == 4) {
Toast.makeText(MainActivity.this, "已连续点击五次 - 触发:隐藏入口", Toast.LENGTH_SHORT).show();
//给临时时间和点击次数进行初始化
mTempTime = 0;
mClickNum = 0;
}
}
}
});
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<TextView android:id="@+id/btn_1" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="长按监听 (原生版) - 隐藏入口" />
<View android:layout_width="match_parent" android:layout_height="1dp" android:background="#fb5" />
<TextView android:id="@+id/btn_2" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="长按时长监听(乞丐版) - 隐藏入口" />
<View android:layout_width="match_parent" android:layout_height="1dp" android:background="#fb5" />
<TextView android:id="@+id/btn_3" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="长按时长监听(主推:土豪版) - 隐藏入口" />
<View android:layout_width="match_parent" android:layout_height="1dp" android:background="#fb5" />
<TextView android:id="@+id/btn_4" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="规定时间,点击次数(主推:土豪版) - 隐藏入口" />
</LinearLayout>
今天的文章Android进阶之路 – 隐藏入口分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/31599.html