【问题标题】:Android OnClickListener - identify a buttonAndroid OnClickListener - 识别一个按钮
【发布时间】:2011-03-20 04:56:34
【问题描述】:

我有活动:

public class Mtest extends Activity {
  Button b1;
  Button b2;
  public void onCreate(Bundle savedInstanceState) {
    ...
    b1 = (Button) findViewById(R.id.b1);
    b2 = (Button) findViewById(R.id.b2);
    b1.setOnClickListener(myhandler);
    b2.setOnClickListener(myhandler);
    ...
  }
  View.OnClickListener myhandler = new View.OnClickListener() {
    public void onClick(View v) {
      // MY QUESTION STARTS HERE!!!
      // IF b1 do this
      // IF b2 do this
      // MY QUESTION ENDS HERE!!!
    }
  }
}

如何查看点击了哪个按钮?

【问题讨论】:

标签: android events resources listener


【解决方案1】:

您将学会做这件事的简单方法是:

public class Mtest extends Activity {
  Button b1;
  Button b2;
  public void onCreate(Bundle savedInstanceState) {
    ...
    b1 = (Button) findViewById(R.id.b1);
    b2 = (Button) findViewById(R.id.b2);
    b1.setOnClickListener(myhandler1);
    b2.setOnClickListener(myhandler2);
    ...
  }
  View.OnClickListener myhandler1 = new View.OnClickListener() {
    public void onClick(View v) {
      // it was the 1st button
    }
  };
  View.OnClickListener myhandler2 = new View.OnClickListener() {
    public void onClick(View v) {
      // it was the 2nd button
    }
  };
}

或者,如果您只使用一个 clicklistener,您可以这样做:

View.OnClickListener myOnlyhandler = new View.OnClickListener() {
  public void onClick(View v) {
      switch(v.getId()) {
        case R.id.b1:
          // it was the first button
          break;
        case R.id.b2:
          // it was the second button
          break;
      }
  }
}

不过,我不建议这样做,因为您必须为您使用的每个按钮添加一个if。这很难维护。

【讨论】:

  • 嗯,实际上这是不正确的。 View 不是 Button,但 ButtonView。不过,您可以将View 转换为Button。请记住,不建议使用第二种方式...也许 v 可能不是 Button,这会产生强制转换异常。
  • 其实两种方式都不推荐,看我的回答
  • 用一个switch case语句替换if,elses实际上很简单,你可以打开视图的id,case是来自R.java的id
  • 只是想知道为什么要将 v 转换为 Button。 getId() 也为视图定义。因此我真的不推荐第二种方法,而是更喜欢Christian的解决方案!
【解决方案2】:

除了 Cristian C 的回答(对不起,我没有能力制作 cmets),如果您为两个按钮制作一个处理程序,您可以直接将 v 与 b1 和 b2 进行比较,或者如果您想通过ID,不需要将 v 转换为 Button(View 也有 getId() 方法),这样就不用担心转换异常了。

【讨论】:

  • 另一种选择是执行“if (v instanceof Button) { // Cast to Button and do stuff here }”
【解决方案3】:

最好的方法是在 v.getId() 之间通过switch-ing。为每个 Button 设置单独的匿名 OnClickListener 会占用更多内存。将视图转换为按钮是不必要的。在可以切换时使用 if-else 会更慢且更难阅读。在 Android 的源代码中,您经常可以注意到通过 if-else 比较引用:

if (b1 == v) {
 // ...
} else if (b2 == v) {

我不知道他们为什么选择这种方式,但它也有效。

【讨论】:

  • 因为自 v14 以来不再可能,其中 id 不被视为常量
  • @ognian 我跟进了这里,因为您说主要答案使用了已弃用的方法。如今随着 Android 5.0 Lollipop 的发布,您的答案仍然是正确的,还是像上面的评论所暗示的那样,时间让它成为了一个谬论?我真的不知道该怎么想,或者从这里往哪个方向走。
【解决方案4】:

另一种方法是使用来自 activity 的单个侦听器,如下所示:

public class MyActivity extends Activity implements OnClickListener {
    .......  code

    //my listener
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.mybutton) { 
            DoSomething();
            return;
        }

        if (v.getId() == R.id.mybutton2) { 
            DoSomething2();
            return;
        }
    }
}

我喜欢使用单个 IF 而不是 switch-else,但如果您愿意,那么您应该这样做:

//my listener
@Override
public void onClick(View v) {
    switch(v.getId()) {
        case R.id.mybutton:
        { 
             DoSomething();
             break;
        }

        case R.id.mybutton2:
        {
            DoSomething();
            break;
        }
    }
}

