多个按钮的 OnClickListener() Android

99

我目前正在制作一个简单的Android计算器应用程序。我试图设置代码,使得当数字按钮被按下时,它会更新计算器屏幕上的该数字。目前我是这样做的。

    Button one = (Button) findViewById(R.id.oneButton);
    one.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            TextView output = (TextView) findViewById(R.id.output);
            output.append("1");
        }
    });

它能工作,但我正在为计算器上的每个按钮编写相同的代码。正如您所想象的那样,这非常冗余。有没有更有效的方法来编写这段代码?一种不需要为每个按钮编写此方法的方法?


在你的类中实现onclick监听器,它将覆盖onclick方法。根据按钮的id,你可以执行操作。 - learner
Boopathi,你能详细解释一下我该如何编写这个按钮吗?我将按钮ID设置为“1”,这样我就可以使用“this”来访问该数字。但我不确定我该如何编辑TextView。 - user3011685
12个回答

258

您只需要按照以下步骤进行操作,即可轻松实现...

您无需为每个按钮编写新的onClickListener...只需将View.OnClickLister实施到您的Activity/Fragment中..它将实现一个名为onClick()的新方法,用于处理ButtonTextView等的onClick事件。

  1. 在您的Activity/Fragment中实现OnClickListener()
public class MainActivity extends Activity implements View.OnClickListener {

}
  1. 在您的Activity/Fragment中实现onClick()方法
public class MainActivity extends Activity implements View.OnClickListener {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    
    @Override
    public void onClick(View v) {
      // default method for handling onClick Events..
    }
}
  1. 为按钮实现OnClickListener()
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    setContentView(R.layout.your_layout);
    
    Button one = (Button) findViewById(R.id.oneButton);
    one.setOnClickListener(this); // calling onClick() method
    Button two = (Button) findViewById(R.id.twoButton);
    two.setOnClickListener(this);
    Button three = (Button) findViewById(R.id.threeButton);
    three.setOnClickListener(this);
}
  1. 按ID查找按钮并实现您的代码...
@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.oneButton:
            // do your code
            break;
        case R.id.twoButton:
            // do your code
            break;
        case R.id.threeButton:
            // do your code
            break;
        default:
            break;
    }
}

请参考此链接获取更多信息:

这将使处理多个按钮点击事件变得更加容易,并使其管理变得简单...


第四点:我在 @Override 标签上遇到了错误,警告我该方法未覆盖其超类的方法。 - KasparTr
我在使用Eclipse时经常使用这种方法,但现在我转换到了Android Studio,我遇到了一个错误:“在Android库模块中不能在switch语句中使用资源ID。”。从SDK工具R14开始,资源ID不是最终的。建议的解决方法是用if/else语句替换switch语句。 - Scorpio
@Scorpio:我也在使用Android Studio。但是我从未遇到过那个错误。请确保您正在使用正确的方法,并且使用view.getId()获取所点击的按钮的ID。这是一个示例,您需要根据自己的需求进行一些更改。加油。:) - Pragnesh Ghoda シ
有没有办法避免在每个按钮上设置 onClickListener? 我的意思是,如果我有很多按钮需要监听点击事件,那么代码看起来很混乱,为每个按钮编写监听器很繁琐,例如:button1.setOnClickListener(this);button2.setOnClickListener(this);.... buttonN.setOnClickListener(this); 有没有什么方法可以避免这种情况? 在布局中使用 android:onClick 属性可以解决这个问题,但我想要在 Java 源代码中实现。 - srv_sud
1
@PragneshGhodaシ 感谢您的回答。在我向StackOverflow提问后,我已经解决了这个问题。https://stackoverflow.com/questions/56965159/how-can-add-same-onclick-for-all-imageview-in-recyclerview/56965409?noredirect=1#comment100470609_56965409 - Ahmet Yılmaz
显示剩余4条评论

59
你可以设置该属性:
android:onClick="buttonClicked"
在每个按钮的XML文件中添加此代码,并在Java代码中使用它:
public void buttonClicked(View view) {

    if (view.getId() == R.id.button1) {
        // button1 action
    } else if (view.getId() == R.id.button2) {
        //button2 action
    } else if (view.getId() == R.id.button3) {
        //button3 action
    }

}

4
最好使用开关。 - Ali Khaki
1
@AliKhaki switch 在某些情况下可能无法正常工作。在这里有解释:http://tools.android.com/tips/non-constant-fields - Andro

11

为每个按钮设置一个标签,可以是任何你想要处理的内容,在这种情况下可能是一个整数。然后你只需要一个OnClickListener来处理所有的按钮:

Button one = (Button) findViewById(R.id.oneButton);
Button two = (Button) findViewById(R.id.twoButton);
one.setTag(new Integer(1));
two.setTag(new Integer(2));

