【问题标题】:Android - setOnClickListener vs OnClickListener vs View.OnClickListenerAndroid - setOnClickListener vs OnClickListener vs View.OnClickListener
【发布时间】:2015-04-06 21:03:36
【问题描述】:

我的理解是,当我创建一个监听点击的按钮对象时,我必须:

  1. 创建按钮对象
  2. 使用OnClickListner让它监听用户的点击
  3. 使用onClick在用户点击按钮后执行动作

现在,

  • setOnClickListener 在哪里符合上述逻辑?
  • 哪个真正听到按钮点击?
  • setOnClickListener?
  • OnClickListener?
  • View.OnClickListener?
  • 这三者之间有什么区别?

这是我在 Android Dev 中找到的:

//The example below shows how to register an on-click listener for a Button.

// Create an anonymous implementation of OnClickListener
private OnClickListener mCorkyListener = new OnClickListener() {
    public void onClick(View v) {
      // do something when the button is clicked
    }
};

protected void onCreate(Bundle savedValues) {
    ...
    // Capture our button from layout
    Button button = (Button)findViewById(R.id.corky);
    // Register the onClick listener with the implementation above
    button.setOnClickListener(mCorkyListener);
    ...
}

您可能还会发现将OnClickListener 作为Activity 的一部分来实现更为方便。这将避免额外的类负载和对象分配。例如:

public class ExampleActivity extends Activity implements OnClickListener {
    protected void onCreate(Bundle savedValues) {
        ...
         Button button = (Button)findViewById(R.id.corky);
         button.setOnClickListener(this);
    }

    // Implement the OnClickListener callback
    public void onClick(View v) {
      // do something when the button is clicked
    }
}

