Элементы панели действий дублируют
В моем приложении есть панель действий. Я добавляю элементы действия, используя menu.xml. Я использую action-bar-compat в качестве моей библиотеки поддержки. Я заметил странную проблему, в которой мои элементы действия дублируются.
Я нахожу эту проблему случайным образом, когда мое устройство не работает или работает с другими приложениями. Пожалуйста, найдите снимок экрана и мой код ниже:
private LoginWebActivity mContext;
private final String TAG = "LoginFragment";
// for metrics
private String mPageNameSignIn = "signin";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.webview, container, false);
return mView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mContext = (LoginWebActivity) getActivity();
initFragment();
}
@Override
public void onResume() {
super.onResume();
}
/**
* Initialises the views and variables of the fragment.
*/
@SuppressLint({ "JavascriptInterface", "SetJavaScriptEnabled" })
protected void initFragment() {
mWebView = (WebView) mView.findViewById(R.id.webView);
Bundle b = mContext.getIntent().getExtras();
if (b != null) {
mUrl = b.getString(Constants.EXTRA_WEB_LOGIN_URL);
}
super.initFragment();
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.signin, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Navigate
switch (item.getItemId()) {
case R.id.menu_item_signup:
mContext.onSignUpClick();
break;
case android.R.id.home:
if (!goBack())
getActivity().finish();
default:
break;
}
return super.onOptionsItemSelected(item);
}
Мой XML:
<?xml version="1.0" encoding="utf-8"?>
<item
android:id="@+id/menu_item_signup"
allergy:showAsAction="ifRoom"
android:title="@string/sign_up">
</item>
![enter image description here]()
Ответы
Ответ 1
Перед добавлением элементов необходимо очистить объект меню. У меня была такая же проблема, и это было лучшее решение, которое я нашел.
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.signin, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Ответ 2
Довольно поздно для этой вечеринки, но для тех, кто сталкивается с этим через Google, как я, здесь настоящая проблема.
Вы не опубликовали свой код активности, который создает фрагмент, но я рискну предположить, что он выглядит примерно так:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
Fragment fragment = ...
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
Проблема заключается в том, что, когда активность проходит через свой жизненный цикл (что произойдет "когда мое устройство будет работать без работы или работать с другими приложениями", как вы говорите), система сохранит и восстановит состояние фрагментов для вас, Но с помощью этого кода вы также добавляете новый фрагмент в свою активность, поэтому в конечном итоге вы получаете несколько фрагментов в вашей деятельности, каждый из которых добавляет элемент в меню.
В то время как в распространенном обходном пути будет рассмотрен вопрос о дублировании элементов меню, он оставит эти дополнительные экземпляры фрагментов, что явно не то, что вы хотите.
Правильное исправление - простая проверка нуля:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
if (savedInstanceState == null) {
Fragment fragment = ...
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
Поскольку система будет указывать, что активность воссоздана с ненулевым Bundle для параметра savedInstanceState, вы проверяете это, чтобы определить, нужно ли создавать и добавлять новый фрагмент.
Надеюсь, что это поможет.
Ответ 3
Я использовал отличное решение Renan Bandeira, и у меня была некоторая ошибка, поэтому я немного изменил его и работал у меня тоже. то я делюсь своим опытом: может быть, он снова станет полезным, и все его заслуги за отличное решение.
@Override
public void onCreateOptionsMenu(Menu menu ) {
menu.clear();
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu."your current activity name ", menu);
return true;
}
Ответ 4
Я сталкиваюсь с той же проблемой и точно так же, как состояние by @Szymon "Я добавляю опцию меню из фрагмента, я создаю несколько фрагментов?" Поэтому мое решение было похоже ниже.
onCreate:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.menu, menu);
menu.findItem(R.id.action_one).setVisible(true);
menu.findItem(R.id.action_two).setVisible(false);
super.onCreateOptionsMenu(menu, inflater);
}
onPrepare:
@Override
public void onPrepareOptionsMenu(Menu menu) {
if (isAdded()
&& !isDetached()
&& isVisible()
&& !isRemoving()
)
{
// show the menu
if (menu.findItem(R.id.action_one).isVisible())
menu.findItem(R.id.action_one).setVisible(true);
// hide the menu
if (menu.findItem(R.id.action_two).isVisible())
menu.findItem(R.id.action_two).setVisible(false);
}
}
Ответ 5
Вместо этого вы должны использовать следующий метод, и вы больше не увидите дубликатов (обратите внимание, что он имеет только объект меню в качестве аргумента)
@Override
public boolean onCreateOptionsMenu( Menu menu )
{
getMenuInflater().inflate( R.menu.main_activity_menu, menu );
return true;
}