OnClickListener onClickListener = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        TextView output = (TextView) findViewById(R.id.output);
        output.append(v.getTag());
    }
}

one.setOnClickListener(onClickListener);
two.setOnClickListener(onClickListener);

1
请参考此答案,了解如何使用标签。 - Henrik Christensen

9
我创建了一个专用的类来实现View.OnClickListener。
public class ButtonClickListener implements View.OnClickListener {

    @Override
    public void onClick(View v) {
        Toast.makeText(MainActivity.this, "Button Clicked", Toast.LENGTH_SHORT).show();
    }

}

然后,在MainActivity中创建了这个类的一个实例。

private ButtonClickListener onClickBtnListener = new ButtonClickListener();

然后为按钮设置 onClickListener

btn.setOnClickListener(onClickBtnListener);

如果您只使用一个按钮,那么这可以正常工作,但是如果您使用多个按钮,则始终会调用相同的侦听器,因此您应该在onClick方法中添加一个switch case,并包含每个按钮的id。 - lebarillier
我假设如果您为每个按钮创建一个类实例,那么这也将缓解这种担忧。 - Matt Strom

3
public class MainActivity extends AppCompatActivity implements OnClickListener  {
    Button  b1,b2;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        b1= (Button) findViewById(R.id.button);
        b2= (Button) findViewById(R.id.button2);
        b1.setOnClickListener(this);
        b2.setOnClickListener(this);
    }


    @Override
    public void onClick(View v)
    {
        if(v.getId()==R.id.button)
        {
            Intent intent=new Intent(getApplicationContext(),SignIn.class);
            startActivity(intent);
        }
        else if (v.getId()==R.id.button2)
        {
            Intent in=new Intent(getApplicationContext(),SignUpactivity.class);
            startActivity(in);
        }
    }
}

2
我有一个类似的问题,我的做法是: 创建一个按钮数组。
Button buttons[] = new Button[10];

接着为了实现点击监听器并引用xml id,我使用了以下循环:

for (int i = 0; i < 10; i++) {      
String buttonID = "button" + i;
        int resID = getResources().getIdentifier(buttonID, "id",
                "your package name here");
        buttons[i] = (Button) findViewById(resID);
        buttons[i].setOnClickListener(this);
    }

但是呼叫它们的方法与Prag的答案第4点相同。 附注- 如果有人有更好的方法来调用所有按钮的onClick,请留言。


1

在你的Activity/Fragment中实现onClick()方法 public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onClick(View v) {
 switch (itemId) {

// if you call the fragment with nevigation bar then used.

           case R.id.nav_menu1:
                fragment = new IntroductionFragment();
                break;

// if call activity with nevigation bar then used.

            case R.id.nav_menu6:
                Intent i = new Intent(MainActivity.this, YoutubeActivity.class);
                startActivity(i);
      // default method for handling onClick Events..
    }
}

1
public void onClick(View v) {
    int id = v.getId();
    switch (id){
        case R.id.button1:
            //do ur code
            Toast.makeText(this,"This is button 1",Toast.LENGTH_SHORT).show();
            break;
        case R.id.button2:
            Intent intent = new Intent(this,SecondActivity.class);
            Intent.putExtra("key",value);
            startActivity(intent);
            break;
        case R.id.button3:
            //do ur code
            break;
        case R.id.button4:
            //do ur code;
            break;
        default:
            //do ur code;
    }
}

1
你可以使用这个。
    TextView output = (TextView) findViewById(R.id.output);
    one.setOnClickListener(youractivity.this);
    // set the onclicklistener for other buttons also

    @Override
    public void onClick(View v) {
      int id = v.getId();
    switch(id) {
    case R.id.oneButton:      
       append("1",output);
       break;
    case R.id.twoButton:
        append("2",output);
       break;
    case R.id.threeButton:
        append("3",output);
       break;
     } 
      }

 private void append(String s,TextView t){
  t.setText(s); 
}

你可以在一个单独的方法中识别活动中的视图。

0
不需要if else或switch,让我们开始吧: 在你的每个按钮或其他控件上(我使用ImageView),添加这个属性 android:onClick="DoSomeThing" 在你的Activity中:
public void DoSomeThing(View v){
    ImageView img1= (ImageView) v; //you have to cast the view i.e. if it's button, it must be cast to Button like below line

    Button b1= (Button) v;

    img1.setImageBitmap(imageBitmap); //or anything you want to do with your view, This will work for all

    b1.setText("Some Text");
}

这样做,无需通过id查找视图,也不需要点击监听器,没有冗余代码,就像上面那样简单!


这样做就不需要通过id查找视图,也不需要点击监听器,没有冗余代码,就像上面那样简单! - Zubair Younas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接