【问题讨论】:

    标签: android onclicklistener


    【解决方案1】:

    假设我们有 3 个按钮

    public class MainActivity extends ActionBarActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
    
            // Capture our button from layout
            Button button = (Button)findViewById(R.id.corky);
            Button button2 = (Button)findViewById(R.id.corky2);
            Button button3 = (Button)findViewById(R.id.corky3);
            // Register the onClick listener with the implementation above
            button.setOnClickListener(mCorkyListener);
            button2.setOnClickListener(mCorkyListener);
            button3.setOnClickListener(mCorkyListener);
    
        }
    
        // Create an anonymous implementation of OnClickListener
        private View.OnClickListener mCorkyListener = new View.OnClickListener() {
            public void onClick(View v) {
                // do something when the button is clicked 
                // Yes we will handle click here but which button clicked??? We don't know
    
            }
        };
    
    }
    

    那我们该怎么办?

    public class MainActivity extends ActionBarActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
    
            // Capture our button from layout
            Button button = (Button)findViewById(R.id.corky);
            Button button2 = (Button)findViewById(R.id.corky2);
            Button button3 = (Button)findViewById(R.id.corky3);
            // Register the onClick listener with the implementation above
            button.setOnClickListener(mCorkyListener);
            button2.setOnClickListener(mCorkyListener);
            button3.setOnClickListener(mCorkyListener);
    
        }
    
        // Create an anonymous implementation of OnClickListener
        private View.OnClickListener mCorkyListener = new View.OnClickListener() {
            public void onClick(View v) {
                // do something when the button is clicked
                // Yes we will handle click here but which button clicked??? We don't know
    
                // So we will make
                switch (v.getId() /*to get clicked view id**/) {
                    case R.id.corky:
    
                        // do something when the corky is clicked
    
                        break;
                    case R.id.corky2:
    
                        // do something when the corky2 is clicked
    
                        break;
                    case R.id.corky3:
    
                        // do something when the corky3 is clicked
    
                        break;
                    default:
                        break;
                }
            }
        };
    
    }
    

    或者我们可以这样做:

    public class MainActivity extends ActionBarActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
    
            // Capture our button from layout
            Button button = (Button)findViewById(R.id.corky);
            Button button2 = (Button)findViewById(R.id.corky2);
            Button button3 = (Button)findViewById(R.id.corky3);
            // Register the onClick listener with the implementation above
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // do something when the corky is clicked
                }
            });
            button2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // do something when the corky2 is clicked
                }
            });
            button3.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // do something when the corky3 is clicked
                }
            });
    
        }
    
    }
    

    或者我们可以实现 View.OnClickListener,我认为这是最好的方法:

    public class MainActivity extends ActionBarActivity implements View.OnClickListener {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
    
            // Capture our button from layout
            Button button = (Button)findViewById(R.id.corky);
            Button button2 = (Button)findViewById(R.id.corky2);
            Button button3 = (Button)findViewById(R.id.corky3);
            // Register the onClick listener with the implementation above
            button.setOnClickListener(this);
            button2.setOnClickListener(this);
            button3.setOnClickListener(this);
    
        }
    
        @Override
        public void onClick(View v) {
            // do something when the button is clicked
            // Yes we will handle click here but which button clicked??? We don't know
    
            // So we will make
            switch (v.getId() /*to get clicked view id**/) {
                case R.id.corky:
    
                    // do something when the corky is clicked
    
                    break;
                case R.id.corky2:
    
                    // do something when the corky2 is clicked
    
                    break;
                case R.id.corky3:
    
                    // do something when the corky3 is clicked
    
                    break;
                default:
                    break;
            }
        }
    }
    

    最后这里没有真正的区别只是“比其他的好”

    【讨论】:

    • 第二种方式的性能难道不会比其他方式稍好一些吗?第一种和第三种方式,您首先确定点击了哪个视图,然后对其采取行动,而第二种方式您可以直接跳入其中。很想看看别人怎么说,因为老实说我不是 100% 确定我的逻辑是否正确。
    • @HuskyHuskie。知道什么时候需要关注性能,什么时候不需要。问问自己:用户多久点击一次?用户点击时可接受的响应时间是多少?我的目标设备每秒执行多少百万条 java 指令?找出哪个视图所需的少量指令 - 这很重要吗?还要考虑您为处理点击所做的工作。计算操作系统内部的代码,将执行数千、数万甚至数十万条 java 指令。我想你知道这是怎么回事......
    • 是否可以同时使用它们,我的意思不仅是“实现View.OnClickListener”,还有“SetOnClickListener”
    • @Patze 是的,您可以在不同的视图上同时使用它们。
    • 很好的例子。但是我有一个问题……鉴于这些示例,我何时在按钮的 xml 中使用 anrdoid:onClick(function) ?这只是捕获点击的第四种方式吗?
    【解决方案2】:

    逻辑很简单。 setOnClickListener 属于第 2 步。

    1. 您创建按钮
    2. 您创建OnClickListener* 的实例,就像在该示例中所做的那样,并覆盖onClick-方法。
    3. 您在片段/活动onCreate 方法中使用btn.setOnClickListener(myOnClickListener);OnClickListener 分配给该按钮。
    4. 当用户点击按钮时,分配的OnClickListeneronClick函数被调用。

    *如果您使用import android.view.View;,则使用View.OnClickListener。如果你 import android.view.View.*;import android.view.View.OnClickListener; 你使用 OnClickListener 就我所知。

    另一种方法是让您的活动/片段继承自OnClickListener。这样,您将片段/活动分配为按钮的侦听器,并将 onClick 实现为成员函数。

    【讨论】:

      【解决方案3】:

      请注意,为了简单起见,我只引用了第一个代码 sn-p 即,

      // Create an anonymous implementation of OnClickListener
      private OnClickListener mCorkyListener = new OnClickListener() {
          public void onClick(View v) {
            // do something when the button is clicked
          }
      };
      
      protected void onCreate(Bundle savedValues) {
          ...
          // Capture our button from layout
          Button button = (Button)findViewById(R.id.corky);
          // Register the onClick listener with the implementation above
          button.setOnClickListener(mCorkyListener);
          ...
      }
      

      setOnClickListener(View.OnClickListener l) 是 View 类的公共方法。 Button 类扩展了 View 类,因此可以调用setOnClickListener(View.OnClickListener l) 方法。

      setOnClickListener 注册一个回调,以便在单击视图(在您的情况下为按钮)时调用。这个答案应该回答你的前两个问题:

      1. setOnClickListener 符合上述逻辑在哪里?

      回答。单击按钮时它会注册一个回调。 (在下一段中详细解释)。

      2。哪个真正在听按钮点击?

      回答。 setOnClickListener 方法是真正监听按钮点击的方法。

      当我说它注册了一个要调用的回调时,我的意思是它将运行View.OnClickListener l,这是该方法的输入参数。在您的情况下,它将是 button.setOnClickListener(mCorkyListener); 中提到的 mCorkyListener,然后将执行 onClick(View v) 中提到的方法

      // Create an anonymous implementation of OnClickListener
      private OnClickListener mCorkyListener = new OnClickListener() {
          public void onClick(View v) {
            // do something when the button is clicked
          }
      };
      

      继续前进,OnClickListener 是一个接口定义,用于在单击视图(在您的情况下为按钮)时调用回调。简单地说,当您单击该按钮时,mCorkyListener 中的方法(因为它是OnClickListener 的实现)被执行。但是,OnClickListener 只有一种方法,即OnClick(View v)。因此,点击按钮需要执行的任何操作都必须在此方法中进行编码。

      既然您知道setOnClickListenerOnClickListener 的含义,我相信您将能够自己区分这两者。第三个词 View.OnClickListener 实际上是 OnClickListener 本身。您拥有View.preceding 的唯一原因是程序开头的import 语句不同。如果您只有import android.view.View; 作为导入语句,则必须使用View.OnClickListener。如果您提及以下任一导入语句: import android.view.View.*;import android.view.View.OnClickListener; 你可以跳过View. 直接使用OnClickListener

      【讨论】:

        【解决方案4】:

        View 是所有小部件的超类,OnClickListener 接口属于此类。所有小部件都继承了这一点。 View.OnClickListener 与 OnClickListener 相同。您必须覆盖此侦听器的 onClick(View view) 方法才能实现您想要的按钮操作。

        要告诉 Android 监听小部件的点击事件,您需要这样做:

        widget.setOnClickListener(this); // If the containing class implements the interface
        // Or you can do the following to set it for each widget individually
        widget.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Do something here
            }
        });
        

        在 onClick() 方法中传递的 'View' 参数只是让 Android 知道一个视图已被点击。它可以是 Button 或 TextView 或其他东西。您可以为每个小部件设置 OnClickListener 或简单地使包含所有这些小部件的类实现接口。在这种情况下,您将为所有小部件使用一个通用的 onClick() 方法,您所要做的就是检查传递给该方法的视图的 id,然后将其与您想要的每个元素的 id 匹配,并且对该元素采取行动。

        【讨论】:

          【解决方案5】:
          1. 首先,View.OnClickListenerOnClickListener 没有区别。如果只是直接使用View.OnClickListener,那就不用写了-

            导入 android.view.View.OnClickListener

          2. 您将 OnClickListener 实例(例如 myListener 命名对象)设置为通过 setOnclickListener() 的视图的侦听器。当click 事件被触发时,myListener 会收到通知并调用它的onClick(View view) 方法。那就是我们做我们自己的任务的地方。 希望这对您有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-09-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多