【问题标题】:android fragment action bar menuandroid片段操作栏菜单
【发布时间】:2016-08-31 05:00:45
【问题描述】:

我创建了一个带有操作栏菜单的片段,该菜单已显示但在单击时不起作用。

这是我的片段:

public class ComposeFragment extends Fragment {

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_compose, container, false);

        userName = (TextView) view.findViewById(R.id.user_name);
        subjectSpinner = (Spinner) view.findViewById(R.id.subject_spinner);
        sendButton = (Button) view.findViewById(R.id.send_btn);
        messageEditText = (EditText) view.findViewById(R.id.message);

        userName.setText(Ezcation.getInstance().userName);
        return view;
    }
@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.compose_menu, menu);
    }
@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Log.e("Menu","Before Switch");
        switch (item.getItemId()){
            case R.id.sent:
                Log.e("Menu","Sent");
                if (messageEditText.getText().toString().equals("")){
                    messageEditText.setError("Please Enter your Message");
                }else {
                    sendMessage(messageEditText.getText().toString());
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
@Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.messageActivity = (MessageActivity) context;
        SpannableString s = new SpannableString("Compose Message");
        s.setSpan(new TypefaceSpan(messageActivity, "Miller-Text.ttf"), 0, s.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        messageActivity.setTitle(s);
    }
}

当点击菜单时甚至 Log.e("Menu","Before Switch"); 不起作用。

我的菜单 xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/sent"
        android:title="Sent"
        android:orderInCategory="10"
        android:icon="@drawable/sent"
        app:showAsAction="ifRoom" />
</menu>

【问题讨论】:

  • 是的,现在才看到 @0X0nosugar 之前错过了它
  • 你是返回true还是在Activity的onOptionsItemSelected()中调用super.onOptionsItemSelected()?我认为刚刚删除答案的海报在正确的轨道上,但不幸的是它已经消失了
  • 抱歉,由于一些垃圾邮件发送者,我不得不删除我的答案。
  • @Shinil M S - 是的,有点粗鲁。当整个帖子变成空白时,我正要标记评论。请问可以取消删除吗?您必须从 Activity 方法返回 false 是 100% 正确的 - 我刚刚检查了我自己的一个(正在工作的)应用程序以确保
  • @ShinilMS 检查我对推荐方法的回答

标签: android android-fragments android-fragmentactivity


【解决方案1】:

对于未来的访问者,您应该在 Activity 类中使​​用它:

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

为了正常工作,硬编码 false 不是正确的方法

【讨论】:

  • “硬编码”听起来像“禁忌”。我一直认为返回“true”意味着我的方法处理了事件,返回“false”意味着我不感兴趣,让下一个有机会。真的不仅仅是风格问题吗?也就是说,如果我知道还有其他相关方。
  • @0X0nosugar 来自方法文档 派生类应调用基类以执行默认菜单处理。
  • @0X0nosugar 好吧,你对真假是对的,但我的观点只是关于硬编码
  • 谢谢 :) 我一直在想这最后几分钟,我的其他评论中的最后一句话是一个很好的理由,为什么调用 super 被认为是一种好习惯。维护等等。
【解决方案2】:

将此添加到您的活动中。

@Override public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {
    case android.R.id.home:
        finish();
        break;
}
return super.onOptionsItemSelected(item);;
}

【讨论】:

  • 如果你的 Activity 的 onOptionsItemSelected 方法返回 true,则调用在 Activity 中消耗,Fragment 的 onOptionsItemSelected 不会被调用。因此,通过 super.onOptionsItemSelected 调用在您的 Activity onOptionsItemSelected 方法或父类实现中返回 false(默认实现返回 false)。
  • 我认为你必须从 Activity 方法中返回 false
  • 是的,这就是我的意思。 FragmentActivity 是fragment连接的activity。
  • 好吧,显然你可能会弄错 :-( 或许可以说类似“托管活动”?
【解决方案3】:

super call 内部缺少 onCreateOptionsMenu

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.compose_menu, menu);
    super.onCreateOptionsMenu(menu, inflater);
}

【讨论】: