How to determine which child has called a parent’s

2019-07-21 07:28发布

问题:

I am using the same tabBar across multiple Activities. And since there are extensive logic involved for onOptionsItemSelected, I want to write the relevant methods once and then reuse them. Hence I am deciding to created a super class called CustomActionBarActivity and then have the children activities extend it. One particular problem I need help with is how can I tell which child has caused the onOptionsItemSelected to be called? To elucidate, I will present the general code and then a failed attempt at a solution.

Here is the general code

public class CustomActionBarActivity extends FragmentActivity {

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
            case R.id.tab_dog:
                startActivity(new Intent(this, DogActivity.class));
                return true;
            case R.id.tab_cat:
                startActivity(new Intent(this, CatActivity.class));
                return true;
            case R.id.tab_mouse:
                startActivity(new Intent(this, MouseActivity.class));
                return true;
            case R.id.tab_goose:
                startActivity(new Intent(this, GooseActivity.class));
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

}

Failed attempt

If I try, for instance,

case R.id.tab_dog:
  if(!(this instanceof DogActivity))
    startActivity(new Intent(this, DogActivity.class));

then I get a compile error such that CustomActionBarActivity is not compatible with DogActivity. Thanks for any help you can provide.

回答1:

Instead of having your parent class inspect the children using reflection (which is pretty fragile since it doesn't scale with the number of children subclasses you create), maybe you could take advantage of dynamic dispatch instead.

For example, maybe you could declare an abstract method in your parent activity like:

protected abstract void onTabItemSelected(MenuItem item);

Then your children activities can override this method depending on the desired behavior. For example, DogActivity might implement it like this:

protected boolean onTabItemSelected(MenuItem item) {
    if (item.getItemId() != R.id.dog_tab) {
        startActivity(new Intent(this, DogActivity.class));
        return true;
    }
    return false;
}

The onOptionsItemSelected method would then be implemented like this:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (onTabItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

Let me know if I misunderstood the question. Either way, you might be able to modify this approach to suit your use case.