Cara menambahkan Menu Opsi ke Fragmen di Android

399

Saya mencoba menambahkan item ke menu opsi dari sekelompok fragmen.

Saya telah membuat yang baru MenuFragment kelas dan memperluas ini untuk fragmen yang saya ingin sertakan item menu masuk. Berikut adalah kode:

Jawa:

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);
    }
}

Kotlin:

class MenuFragment : Fragment {

    lateinit var fav: MenuItem

    override fun onCreate(savedInstanceState: Bundle) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }

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

Untuk beberapa alasan onCreateOptionsMenutampaknya tidak berjalan.

misterbassman
sumber
mungkin pertanyaan konyol ... Anda menekan tombol menu kan?
Ovidiu Latcu
2
..lol ... ya saya telah menekan tombol menu, saya juga sudah mencobanya dengan dan tanpa: fav.setShowAsAction (MenuItem.SHOW_AS_ACTION_ALWAYS);
misterbassman
Hai, mungkin utas ini akan membantu Anda atau memeriksa demo api untuk contoh yang berfungsi.
kameny

Jawaban:

605

Panggil metode super:

Jawa:

    @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);
    }

Kotlin:

    override fun void onCreate(savedInstanceState: Bundle) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        // TODO Add your menu entries here
        super.onCreateOptionsMenu(menu, inflater)
    }

Masukkan pernyataan log dalam kode untuk melihat apakah metode ini tidak dipanggil atau jika menu tidak diubah oleh kode Anda.

Juga memastikan Anda menelepon setHasOptionsMenu(boolean)di onCreate(Bundle)untuk memberitahu fragmen yang harus berpartisipasi dalam penanganan pilihan menu.

Kuffs
sumber
2
Terima kasih atas bantuannya, saya menambahkan metode super, dan menyadari bahwa saya telah menghapus @Override sehingga menambahkan ini kembali, gerhana melemparkan kesalahan jadi saya mengganti MenuInflater untuk mengimpor android.view.MenuInflater; alih-alih mengimpor android.support.v4.view.MenuInflater; dan sekarang semuanya bekerja
misterbassman
183
tidak memanggil setHasOptionsMenu (true) di onCreate Fragment telah membuat saya dua kali sekarang
joshkendrick
7
Saya mentransfer Aktivitas saya ke Fragmen dan mengalami masalah ini. Metode tanda tangan telah berubah dari boolean publik menjadi public void dan argumennya juga telah berubah. Pastikan untuk mencatat ini!
you786
14
Perhatikan bahwa Fragment.onCreateOptionsMenu (Menu, MenuInflater) adalah metode kosong, jadi memanggil super tidak diperlukan sama sekali. Satu-satunya kesalahan di sini adalah metode tanda tangan yang salah dan mungkin setHasOptionsMenu () yang hilang di onCreate ()
cmende
6
Ganti super.onCreateOptionsMenu dengan inflater.inflate (R.menu.menu_custom, menu);
Code_Worm
197

Saya memiliki masalah yang sama, tetapi saya pikir lebih baik merangkum dan memperkenalkan langkah terakhir untuk membuatnya bekerja:

  1. Tambahkan metode setHasOptionsMenu (true) dalam metode Fragment Anda onCreate(Bundle savedInstanceState).

  2. Ganti onCreateOptionsMenu(Menu menu, MenuInflater inflater)(jika Anda ingin melakukan sesuatu yang berbeda di menu Fragmen Anda) dan onOptionsItemSelected(MenuItem item)metode di Fragmen Anda.

  3. Di dalam onOptionsItemSelected(MenuItem item)metode Aktivitas Anda , pastikan Anda mengembalikan false ketika tindakan item menu akan diterapkan dalam onOptionsItemSelected(MenuItem item)metode Fragment.

Sebuah contoh:

Aktivitas

@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;
}

Pecahan

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;
}
Marco HC
sumber
2
Baru saja hilang. setHasOptionsMenu(true);Terima kasih
Chad Bingham
1
Pada tampilanPager pada beberapa perangkat menu hanya ditampilkan saat Anda pergi ke fragmen
Roel
3
@ Marco HC kode Anda berfungsi dengan baik. Tetapi bagaimana jika saya ingin menyembunyikan beberapa menu untuk Aktivitas atau untuk Fragmen? Anda telah menyebutkan tentang di mana menerapkan menu opsi mana (Dalam aktivitas dan fragmen). Tetapi bagaimana jika saya ingin menyembunyikan beberapa menu?
Shreyash Mahajan
@ iDroidExplorer hanya menyimpan referensi ke MenuItem itu dan mengatur visibilitas menjadi hilang atau tidak terlihat. Apakah itu pertanyaan Anda?
Marco HC
@ iDroidExplorer Saya mencoba kodenya dan saya tidak tahu caranya tetapi secara otomatis menyembunyikan menu ketika saya beralih ke fragmen lain.
Noor Ali Butt
156

Jika Anda menemukan onCreateOptionsMenu(Menu menu, MenuInflater inflater)metode ini tidak dipanggil, pastikan Anda memanggil yang berikut dari metode Fragment onCreate(Bundle savedInstanceState):

setHasOptionsMenu(true)
Matthew Blackford
sumber
Ini memberi saya Kesalahan seperti NullPointerException
Pratik Butani
2
Poin yang bagus. Saya memanggil metode setHasOptionMenu dari metode newInstance statis. Karena saya hanya melampirkan fragmen saya ketika saveInstanceState adalah nol, ketika konfigurasi layar berubah menu tidak akan dibuat. Metode onCreate dari fragmen adalah tempat yang benar untuk mengatur setHasOptionMenu menjadi true.
argenkiwi
1
Saya menggunakan Toolbardan memanggil setHasOptionsMenu(true)di onCreateView()bukannya onCreate()untuk menyelesaikannya.
CLOUGH
60

Jika Anda perlu menumenyegarkan bagian webviewdalam tertentu Fragment, Anda dapat menggunakan:

Fragmen :

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;

}

menu.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>
HUBUNGI19
sumber
31

TL; DR

Gunakan android.support.v7.widget.Toolbardan lakukan saja:

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

Toolbar Mandiri

Sebagian besar solusi yang disarankan seperti setHasOptionsMenu(true)hanya berfungsi ketika Aktivitas induk memiliki Bilah Alat di tata letaknya dan mendeklarasikannya melalui setSupportActionBar(). Kemudian Fragmen dapat berpartisipasi dalam populasi menu dari ActionBar yang tepat ini :

Fragment.onCreateOptionsMenu (): Menginisialisasi konten menu opsi standar host Fragmen.

Jika Anda menginginkan toolbar dan menu mandiri untuk satu Fragmen spesifik, Anda dapat melakukan hal berikut:

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.kt

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)
    }
}

Ya itu mudah. Anda bahkan tidak perlu mengganti onCreate()atauonCreateOptionsMenu() .

PS: Ini hanya bekerja dengan android.support.v4.app.Fragmentdan android.support.v7.widget.Toolbar(juga pastikan untuk menggunakan AppCompatActivitydan AppCompattema di Anda styles.xml).

Marius
sumber
1
benar-benar banyak membantu saya
brahmy adigopula
23

Dalam menu.xmlAnda harus menambahkan semua item menu. Kemudian Anda dapat menyembunyikan item yang tidak ingin Anda lihat di pemuatan awal.

menu.xml

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

Tambahkan setHasOptionsMenu(true)metode onCreate () untuk memanggil item menu di kelas Fragment Anda.

FragmentClass.java

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

Anda tidak perlu mengganti onCreateOptionsMenukelas Fragment Anda lagi. Item menu dapat diubah (Tambah / hapus) dengan mengganti onPrepareOptionsMenumetode yang tersedia di Fragment.

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

}
Parinda Rajapaksha
sumber
16

Anda perlu menggunakan menu.clear () sebelum menggembungkan menu.

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

dan

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
Spl2nky
sumber
1
Ini benar ketika Anda menginginkan menu yang berbeda dalam fragmen yang berbeda dan Anda menambahkan fragmen alih-alih menggantinya.
Akshay Mahajan
Terima kasih! menu.clear () bantu saya menghapus opsi menu Activity.
kimcy929
13

Dalam kasus saya, berikut adalah langkah-langkahnya.

Langkah 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);
}

Langkah 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);
}

Langkah-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);
}
Harry Zhang
sumber
Saya sudah memiliki menu pada aktivitas utama, menggunakan menu.clear()menu yang sudah dihapus sebelumnya. Bekerja untuk saya :)
Anbuselvan Rocky
8

Jika Anda ingin menambahkan menu kustom Anda

@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);
}
Ezequiel García
sumber
bagaimana jika ada tampilan tab dan Anda ingin mengembang menu yang berbeda untuk setiap fragmen?
Jainam Jhaveri
7

Saya memiliki masalah yang sama, fragmen saya adalah halaman-halaman ViewPager. Alasan hal itu terjadi adalah karena saya menggunakan manajer fragmen anak daripada manajer fragmen dukungan aktivitas saat instantiating FragmentPagerAdapter.

farid_z
sumber
3

File 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>

Kode aktivitas:

@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;
}

Kode fragmen:

@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;
}
Suyog Gunjal
sumber
3

Kode Anda baik-baik saja. Hanya super yang hilang dalam metode:

@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);
}
AlexPad
sumber
2

Saya menjadi gila karena tidak ada jawaban di sini yang bekerja untuk saya.

Untuk menunjukkan menu yang harus saya panggil: setSupportActionBar(toolbar)

Selesai!

Catatan: jika toolbartampilan Anda tidak dalam tata letak aktivitas yang sama Anda tidak dapat menggunakan panggilan di atas langsung dari kelas aktivitas Anda, dalam hal ini Anda harus mendapatkan aktivitas itu dari kelas fragmen Anda dan kemudian memanggilsetSupportActionBar(toolbar) . Mengingat: kelas aktivitas Anda harus memperluas AppCompatActivity.

Semoga jawaban ini membantu Anda.

Filipe Brito
sumber
1

Pengaturan menu opsi setelah membuat tampilan fragmen bekerja dengan baik untuk saya.

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

Masalah saya sedikit berbeda. Saya melakukan segalanya dengan benar. Tetapi saya mewarisi kelas yang salah untuk aktivitas yang menampung fragmen tersebut.

Jadi untuk menjadi jelas, jika Anda menimpa onCreateOptionsMenu(Menu menu, MenuInflater inflater)fragmen, pastikan kelas aktivitas Anda yang menjadi tuan rumah fragmen iniandroid.support.v7.app.ActionBarActivity (jika Anda ingin mendukung di bawah API level 11).

Saya mewarisi android.support.v4.app.FragmentActivityuntuk mendukung level API di bawah 11.

Krishna Deepak
sumber
1

Satu hal yang akan saya tambahkan ke sini dan alasan itu tidak berhasil untuk saya.

Ini mirip dengan jawaban Napster.

  1. Pastikan aktivitas hosting fragmen Anda meluas AppCompatActivity, tidak FragmentActivity!

    public class MainActivity extends AppCompatActivity {
    
    }

    Dari Dokumentasi Referensi Google untuk FragmentActivity:

    Catatan: Jika Anda ingin menerapkan aktivitas yang menyertakan bilah tindakan, Anda harus menggunakan kelas ActionBarActivity, yang merupakan subkelas dari yang ini, jadi memungkinkan Anda untuk menggunakan API Fragmen pada API level 7 dan lebih tinggi.

  2. Untuk memperbarui jawaban Napster - ActionBarActivitysekarang sudah tidak digunakan lagi, gunakan AppCompatActivitysaja.

  3. Saat menggunakan AppCompatActivity, pastikan juga Anda mengatur "tema aktivitas Theme.AppCompatatau tema serupa" (Google Doc).

Catatan: android.support.v7.app.AppCompatActivityadalah subclass dari android.support.v4.app.FragmentActivitykelas (lihat AppCompatActivity ref doc).

bastien
sumber
1

Di folder menu Anda, buat file .menu xml dan tambahkan xml ini

<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" />

Di kelas fragmen Anda, overide metode ini dan

implement SearchView.OnQueryTextListener    in your fragment class



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

}

Sekarang hanya mengatur file xml menu Anda di kelas fragmen

@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
                }
            });

}
pavel
sumber
0

Jika semua hal di atas tidak berfungsi, Anda perlu men-debug dan memastikan fungsi onCreateOptionsMenu telah dipanggil (dengan menempatkan debug atau menulis log ...)

Jika tidak berjalan, mungkin tema Android Anda tidak mendukung bilah tindakan. Buka AndroidManifest.xml dan tetapkan nilai untuk android:themedengan bilah tindakan dukungan tema :

 <activity
     android:name=".MainActivity"
     android:label="@string/app_name"
     android:theme="@style/Theme.AppCompat">
Serigala abu-abu
sumber
0

pada metode onCreate Anda, tambahkan setHasOptionMenu ()

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

Kemudian timpa onCreateOptionsMenu Anda

@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);
}
Ashana.Jackol
sumber