Меню опций Android во фрагменте



Я пытаюсь добавить элемент в меню "Параметры" из группы фрагментов.



Я создал новый MenuFragment класс и расширил это для фрагментов, в которые я хочу включить пункт меню. Вот код:



public class MenuFragment extends Fragment {

MenuItem fav;

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

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
fav = menu.add("add");
fav.setIcon(R.drawable.btn_star_big_off);
}
}


почему-то onCreateOptionsMenu Кажется, не работает.

698   19  

19 ответов:

вызов супер метод:

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // TODO Add your menu entries here
    super.onCreateOptionsMenu(menu, inflater);
}

поместите инструкции журнала в код, чтобы увидеть, если метод не вызывается или если меню не изменяется вашим кодом.

также убедитесь, что вы звоните SetHasOptionsMenu in onCreate чтобы уведомить фрагмент, что он должен участвовать в обработке меню опций.

у меня была та же проблема, но я думаю, что лучше обобщить и ввести последний шаг, чтобы заставить его работать:

  1. добавьте метод setHasOptionsMenu (true) в свой фрагмент onCreate(Bundle savedInstanceState) метод.

  2. переопределить onCreateOptionsMenu(Menu menu, MenuInflater inflater) (Если вы хотите сделать что-то другое в меню фрагмента) и onOptionsItemSelected(MenuItem item) методы в вашем фрагменте.

  3. внутри onOptionsItemSelected(MenuItem item) метод действия, убедитесь, что вы возвращаете false, когда пункт меню действие будет реализовано в onOptionsItemSelected(MenuItem item) метод фрагмента.

пример:

активность

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        case R.id.activity_menu_item:

            // Do Activity menu item stuff here
            return true;

        case R.id.fragment_menu_item:

            // Not implemented here
            return false;
        default:
            break;
    }

    return false;
}

фрагмент

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // Do something that differs the Activity's menu here
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        case R.id.activity_menu_item:

            // Not implemented here
            return false;
        case R.id.fragment_menu_item:

            // Do Fragment menu item stuff here
            return true;

        default:
            break;
    }

    return false;
}

Если вы найдете onCreateOptionsMenu(Menu menu, MenuInflater inflater) метод не вызывается, убедитесь, что вы звоните следующей из фрагмента onCreate(Bundle savedInstanceState) способ:

setHasOptionsMenu(true)

В моем случае, мне нужно меню, чтобы обновить webview внутри определенного фрагмента, для этого я использовал:

фрагмент:

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

    // TODO Add your menu entries here
    inflater.inflate(R.menu.menu, menu);
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.exit:
        System.exit(1);
        break;

    case R.id.refresh:
        webView.reload();
        break;
    }
    return true;

}

меню "Файл".xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/exit" android:title="Exit" android:icon="@drawable/ic_action_cancel" />
    <item android:id="@+id/refresh" android:title="Refresh" android:icon="@drawable/ic_action_refresh" />
</menu>

на menu.xml вы должны добавить все пункты меню. Затем вы можете скрыть элементы, которые вы не хотите видеть в исходной загрузки.

.xml

<item
    android:id="@+id/action_newItem"
    android:icon="@drawable/action_newItem"
    android:showAsAction="never"
    android:visible="false"
    android:title="@string/action_newItem"/>

добавить setHasOptionsMenu(true) в методе onCreate () для вызова элементов меню в вашем классе фрагментов.

FragmentClass.java

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

вам не нужно переопределять onCreateOptionsMenu в вашем классе фрагментов снова. Пункты меню можно изменить (добавить/удалить) путем переопределения onPrepareOptionsMenuметод доступен в фрагменте.

@Override
public void onPrepareOptionsMenu(Menu menu) {
    menu.findItem(R.id.action_newItem).setVisible(true);
    super.onPrepareOptionsMenu(menu);

}

вы должны использовать меню.очистить () перед раздуванием меню.

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

и

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

В моем случае, вот шаги.

Шаг 1

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

    // Here notify the fragment that it should participate in options menu handling.
    setHasOptionsMenu(true);
}

Шаг 2

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // First clear current all the menu items
    menu.clear();

    // Add the new menu items
    inflater.inflate(R.menu.post_stuff, menu);

    super.onCreateOptionsMenu(menu, inflater);
}

Шаг 3

 @Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.post_stuff:
            Log.d(TAG, "Will post the photo to server");
            return true;
        case R.id.cancel_post:
            Log.d(TAG, "Will cancel post the photo");
            return true;
        default:
            break;
    }
    return super.onOptionsItemSelected(item);
}

У меня была такая же проблема, мои фрагменты страницы ViewPager. Причина, по которой это происходило, заключается в том, что я использовал child fragment manager, а не диспетчер фрагментов поддержки активности при создании экземпляра FragmentPagerAdapter.

Если вы хотите добавить меню custom

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

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

меню Файл:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/play"
        android:titleCondensed="Speak"
        android:showAsAction="always"
        android:title="Speak"
        android:icon="@drawable/ic_play">
    </item>
    <item
        android:id="@+id/pause"
        android:titleCondensed="Stop"
        android:title="Stop"
        android:showAsAction="always"
        android:icon="@drawable/ic_pause">
    </item>
</menu>

код операции:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.speak_menu_history, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        case R.id.play:
            Toast.makeText(getApplicationContext(), "speaking....", Toast.LENGTH_LONG).show();
            return false;

        case R.id.pause:
            Toast.makeText(getApplicationContext(), "stopping....", Toast.LENGTH_LONG).show();
            return false;

        default:
            break;
    }

    return false;
}

фрагмент кода:

@Override

public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        case R.id.play:
            text = page.getText().toString();
            speakOut(text);

            // Do Activity menu item stuff here
            return true;

        case R.id.pause:
            speakOf();

            // Not implemented here
            return true;

        default:
            break;
    }
    return false;
}

