Android Fragment操作栏菜单

4

我已经创建了一个带有操作栏菜单的碎片,但是当菜单被点击时,它并没有起作用。

以下是我的碎片代码:

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>

是的,我确定那是我的菜单。 - Rathina Sabapathi M
1
在Activity的onOptionsItemSelected()方法中,你是返回true还是调用super.onOptionsItemSelected()呢?我认为刚刚被删除的回答的发布者是正确的,但不幸的是它已经消失了。 - Bö macht Blau
1
抱歉,我不得不删除我的回答,因为有些垃圾邮件发送者。 - shinilms
1
@Shinil M S - 是的,有点粗鲁。我正要标记这条评论时,整个帖子突然消失了。你能恢复它吗?关于从Activity方法中返回false的问题,你是100%正确的 - 我刚刚检查了我的一个(正常运行的)应用程序来确认。 - Bö macht Blau
1
@ShinilMS,请检查我提供的推荐方法的答案。 - JAAD
显示剩余9条评论
3个回答

7

对于未来的访问者,您应在Activity类中使用以下内容:

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

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


“硬编码”听起来像是“禁忌”。我一直认为返回“true”意味着我的方法处理了事件,而返回“false”则意味着我不感兴趣,让下一个有机会。这真的只是风格问题吗?也就是说,如果我知道还有其他感兴趣的人。 - Bö macht Blau
从方法文档中,派生类应该通过调用基类来执行默认菜单处理。- @0X0nosugar - JAAD
@0X0nosugar,你说的关于true和false的是对的,但我的观点只是关于硬编码的。 - JAAD
谢谢 :) 我在思考这些最后几分钟,我在其他评论中的最后一句话是为什么调用super被认为是一个好习惯的一个很好的理由。维护等等。 - Bö macht Blau

1
在你的Activity中添加这个。
@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不会被调用。因此,请在您的Activity的onOptionsItemSelected方法或父类实现中通过super.onOptionsItemSelected调用返回false(默认实现返回false)。 - shinilms
我认为你必须从Activity方法中返回false。 - Bö macht Blau
是的,那就是我想表达的意思。FragmentActivity是与该片段连接的活动。 - shinilms
好的,显然有时候会出错 :-( 也许可以说类似于“托管活动”? - Bö macht Blau

0

onCreateOptionsMenu 中缺少 super call

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接