【问题标题】:Android Button setOnClickListener DesignAndroid 按钮 setOnClickListener 设计
【发布时间】:2011-04-07 23:30:06
【问题描述】:

我正在构建一个 Android 应用程序。我注意到我在每个类中都创建了许多类似的重复代码:

Button buttonX = (Button)findViewById(R.id.buttonXName);
// Register the onClick listener with the implementation above
buttonX.setOnClickListener(new OnClickListener() {
    public void onClick(View v)
    {
        //DO SOMETHING! {RUN SOME FUNCTION ... DO CHECKS... ETC}
    } 
});

我现在有十五个按钮,这让我的代码很丑。有没有人有关于如何将所有这些代码变成更高效的课程或一些示例,所以我可以:

  1. 创建按钮对象{Button buttonX (Button)findViewById(R.id.buttonXName);}
  2. 设置监听{buttonX.setOnClickListener(new OnClickListener()}
  3. 判断是否被点击{public void onClick(View v)}
  4. 然后为每个按钮运行特定代码?

如果有人知道,我将不胜感激。

【问题讨论】:

标签: android button design-patterns onclicklistener


【解决方案1】:

如果您的目标是 1.6 或更高版本,您可以使用 android:onClick xml attribute 删除一些重复代码。请参阅 Romain Guy 的 this blog post

<Button 
   android:height="wrap_content"
   android:width="wrap_content"
   android:onClick="myClickHandler" />

在 Java 类中,使用以下代码行:

class MyActivity extends Activity {
    public void myClickHandler(View target) {
        // Do stuff
    }
}

【讨论】:

  • 谢谢。这是完美的解决方案。
  • 奇怪,这不适用于我的对话框。我得到一个异常说处理程序不存在,但我确实定义了处理程序!
  • @SomeoneSomewhere 我认为它在活动上下文中搜索视图。处理程序已出局。
  • @dgmltn “让视图了解 Activity 内部结构”是一种好习惯吗?
  • 太棒了!谢谢你。对于像我这样的老家伙来说,Lambda 代码和内联函数很难阅读。
【解决方案2】:

在您的 Activity 上实现 OnClickListener()...

public class MyActivity extends Activity implements View.OnClickListener {
}

对于每个按钮使用...

buttonX.setOnClickListener(this);

在您的 Activity onClick() 方法中测试它是哪个按钮...

@Override
public void onClick(View view) {
    if (View.equals(buttonX))
        // Do something
}

您还可以在 onClick 中使用 view.getId() 来获取资源 ID,然后在 switch/case 块中使用它来识别每个按钮并执行相关操作。

【讨论】:

  • 这真的是进步吗?
  • @Corey Sunwold:这一切都很主观,但使用 setOnClickListener(this);不那么难看,并且通过没有内联 onClick() 声明减少了代码的按钮创建部分。只有一个 onCLick() 代码块,特别是使用 switch/case 代码块来识别按下了哪个按钮,可以在主代码的单独区域中进行简单的测试。不仅如此,每个“案例”都可以简单地调用位于其他地方的“助手”类中的方法。我可以想到另一种或两种做事方式,但代码仍然必须去某个地方。
  • Squonk:这更有意义,我没有从可测试性的角度考虑它(可能应该有)。谢谢。
【解决方案3】:

Android lambda 解决方案

public void registerButtons(){
    register(R.id.buttonName1, ()-> {/*Your code goes here*/});
    register(R.id.buttonName2, ()-> {/*Your code goes here*/});
    register(R.id.buttonName3, ()-> {/*Your code goes here*/});
}

private void register(int buttonResourceId, Runnable r){
    findViewById(buttonResourceId).setOnClickListener(v -> r.run());
}

Switch case解决方案

public void registerButtons(){
    register(R.id.buttonName1);
    register(R.id.buttonName2);
    register(R.id.buttonName3);
}

private void register(int buttonResourceId){
    findViewById(buttonResourceId).setOnClickListener(buttonClickListener);
}

private OnClickListener buttonClickListener = new OnClickListener() {

    @Override
    public void onClick(View v){
        switch (v.getId()) {
            case R.id.buttonName1:
                // TODO Auto-generated method stub
                break;
            case R.id.buttonName2:
                // TODO Auto-generated method stub
                break;
            case View.NO_ID:
            default:
                // TODO Auto-generated method stub
                break;
        }
    }
};

【讨论】:

    【解决方案4】:

    由于setOnClickListener 是在View 而不是Button 上定义的,如果您不需要该变量用于其他用途,您可以将其简化为:

    findViewById(R.id.buttonXName).setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
        //DO SOMETHING! {RUN SOME FUNCTION ... DO CHECKS... ETC}
        } 
    });
    

    【讨论】:

      【解决方案5】:

      您可以使用数组来处理 android 中的多个按钮单击侦听器,如下所示: 在这里,我通过使用数组为 n 个按钮设置按钮单击侦听器:

      Button btn[] = new Button[n]; 
      

      注意:n 是一个常数正整数

      代码示例:

      //class androidMultipleButtonActions 
      package a.b.c.app;
      
      import android.app.Activity;
      import android.os.Bundle;
      import android.view.View;
      import android.view.View.OnClickListener;
      import android.widget.Button;
      
      public class androidMultipleButtonActions extends Activity implements OnClickListener{
          Button btn[] = new Button[3];
      
          public void onCreate(Bundle savedInstanceState) {   
          super.onCreate(savedInstanceState);
              setContentView(R.layout.main);        
              btn[0] = (Button) findViewById(R.id.Button1);
              btn[1] = (Button) findViewById(R.id.Button2);
              btn[2] = (Button) findViewById(R.id.Button3);
              for(int i=0; i<3; i++){
                  btn[i].setOnClickListener(this);
              }           
          }
      
          public void onClick(View v) {
              if(v == findViewById(R.id.Button1)){
                  //do here what u wanna do.
              }
              else if(v == findViewById(R.id.Button2)){
                  //do here what u wanna do.
              }
              else if(v == findViewById(R.id.Button3)){
                  //do here what u wanna do.
              }
          }
      }
      

      注意:如果你不知道怎么写,请先写一个 main.xml 文件,请发邮件到: wesagnd@yahoo.com

      【讨论】:

        【解决方案6】:

        我认为你通常可以在循环中做你需要的事情,如果可以的话,这比许多onClick方法要好得多。

        查看this answer,了解如何使用循环解决类似问题。如何构建循环取决于onClick 函数的需求以及它们之间的相似程度。最终的结果是更少重复的代码,更易于维护。

        【讨论】:

          【解决方案7】:

          使用View.OnClickListener 实现活动,如下所示。

          public class MyActivity extends AppCompatActivity implements View.OnClickListener {
          
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_scan_options);
          
                  Button button = findViewById(R.id.button);
                  Button button2 = findViewById(R.id.button2);
          
                  button.setOnClickListener(this);
                  button2.setOnClickListener(this);
              }
          
              @Override
              public void onClick(View view) {
          
                  int id = view.getId();
          
                  switch (id) {
          
                      case R.id.button:
          
                            // Write your code here first button
          
                          break;
          
                       case R.id.button2:
          
                            // Write your code here for second button
          
                          break;
          
                  }
          
              }
          
          }
          

          【讨论】:

            【解决方案8】:
            public class MyActivity extends AppCompatActivity implements View.OnClickListener {
            
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_scan_options);
            
                    Button button = findViewById(R.id.button);
                    Button button2 = findViewById(R.id.button2);
            
                    button.setOnClickListener(this);
                    button2.setOnClickListener(this);
                }
            
                @Override
                public void onClick(View view) {
            
                    int id = view.getId();
            
                    switch (id) {
            
                        case R.id.button:
            
                              // Write your code here first button
            
                            break;
            
                         case R.id.button2:
            
                              // Write your code here for second button
            
                            break;
            
                    }
            
                }
            
            }
            

            【讨论】:

              【解决方案9】:
              public class MainActivity extends AppCompatActivity  implements View.OnClickListener{
              
                  Button b1;
              
                  @Override
                  protected void onCreate(Bundle savedInstanceState) {
                      super.onCreate(savedInstanceState);
                      setContentView(R.layout.activity_main);
                      b1=(Button)findViewById(R.id.button);
                      b1.setOnClickListener(this);
                  }
              
                  @Override
                  public void onClick(View v) {
                      Toast.makeText(getApplicationContext(),"Button is Working",Toast.LENGTH_LONG).show();
                  }
              
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-04-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-08-20
                • 1970-01-01
                相关资源
                最近更新 更多