【讨论】:

    【解决方案5】:

    我更喜欢:

    class MTest extends Activity implements OnClickListener {
        public void onCreate(Bundle savedInstanceState) {
        ...
        Button b1 = (Button) findViewById(R.id.b1);
        Button b2 = (Button) findViewById(R.id.b2);
        b1.setOnClickListener(this);
        b2.setOnClickListener(this);
        ...
    }
    

    然后:

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.b1:
                ....
                break;
            case R.id.b2:
                ....
                break;
        }   
    }
    

    Switch-caseif-else 更容易维护,而且这种实现不需要制作很多类变量。

    【讨论】:

    • 这非常有效。您需要实现 OnClickListener-android.view.View 而不是 OnClickListener-android.content.DialogInterface
    【解决方案6】:

    或者您可以尝试相同但没有听众。在您的按钮 XML 定义中:

    android:onClick="ButtonOnClick"
    

    并在您的代码中定义方法ButtonOnClick

    public void ButtonOnClick(View v) {
        switch (v.getId()) {
          case R.id.button1:
            doSomething1();
            break;
          case R.id.button2:
            doSomething2();
            break;
          }
    }
    

    【讨论】:

    • 比使用一堆事件处理程序、if 语句和侦听器的其他答案要干净得多。如果按钮是在运行时创建的,那么侦听器会很棒,但通常情况并非如此。
    • 虽然是一种有趣的不同方法,但用于侦听器的 XML 挂钩在 Fragments 的拐角处很粗糙,因为回调必须驻留在活动中(而不是片段)。
    • 我的问题是 doSomething2() 在不抛出 InvocationTargetException 或 NullPointerException(或两者)的情况下无法访问。
    • 只是一个旁注:这里的“没有听众”的说法是错误的。您只是在 XML 中声明侦听器,仅此而已。
    【解决方案7】:
    Button mybutton = new Button(ViewPagerSample.this);
    mybutton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
                // TODO Auto-generated method stub
        }
    });
    

    【讨论】:

      【解决方案8】:

      如果您不想在类代码中保存 2 按钮的实例,请按照此 BETTER 方式(这样更清晰快速!!):

      public void buttonPress(View v) {
        switch (v.getId()) {
          case R.id.button_one:
              // do something
              break;
          case R.id.button_two:
              // do something else
              break;
          case R.id.button_three:
              // i'm lazy, do nothing
              break;
        }
      }
      

      【讨论】:

        【解决方案9】:

        使用 setTag();

        像这样:

        @Override    
        public void onClick(View v) {     
            int tag = (Integer) v.getTag();     
            switch (tag) {     
            case 1:     
                System.out.println("button1 click");     
                break;     
            case 2:     
                System.out.println("button2 click");     
               break;   
            }     
        }     
        

        【讨论】:

        • 我来这里是为了寻找一种将附加参数传递给处理程序的方法,这正是我想要的。标签可以在 Markup 中声明。
        【解决方案10】:

        Five Ways to Wire Up an Event Listener 是一篇很棒的文章,概述了设置单个事件侦听器的各种方法。让我在这里为多个听众扩展它。

        1。会员等级

        public class main extends Activity {
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                //attach an instance of HandleClick to the Button
                HandleClick handleClick = new HandleClick();
                findViewById(R.id.button1).setOnClickListener(handleClick);
                findViewById(R.id.button2).setOnClickListener(handleClick);
            }    
            private class HandleClick implements OnClickListener{
                public void onClick(View view) {
                    switch(view.getId()) {
                    case R.id.button1:
                        // do stuff
                        break;
                    case R.id.button2:
                        // do stuff
                        break;
                    }
                }
            }
        }
        

        2。接口类型

        public class main extends Activity {
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                findViewById(R.id.button1).setOnClickListener(handleClick);
                findViewById(R.id.button2).setOnClickListener(handleClick);
            }
            private OnClickListener handleClick = new OnClickListener() {
                public void onClick(View view) {
                    switch (view.getId()) {
                    case R.id.button1:
                        // do stuff
                        break;
                    case R.id.button2:
                        // do stuff
                        break;
                    }
                }
            };
        }
        

        3。匿名内部类

        public class main extends Activity {
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
                    public void onClick(View view) {
                        // do stuff
                    }
                });
                findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
                    public void onClick(View view) {
                        // do stuff
                    }
                });
            }
        }
        

        4。在 Activity 中实现

        public class main extends Activity implements OnClickListener {
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                findViewById(R.id.button1).setOnClickListener(this);
                findViewById(R.id.button2).setOnClickListener(this);
            }
            public void onClick(View view) {
                switch (view.getId()) {
                case R.id.button1:
                    // do stuff
                    break;
                case R.id.button2:
                    // do stuff
                    break;
                }
            }
        }
        

        5。 OnClick 事件的视图布局中的属性

        public class main extends Activity {
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
            }
            public void HandleClick(View view) {
                switch (view.getId()) {
                case R.id.button1:
                    // do stuff
                    break;
                case R.id.button2:
                    // do stuff
                    break;
                }
            }
        }
        

        在xml中:

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="HandleClick" />
        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="HandleClick" />
        

        【讨论】:

          【解决方案11】:
          Button button1 = (Button)findViewById(R.id.button1);
          button1.setOnClickListener(this);
          
          @Override
          public void onClick(View v) {
              // TODO Auto-generated method stub
              if(v.getId() == R.id.button1){
                  Toast.makeText(context, "Button 1 Click", Toast.LENGTH_LONG).show();
              }
          }
          

          Check this article for more details

          【讨论】:

          • 这或多或少只是一些现有答案的重复。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-12
          • 2021-08-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多