菜单共享多个活动

时间:2018-04-02 17:37:18

标签: java android

我有多个活动共享相同的选项菜单,所以在我的每个活动中,我正在做

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
        case R.id.settings:
           Intent opensettings = new Intent(this, SettingsActivity.class);
           startActivity(opensettings);
            return true;
        case R.id.help:
          ...others

        default:
            return super.onOptionsItemSelected(item);
    }
}

有没有办法在不同的活动中分享上述代码?

我尝试过添加一个类

class MenuHelper{
   Context ctx;
  public MenuHelper(Context context){
    ctx=context
  }

 public boolean openMenuItems(Menu item){
   switch(item.getItemId()) //here .getItemId() doesnt work{

      case R.id.settings: //R.id.settings not found

    }

  }

}

但我被困在我的助手班。我该怎么办,以便在我的不同活动中我只需要

MenuHelper menuitems = new MenuHelper(this);
menuitems.openMenuItems(menu)

3 个答案:

答案 0 :(得分:3)

为什么不为您的常见活动创建一个超类?如果你创建一个超类,如下所示:

public class MySharedMenuActivity extends Activity {
    @Override
    public boolean onOptionsItemSelected(MenuItem item) { ... }
}

然后,如果您为所需的活动扩展该类,您将能够访问共享菜单。

答案 1 :(得分:3)

您可以拥有一个BaseActivity,您可以在其中将常用实施放在您的活动中,然后让其他活动扩展BaseActivity

public class BaseActivity extends AppCompatActivity {

    // Any other common methods

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
            case R.id.settings:
               Intent opensettings = new Intent(this, SettingsActivity.class);
               startActivity(opensettings);
                return true;
            case R.id.help:
              ...others

            default:
                return super.onOptionsItemSelected(item);
        }
    }

}

您现在可以创建扩展BaseActivity的活动:

public class MainActivity extends BaseActivity {

}

答案 2 :(得分:1)

继承

正如其他响应所示,您可以使用继承来提供此类功能。这确实打破了“优先于继承规则的构成”,但可能是简单应用的实用解决方案。

的组合物

我认为你正在创造一个各种各样的“菜单助手”。我更喜欢像OptionsMenuHandler这样的名字,并且可能会这样写:

public class OptionsMenuHandler {

    private final Activity activity;

    public OptionsMenuHandler(Activity activity) {
        this.activity = activity;
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        // do menu inflation here.
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.settings:
                Intent openSettings = new Intent(activity, SettingsActivity.class);
                activity.startActivity(openSettings);
                return true;
            case R.id.help:
                // others
            default:
                return false;
        }
    }

    public boolean onPrepareOptionsMenu(Menu menu) {
        // do menu preparation here.
    }
}

并像这样使用它:

public class TestActivity extends AppCompatActivity {

    private final OptionsMenuHandler optionsMenuHandler = new OptionsMenuHandler(this);

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return optionsMenuHandler.onCreateOptionsMenu(menu) ||
                   super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        return optionsMenuHandler.onPrepareOptionsMenu(menu) ||
                   super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return optionsMenuHandler.onOptionsItemSelected(item) ||
                   super.onOptionsItemSelected(item);
    }
}

这确实需要每个活动中额外的锅炉板。它还创建了抽象。抽象是合理的,因为它保持代码DRY。我还喜欢这样一个事实:业务逻辑不隐藏在某个父类的内部隐藏......组合使得业务逻辑的位置更加明显。

支持合成的基本活动

另一种选择是支持基础活动中的构成如下......

创建一个定义明确的抽象:

public interface OptionsMenuHandler {
    boolean onCreateOptionsMenu(Menu menu);
    boolean onOptionsItemSelected(MenuItem item);
    boolean onPrepareOptionsMenu(Menu menu);
}

为抽象创建一个实现:

public class DefaultOptionsMenuHandler implements OptionsMenuHandler {

    private final Activity activity;

    public DefaultOptionsMenuHandler(Activity activity) {
        this.activity = activity;
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        // do menu inflation here.
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.settings:
                Intent openSettings = new Intent(activity, SettingsActivity.class);
                activity.startActivity(openSettings);
                return true;
            case R.id.help:
                // others
            default:
                return false;
        }
    }

    public boolean onPrepareOptionsMenu(Menu menu) {
        // do menu preparation here.
    }
}

基类中的支持组合(即基类有一个setter):

public class BaseActivity extends AppCompatActivity {

    @Nullable
    private OptionsMenuHandler optionsMenuHandler;

    protected void setOptionsMenuHandler(OptionsMenuHandler optionsMenuHandler) {
        this.optionsMenuHandler = optionsMenuHandler;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return optionsMenuHandler != null
               ? optionsMenuHandler.onCreateOptionsMenu(menu)
               : super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        return optionsMenuHandler != null
               ? optionsMenuHandler.onPrepareOptionsMenu(menu)
               : super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return optionsMenuHandler != null
               ? optionsMenuHandler.onOptionsItemSelected(item)
               : super.onOptionsItemSelected(item);
    }
}

在需要该功能的Activity中设置实现。

public class TestActivity extends BaseActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setOptionsMenuHandler(new DefaultOptionsMenuHandler(this));
    }
}

这里的净效益是您编写一次主样板并通过所有活动支持它。您还可以继续将您的业务逻辑定义在顶级活动中 - 与该特定活动的其他各种逻辑一起使用。

大多数非平凡的应用程序都会从​​这些方面受益。我通常做一些更强大的东西,支持在任何给定活动中设置零个或多个OptionsMenuHandlers,其中每个处理程序支持特定类型的功能。这段代码相当长,需要考虑很多因素,所以我不会在这里制作它。