Best practice for defining button events in androi

2019-01-03 22:54发布

I have a Layout defined in XML which consists of several Buttons.

Currently I am doing this in the OnCreate method to define the event handlers against the buttons:

public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button newPicButton = (Button)findViewById(R.id.new_button);
    newPicButton.setOnClickListener(btnListener);
    ..... similarly for other buttons too
    .....
}

Inside of the Button's onClick event, I launch a camera Intent to get a picture and inside the onActivityResult callback I am again setting the event handlers along with setting the View like this:

protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{ 
    setContentView(R.layout.main);
    Button newPicButton = (Button)findViewById(R.id.new_button);
    newPicButton.setOnClickListener(btnListener);
    ...similarly for other buttons too
}

I am new to android and this approach of redefining an event every time seems quite dirty to me. I would like to know what is the best practice in terms of defining button event handlers in scenarios like this.

Edit: pasting my complete class

public class CameraAppActivity extends Activity 
{
    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button newPicButton = (Button)findViewById(R.id.new_button);
        newPicButton.setOnClickListener(btnListener);
    }

    //---create an anonymous class to act as a button click listener---
    private OnClickListener btnListener = new OnClickListener()
    {

        public void onClick(View v)
        {   
             //Intent newPicIntent = new Intent(v.getContext(), NewPictureActivity.class);
             //startActivityForResult(newPicIntent, 0);
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, 999);
        } 

    };  

    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {  

        setContentView(R.layout.main);
        Button newPicButton = (Button)findViewById(R.id.new_button);
        newPicButton.setOnClickListener(btnListener);

       //if I comment last two lines nothing happens when I click on button

    }  

The main question is

setContentView(R.layout.main);
Button newPicButton = (Button)findViewById(R.id.new_button);
newPicButton.setOnClickListener(btnListener);

Re-registering events inside onActivityResult.. is it right approach? Or am I doing something wrong? Because If I don't re-register event nothing happens when I click the button.

10条回答
狗以群分
2楼-- · 2019-01-03 23:37

Your Activity should implement OnClickListener and you should write all your event handling for all buttons inside single OnCLick() method.

查看更多
做自己的国王
3楼-- · 2019-01-03 23:42

I like the "modern" DI way by using Butter Knife:

  1. Declare your view
@InjectView(R.id.buttonAlert) 
Button buttonAlert;
  1. Inject all annotated resources
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.inject(this);
 }
  1. Annotate and implement your onClick method
@OnClick(R.id.buttonAlert)
public void alertClicked(View v){
    // your logic
}
查看更多
姐就是有狂的资本
4楼-- · 2019-01-03 23:43

@Hasan This is the best approach that i have found and which works for me every single time flawlessly.

  • In Layout.xml define the onClick for the button

                    <Button android:id="@+id/Button01"          
                        android:onClick="@string/method" 
                        android:focusable="true" android:clickable="true"
                        ">
                    </Button>
    
  • In the R.string file add the following line

string name="method">buttonFunction

  • In the sample.java file the function define in R.string will be called on the click of the button and it should look something like

    public void buttonFunction(View view) { // do nething u like on the click of the button }

查看更多
Rolldiameter
5楼-- · 2019-01-03 23:44

Here is the best approach with code:

  public class MyTest extends Activity implements OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     //... some other code here to init the layout
        Button btn1 = (Button)findViewById(R.id.button1);
        Button btn2 = (Button)findViewById(R.id.button2);
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
    }

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

The new class with an interface is only good if you want to decouple the implementation (when you want to use the same class code somewhere else, move it to another seperate class file etc..) but in general if you are doing things connected with the current activity you are on and the onClick implementations depend on it running with reference to the objects defined there you should definitely use the method i suggested.

Creating class interfaces is only good when you want to achieve communication between seperate classes or activities and keep things apart. other than that its a bad practice creating subclasses for this.

查看更多
登录 后发表回答