【问题标题】:How to track every reasonable click in android app?如何跟踪android应用程序中的每一次合理点击?
【发布时间】:2021-03-22 15:25:15
【问题描述】:
每次用户点击我应用中的任何可点击视图时,我都需要跟踪一个事件。我一般想这样做,例如在我的主要活动中。
我知道我可以覆盖 onUserInteraction() 或 dispatchTouchEvent() 但即使对于不可点击视图的点击,它们也会运行。
我不需要区分可点击视图,只要它是可点击的就足够了。
在理想情况下,我还会将向上按钮与其他点击区分开来。
这可能吗?
【问题讨论】:
标签:
android
android-activity
touch-event
【解决方案1】:
在我看来,你想要实现的目标没有完美的实现。
一种可能的方法是使用 OnClickListener 包装器。这需要您或您的团队在任何可点击视图的 OnClickListener 上强制使用此包装器。但是你不能覆盖第三方库中的视图。
public class OnClickListenerWrapper implements OnClickListener {
private OnClickListener listener
public OnClickListenerWrapper (OnClickListener listener) {
this.listener = listener;
}
public void onClick(View view) {
// Logic of tracking
listener.onClick(view);
}
}
【解决方案2】:
问题
跟踪应用中任何可点击的View 上发生的任何点击。
可能的解决方案
此解决方案有点繁重,需要您遵守一定的纪律(不要将setOnClickListener() 用于其他目的,但要跟踪点击次数)。
将View.OnClickListener 添加到基础Activity 中的任何View 或任何Activity,您希望跟踪点击事件。只有在全局布局完成加载(通过添加OnGlobalLayoutListener)到根视图时才开始执行此操作。因此,代码看起来可能如下所示:
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
View decorView = getWindow().getDecorView();
decorView.getViewTreeObserver().addOnGlobalLayoutListener(() ->
printClickedViews(getWindow().getDecorView())
);
}
private void printClickedViews(View currentView) {
if (currentView == null) {
return;
}
currentView.setOnClickListener(v -> {
Toast.makeText(v.getContext(), "Clicked on " + v.getClass().getSimpleName(),
Toast.LENGTH_LONG).show();
});
if (currentView instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) currentView;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
printClickedViews(viewGroup.getChildAt(i));
}
}
}
...
请注意,即使您添加/删除新的View,您的OnGlobalLayoutListener 也会收到通知,这很好。
限制
最明显的限制是必须保留设置 View.OnClickListener 以仅用于跟踪点击。但是,您始终可以将OnTouchListener 用于以下相同目的:
view.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP) {
// handle your click event here
}
return false;
});
【解决方案4】:
要跟踪所有可点击的视图,请使用此方法:
-
为点击事件创建接口
package com.gethello.interfaces;
import android.view.View;
public interface OnItemClickInterfaceTesting {
void onItemClick(View view,int id);
}
-
在 Base 活动中创建一个方法,以便您可以在每个活动中访问。
public void setClickListener(Context context, View view, int id) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.e("TAG", "Track your click events here");
OnItemClickInterfaceTesting itemController = (OnItemClickInterfaceTesting) context;
itemController.onItemClick(view, id);
}
});
}
-
在你的activity中实现OnItemClickInterfaceTesting和接口方法。
@Override
public void onItemClick(View view, int id) {
switch (id){
case R.id.id_of_your_view:
Log.e(TAG, "Your view clicked. Add your code to handle click of view.");
break;
}
}
-
像这样在 onCreate 中调用方法:
setClickListener(this,ViewName,R.id.id_of_view);