【问题标题】:When I open new layouts, the menu item duplicates当我打开新布局时,菜单项重复
【发布时间】:2020-07-22 01:03:51
【问题描述】:

我正在学习如何创建一个应用程序,并且已经知道如何构建一个登录活动和一个用于注销的菜单,以使您返回登录布局。但是,如果我浏览不同的布局/活动,则用于注销重复项的菜单项。我相信这是由于在每个布局上都创建了菜单,但我不确定如何更改它以使其不会重复。

这是我的片段。

    public class UserFragment extends Fragment {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
        savedInstanceState) {
    return inflater.inflate(R.layout.activity_user_fragment, container, false);
}

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

我的 LoginActivity.class

public class LoginActivity extends AppCompatActivity{

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

    setContentView(R.layout.activity_login);

    Button b1login = (Button) findViewById(R.id.btlogin);
    Button b2login_cancel = (Button) findViewById(R.id.btcancel_login);

    assert b1login != null;
    b1login.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            EditText ed1 = (EditText) findViewById(R.id.etuser_name);
            EditText ed2 = (EditText) findViewById(R.id.etpassword);
            if (ed1.getText().toString().equals(getText(R.string.user_id)) &&
                    ed2.getText().toString().equals(getText(R.string.user_password))) {
                Toast.makeText(getApplicationContext(), R.string.successful_login,
                        Toast.LENGTH_SHORT).show();
                setContentView(R.layout.activity_clients);


            } else {
                Toast.makeText(getApplicationContext(), R.string.unsuccessful_login,
                        Toast.LENGTH_SHORT).show();
            }
        }
    });

    assert b2login_cancel != null;
    b2login_cancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            System.exit(0);
        }
    });
}

//Menu option logout return to login screen.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.menu_item_logout) {
        Intent i = new Intent(this, LoginActivity.class);
        this.startActivity(i);
        return true;
    }
    return super.onOptionsItemSelected(item);
}



public void addClient(View view) {
    setContentView(R.layout.activity_new_client);
}

public void submitClient(View view) {
    setContentView(R.layout.activity_sessions);
}

public void cancelClient(View view) {
    setContentView(R.layout.activity_clients);
}


public void newSession(View view) {
    setContentView(R.layout.activity_new_session);
}

public void cancelSessionCompletion(View view) {
    setContentView(R.layout.activity_sessions);
}

public void cancelSession(View view) {
    setContentView(R.layout.activity_sessions);
}
}

片段布局。

<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
    android:id="@+id/menu_item_logout"
    android:icon="@drawable/ic_logout"
    android:title="@string/logout"
    app:showAsAction="ifRoom|withText" />
</menu

编辑:

我删除了最初创建菜单的片段以及 UserFragment 中的菜单代码,并将菜单本身硬编码到 LoginActivity 类中,从而解决了重复问题。

代码添加菜单。

    @Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.menu, menu);
    return true;
    }

但是,菜单现在显示在登录屏幕上。如何防止它在那里显示?

【问题讨论】:

  • 是的,您肯定不想在 LoginActivity 中出现任何 Logout 菜单,因为此时用户甚至还没有登录?
  • 菜单没有显示在登录屏幕上,因为我已将其设置为加载显示用户登录时显示用户名的片段。
  • 现在我已经修复了重复问题,它显示在登录屏幕上。有什么想法吗?

标签: android android-layout android-fragments android-studio menuitem


【解决方案1】:

为了在不同的活动中拥有不同的菜单项,您需要创建不同的菜单 xml 布局。

所以 res 文件夹中已经有一个名为 menu.xml 的文件。您需要在同一文件夹中创建新的 xml 文件。

然后在该活动的 java 代码中:- 在覆盖 Oncreateoptionmenu 中膨胀您想要的菜单。

【讨论】:

  • 我希望在所有活动中显示相同的菜单项(注销)。发生的事情是当我加载新布局时,菜单被复制了。
  • 然后在所有要显示相同菜单的活动中,只需将 inflate.inflate(在 OnCreateOptionMenu 中)项更改为相同的 xml 文件名。
  • 如果我没有以正确的方式回答您的问题,请告诉我。
  • 我修复了重复问题。该片段导致在每次布局调用时重新创建菜单。但是,菜单现在显示在登录屏幕上。关于阻止它显示的任何想法?
  • 好吧,Ankesh,你的回答奏效了。我的问题是我缺乏理解多个布局和类之间的关系。我只有最初的 LoginActivity.class 做所有的工作,这导致了我最初的帖子的问题,以及其他并发症。我创建了几个新课程并提出了一些意图,然后按照您所说的去做。这解决了它。
【解决方案2】:

这是你需要做的:

  • 在 LoginActivity 类中,您不想让菜单膨胀,因为您不希望用户看到注销选项。
  • 在登录后加载的 Activity 中,您实际上希望扩大“注销”菜单 - 嗯,因为您希望他们看到并使用该选项。

在您的代码中,我看到您的片段使用了该方法:

setHasOptionsMenu(true);

您可以在这里做的是使用 if 语句来查看用户之前是否登录过,如果没有,则将其设置为 true,否则不执行任何操作(就像设置为 false)。

如果您希望用户能够从这些活动中注销或将其排除在外,您可以在其他活动中重复使用该菜单!

我希望这会有所帮助!

编辑

根据您上面的示例代码,您的第一部分显示了您将在 Fragment 类中执行的操作 - 您 setHasOptionsMenu(true)。现在,您似乎有两个注销菜单,在活动和片段中 - 我看不到您在 LoginActivity 中使用片段的位置 - 除非它在不同活动中的其他地方!

【讨论】:

  • 我认为您的 Activity 可能正在重用片段?
  • 我将片段设置为显示用户的用户名,所以也许每个新布局都会重新创建它并复制菜单?让我的按钮启动一个意图并运行一个实际的新活动来设置它的布局而不是让按钮自己调用布局会更好吗?
  • 正确,我的片段被编码到我其他布局的 xml 中。
  • 好的,我修复了重复问题。该片段在每个布局调用上复制菜单。但是,我需要隐藏菜单以使其不显示在登录屏幕上。有什么想法吗?
  • 在你的LoginActivity里面,基本上去掉optionsMenu的代码就看不到菜单了;
【解决方案3】:

与我在这里的回答类似,https://stackoverflow.com/a/63008005/5916188,解决方法是每次都删除菜单(如果存在),然后再添加。

请注意,现有的菜单是逐项删除的(R.id...),而膨胀的菜单是由菜单(R.menu...)照常添加的。

这样,您可以将菜单保留在片段中。像这样:

    @Override public void onCreateOptionsMenu (@NonNull Menu menu, @NonNull MenuInflater
        inflater)
{
    super.onCreateOptionsMenu (menu, inflater);

    removeMenuItemIfPresent (menu, R.id.menu_search_options);
    removeMenuItemIfPresent (menu, R.id.menu_sample_filter1);
    removeMenuItemIfPresent (menu, R.id.menu_sample_filter2);

    inflater.inflate (R.menu.menu_search_menu, menu);        
}

private void removeMenuItemIfPresent (@NonNull Menu menu, int resourceIDToRemove)
{
        MenuItem menuItemToRemove = menu.findItem (resourceIDToRemove);

        if (menuItemToRemove != null) {
            menu.removeItem (menuItemToRemove.getItemId ());
    }
}

【讨论】:

    猜你喜欢
    • 2018-02-22
    • 2015-03-29
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多