在Android中委派点击监听器

比方说,我有几个按钮,他们的点击是由一个共同的处理程序处理有没有一种方法来定义监听一次,而不是定义每个按钮的onClick属性?

 <Button android:onClick="handler" /> 

也许父母代表在浏览器或一些拦截器…..想象你有50个按钮,你声明每个明确点击每个?

是的,可以通过编程的方式在活动层面实现。 所以不需要在XML中定义“onClick”属性。

你定义一个View.OnClickListener类。 例如

 View.OnClickListener buttonListener = new View.OnClickListener() { public void onClick(View v) { // here you can define different code for different buttons }; 

那么你把这个监听器附加到一个地方的所有按钮上

 final Button button = findViewById(R.id.button_id); button.setOnClickListener(buttonListener); 

是的,你可以这样做。

 import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { List<Button> buttons; ViewGroup parentView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttons = new ArrayList<>(); parentView = (ViewGroup) findViewById(R.id.cord); //Replace the above line with the container view ie //Replace parentView = (ViewGroup) findViewById(R.id.cord); // With parentView = (ViewGroup) findViewById(R.id.<YOUR MAIN VIEW/PARENT CONTAINER>); //R.id.cord is R.id.<YOUR MAIN VIEW/PARENT CONTAINER> for me because my Relative Layout // container's name is cord. for(int i=0; i < parentView.getChildCount(); i++) { childView = parentView.getChildAt(i); //The if may change there are other options try them too. if(childView.getClass().getName().substring(35).equals("Button")){ buttons.add((Button)parentView.getChildAt(i)); } /* //Else part optional //Remove comment to use else Log.e("Not","A Button");*/ } for (int i =0;i<buttons.size();i++){ buttons.get(i).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //Do the work here Log.d("Button Clicked",Integer.toString(view.getId())); } }); } } } 

这是一个你可以解决你的问题的方法…

最好的方法:只要让你的活动实现View.OnClickListener ,并写下你的onClick方法,如下所示:

 public void onClick(View v) { final int id = v.getId(); switch (id) { case R.id.button1: // your code for button1 here break; case R.id.button2: // your code for button2 here break; // even more buttons here } } 

然后,在您的XML布局文件中,您可以使用属性android:onClick:直接设置点击监听android:onClick:

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

以下是我终于解决的问题:

在java中:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final MainActivity activity = this; View rootView = this.getWindow().getDecorView().getRootView(); // Buttons are touchables ArrayList<View> touchables = rootView.getTouchables(); // Define the common on click listener for the buttons View.OnClickListener listener = new View.OnClickListener() { public final void onClick(View view) { activity.onBtnClick( (Button) view ); } }; // Iterate trough touchables and if the View is a button assign the listener for (View v: touchables) { // TODO: omit button if that common listener isn't meant for it if(v instanceof Button) { v.setOnClickListener(listener); } } } // The listener callback protected final void onBtnClick(Button btn) { String btnStringId = btn.getResources().getResourceEntryName(btn.getId()); } 

在Kotlin:

 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val rootView = window.decorView.rootView val touchables = rootView.touchables val listener = View.OnClickListener { onBtnClick(it as Button) } touchables.forEach { if (it is Button) { it.setOnClickListener(listener) }} } protected fun onBtnClick(btn: Button) { var btnStringId = btn.getResources().getResourceEntryName(btn.id) }