ваш код в порядке. Только супер не хватало в методе:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // TODO add your menu : 
    inflater.inflate(R.menu.my_menu, menu);
    //TODO call super
    super.onCreateOptionsMenu(menu, inflater);
}

Я сходил с ума, потому что ни один из ответов здесь не работал для меня.

чтобы показать меню мне пришлось позвонить:setSupportActionBar(toolbar)

готово!

Примечание: Если ваш toolbar вид не находится в том же макете активности вы не можете использовать вызов выше непосредственно из вашего класса активности, в этом случае вам нужно будет получить эту активность из вашего класса фрагмента, а затем вызвать setSupportActionBar(toolbar). Запоминание: ваш класс активности должен расширять AppCompatActivity.

надеемся, что этот ответ поможет вам.

TL; DR

использовать android.support.v7.widget.Toolbar и вобще:

toolbar.inflateMenu(R.menu.my_menu)
toolbar.setOnMenuItemClickListener {
    onOptionsItemSelected(it)
}

Автономная Панель Инструментов

большинство предлагаемых решений, как setHasOptionsMenu(true) работают только тогда, когда родительская активность имеет панель инструментов в своем макете и объявляет его через setSupportActionBar(). Тогда фрагменты могут участвовать в населении меню именно этого ActionBar:

фрагмент.onCreateOptionsMenu(): инициализировать содержимое Меню стандартных опций хоста фрагмента.

если вы хотите отдельную панель инструментов и меню для одного конкретного фрагмента вы можете сделать следующее:

menu_custom_fragment.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_save"
        android:title="SAVE" />
</menu>

custom_fragment.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    ...

CustomFragment.КТ

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(layout.custom_fragment, container, false)
    val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
    toolbar.inflateMenu(R.menu.menu_custom_fragment)
    toolbar.setOnMenuItemClickListener {
        onOptionsItemSelected(it)
    }
    return view
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.menu_save -> {
            // TODO: User clicked the save button
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

Да, это так просто. Вам даже не нужно переопределять onCreate() или onCreateOptionsMenu().

PS: это работает только с android.support.v4.app.Fragment и android.support.v7.widget.Toolbar (также обязательно используйте AppCompatActivity и AppCompat темы в своем styles.xml).

настройка меню параметров после создания фрагментного представления хорошо работала для меня.

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

моя проблема была немного другая. Я все сделал правильно. Но я наследовал неправильный класс для действия, содержащего фрагмент.

поэтому, чтобы быть ясным, если вы переопределяете onCreateOptionsMenu(Menu menu, MenuInflater inflater) во фрагменте убедитесь, что ваш класс activity, который содержит этот фрагмент, наследует android.support.v7.app.ActionBarActivity (в случае, если вы хотите поддерживать ниже уровня API 11).

я унаследовал android.support.v4.app.FragmentActivity для поддержки уровня API ниже 11.

одна вещь, которую я бы добавил к этому, и причина, по которой это не работает для меня.

это похоже на ответ Napster.

  1. убедитесь, что активность хостинга вашего фрагмента расширяется AppCompatActivity, а не FragmentActivity!

    public class MainActivity extends AppCompatActivity {
    
    }
    

    из ссылки Google документация для FragmentActivity:

    Примечание: Если вы хотите осуществлять деятельность, которая включает в себя панель действий, вы должны вместо этого использовать класс ActionBarActivity, который является подклассом этого, поэтому позволяет использовать фрагмент API на уровне API 7 и выше.

  2. чтобы обновить ответ Napster -- ActionBarActivity теперь устарели, используйте AppCompatActivity вместо.

  3. при использовании AppCompatActivity, также убедитесь, что вы установили "тема деятельностиTheme.AppCompat или аналогичная тема " (Google Doc).

Примечание: android.support.v7.app.AppCompatActivity является наследником android.support.v4.app.FragmentActivity класса (см. AppCompatActivity ref doc).

в папке меню сделать .меню XML-файл и добавить этот XML

<item
    android:id="@+id/action_search"
    android:icon="@android:drawable/ic_menu_search"
    android:title="@string/action_search"
    app:actionViewClass="android.support.v7.widget.SearchView"
    app:showAsAction="always|collapseActionView" />

в вашем классе фрагментов переопределите этот метод и

implement SearchView.OnQueryTextListener    in your fragment class



@Override
 public void onViewCreated(View view, Bundle savedInstanceState) {    
  super.onViewCreated(view, savedInstanceState);
  setHasOptionsMenu(true);

}

Теперь просто настроить меню xml-файл в классе фрагмента

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

    final MenuItem item = menu.findItem(R.id.action_search);
    final SearchView searchView = (SearchView)    
    MenuItemCompat.getActionView(item);


    MenuItemCompat.setOnActionExpandListener(item,
            new MenuItemCompat.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    // Do something when collapsed

                    return true; // Return true to collapse action view
                }

                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    // Do something when expanded
                    return true; // Return true to expand action view
                }
            });

}

Если все вышеперечисленное не работает, вам нужно отладить и убедиться, что функция onCreateOptionsMenu была вызвана (путем размещения debug или write log...)

если он не запущен, возможно, ваша тема Android не поддерживает панель действий. Открываем AndroidManifest.xml и установите значение для android:theme с темой поддержки панели действий:

 <activity
     android:name=".MainActivity"
     android:label="@string/app_name"
     android:theme="@style/Theme.AppCompat">

на onCreate метод add setHasOptionMenu ()

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

затем переопределить код onCreateOptionsMenu

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    menu.add("Menu item")
            .setIcon(android.R.drawable.ic_delete)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}

Comments

    Ничего не найдено.