【问题标题】: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;
          });
      

      【讨论】:

        【解决方案3】:

        我会选择 OOP。

        1. 创建一个扩展 Button 的类。在这个类中覆盖 onClick 监听器并在那里做任何你需要做的事情。这个 SO 似乎很有帮助Creating custom control with overriding onclick
        2. 将 layouts.xml 中的所有内容替换为

        重复其他类型的控件。

        一般来说,为您将使用的所有元素创建基类并不是一个坏主意,因为这样的事情总是会出现。

        【讨论】:

          【解决方案4】:

          要跟踪所有可点击的视图,请使用此方法:

          1. 为点击事件创建接口

             package com.gethello.interfaces;
            
             import android.view.View;
            
             public interface OnItemClickInterfaceTesting {
            
                void onItemClick(View view,int id);
            
            
             }
            
          2. 在 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);
          
                      }
                  });
              }
          1. 在你的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;
            
             }
            }
            
          2. 像这样在 onCreate 中调用方法:

            setClickListener(this,ViewName,R.id.id_of_view);

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-09-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-30
            • 2021-09-16
            • 1970-01-01
            相关资源
            最近更新 更多