OnCreateOptionsMenu () tidak dipanggil di Fragment

107

Saya memiliki aplikasi yang mendapat satu aktivitas dengan 2 fragmen ditempatkan secara horizontal.

Dalam aktivitas saya, saya menggembungkan menu onCreateOptionsMenu()yang dengannya saya dapat menampilkan menu opsi bilah tindakan. Tetapi ketika saya mencoba memperbarui item menu bilah tindakan dari salah satu fragmen saya, onCreateoptionsmenu()itu tidak dipanggil. Jadi, saya tidak dapat memperbarui menu opsi bilah tindakan.

Kode dalam aktivitas saya adalah sebagai berikut:

myActivity.java

package com.andr.androidtablelist;

import java.io.IOException;

import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

import com.andr.fragments.ListLeftFragment;
import com.andr.utils.DBHelper;

      public class TabletActivity extends Activity {
    ActionBar actionBar = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DBHelper dbhelper;
        dbhelper = new DBHelper(this);
        try {
            dbhelper.createDatabase();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        setContentView(R.layout.activity_tablet);
        actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(false);
        getFragmentManager().beginTransaction()
                .replace(R.id.master, ListLeftFragment.newInstance()).commit();
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            Toast.makeText(
                    getApplicationContext(),
                    "Back Stack Count::"
                            + getFragmentManager().getBackStackEntryCount(),
                    Toast.LENGTH_LONG).show();
            if (getFragmentManager().getBackStackEntryCount() == 1) {
                actionBar.setDisplayHomeAsUpEnabled(false);
            }
            if (getFragmentManager().getBackStackEntryCount() > 1) {
                getFragmentManager().popBackStack();

            }
            return true;

        }
        return super.onOptionsItemSelected(item);
    }

}
      // http://www.vogella.com/articles/AndroidListView/article.html

myFragment.java

      package com.andr.fragments;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;

import com.andr.androidtablelist.R;
import com.andr.helper.LazyHelper;

   public class ListLeftFragment extends Fragment{
    private static ListLeftFragment listFragment = null;

    public static ListLeftFragment newInstance(){
        listFragment = new ListLeftFragment();      
        return listFragment;
    }

     @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);


    }

     @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
         View v =  inflater.inflate(R.layout.fragment_listlayout, container,false);
         getActivity().invalidateOptionsMenu();
         ListView lv = (ListView)v.findViewById(R.id.lview);
         String[] values = new String[] { "Android", "iPhone", "WindowsMobile",
                    "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X",
                    "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux",
                    "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",
                    "Android", "iPhone", "WindowsMobile" };
         getActivity().getActionBar().setTitle("LeftList");

          ArrayList<String> list = new ArrayList<String>();
         LazyHelper lHelper = new LazyHelper(getActivity());
         list = lHelper.getLazyDetials();

           /* for (int i = 0; i < values.length; ++i) {
              list.add(values[i]);
            }
            final StableArrayAdapter adapter = new StableArrayAdapter(getActivity(),
                android.R.layout.simple_list_item_1, list);*/
            LeftListAdapter lAdapter = new LeftListAdapter(getActivity(),list);
            lv.setAdapter(lAdapter);
            lv.setOnItemClickListener(new OnItemClickListener()
            {

                @Override
                public void onItemClick(AdapterView<?> arg0, View arg1,
                        int pos, long arg3) {
                    final String clickedData = (String)arg0.getItemAtPosition(pos);
                    Bundle bundle = new Bundle();
                    bundle.putString("clickedItemName", clickedData);
                    Fragment detailFragment = DetailFormRightFragment.newInstance();
                    detailFragment.setArguments(bundle);
                    getActivity().getFragmentManager().beginTransaction().replace(R.id.details, detailFragment).addToBackStack(null).commit();
                }

            }
                    );
         return v;
    }


     @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        getActivity().getMenuInflater().inflate(R.menu.search, menu);
        SearchView searchView=(SearchView)menu.findItem(R.id.search);
        searchView.setIconifiedByDefault(true);
    } 

     @Override
    public boolean onOptionsItemSelected(MenuItem item) {

         super.onOptionsItemSelected(item);
         return false;
    }


     @Override
    public void onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
        /*MenuItem item;
        menu.clear();
        getActivity().getMenuInflater().inflate(R.menu.search, menu);
        SearchView searchView=(SearchView)menu.findItem(R.id.search);
        searchView.setIconifiedByDefault(true);*/
    }

     private class StableArrayAdapter extends ArrayAdapter<String> {

            HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();

            public StableArrayAdapter(Context context, int textViewResourceId,
                List<String> objects) {
              super(context, textViewResourceId, objects);
              for (int i = 0; i < objects.size(); ++i) {
                mIdMap.put(objects.get(i), i);
              }
            }

            @Override
            public long getItemId(int position) {
              String item = getItem(position);
              return mIdMap.get(item);
            }

            @Override
            public boolean hasStableIds() {
              return true;
            }

          }

     private class LeftListAdapter extends BaseAdapter implements OnClickListener {
         private Context mcontext;
         ArrayList<String> listData;
         private  LayoutInflater inflater=null;
         public LeftListAdapter(Context context, ArrayList<String> listItems) {
              mcontext=context;
              listData=listItems;
              inflater = (LayoutInflater)mcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         }

        @Override
        public int getCount() {
            return listData.size();
        }

        @Override
        public Object getItem(int arg0) {
            return null;
        }

        @Override
        public long getItemId(int arg0) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public View getView(int position, View view, ViewGroup arg2) {
            // create a ViewHolder reference
            View vi=view;
            if(vi==null){
                vi = inflater.inflate(R.layout.item, null);
            }
            TextView text=(TextView)vi.findViewById(R.id.text);
            text.setText(listData.get(position));
            vi.setOnClickListener(this);
            return vi;
        }

        @Override
        public void onClick(View vi) {
            TextView text=(TextView)vi.findViewById(R.id.text);
            Bundle bundle = new Bundle();
            bundle.putString("clickedItemName", text.getText().toString());
            Fragment detailFragment = DetailFormRightFragment.newInstance();
            detailFragment.setArguments(bundle);
            getActivity().getFragmentManager().beginTransaction().replace(R.id.details, detailFragment).addToBackStack(null).commit();          
        }

     }
   }
Android_programmer_office
sumber

Jawaban:

296

Dalam onCreateView()metode fragmen , Anda perlu memanggil setHasOptionsMenu(true)untuk memberi tahu aktivitas host bahwa fragmen Anda memiliki opsi menu yang ingin ditambahkan.

dangVarmit
sumber
Saya melakukan perubahan, tetapi aplikasi macet dengan 11-27 01: 55: 34.468: E / AndroidRuntime (12294): Disebabkan oleh: java.lang.ClassCastException: com.android.internal.view.menu.MenuItemImpl tidak dapat dilemparkan ke android .widget.SearchView
Android_programmer_office
ya saya menemukan masalahnya. lupa menambahkan getActionView () untuk searchView.
Android_programmer_office
2
Anda juga harus menggunakan tipe void untuk onCreateOptionsMenu (Menu menu, MenuInflater inflater) tipe Boolean tidak akan berfungsi
Bahaa Hany
15
Jika Anda menggunakan Toolbardi tata letak Aktivitas, pastikan Anda memanggil setSupportActionBar(your_toolbar)Aktivitas Anda. Jika setHasOptionsMenutidak, tidak berpengaruh.
artkoenig
Kamu adalah kekasihku :)
Qadir Hussain
30

Jika Anda menggunakan tema yang tidak mendukung ActionBar, maka OnCreateOptionsMenu () tidak akan dipanggil secara otomatis, meskipun Anda menulis semua kode Java dengan benar.

Anda dapat membuka AndroidManifest.xml, mengubah nilai android: theme menjadi "@android: style / Theme.Holo.Light.DarkActionBar", atau tema lain yang mendukung ActionBar.

menjadikan binatang
sumber
saya menggunakan toolbar dari support library dan Theme.AppCompat.Light.NoActionBar sebagai tema dan saya menghadapi masalah yang sama ... tidak ada menu opsi yang ditampilkan..plz help
Dhruvam Gupta
6
saya menyelesaikannya dengan menelepontoolbar.inflateMenu(R.menu.menu_custom);
Dhruvam Gupta
Cukup panggil setSupportActionBar (mToolbar) di aktivitas Anda dan onCreateOptionsMenu di Fragmen akan dipanggil secara otomatis.
Vít Kapitola
12

ini berhasil untuk saya

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    setHasOptionsMenu(true);
    View view = inflater.inflate(R.layout.sample, null);
}
Anisetti Nagendra
sumber
11

Selain itu, pastikan instance Toolbar yang Anda teruskan

setSupportActionBar(toolbar);

dalam Aktivitas Anda tidak null, karena Anda tidak akan mendapatkan pengecualian jika memang demikian nulldan Anda akan kehilangan beberapa jam seperti yang saya lakukan.

Saya menggunakan ButterKnife untuk mengikat tampilan, tetapi secara tidak sengaja ditempatkan setSupportActionBar(toolbar)sebelum saya benar-benar melakukan panggilan keButterKnife.bind()

medula oblongata jack
sumber
1
Haris, kamu luar biasa. Terima kasih telah membagikan ini! Saya mengalami masalah ini karena saya menggunakan Kotlin dan sering kali Anda tidak perlu melakukan findViewById, dll ... untuk mendapatkan tampilan yang Anda butuhkan.
DWndrer
1

Cukup beri tahu aktivitas host bahwa fragmen Anda memiliki menu opsi dalam konstruktornya.

public YourFragment () {setHasOptionsMenu (true);}

Meskipun itu berhasil untuk saya, itu tidak disarankan seperti yang disebutkan dalam komentar dari @aldorain

Aplikasi biasanya tidak mengimplementasikan konstruktor. Kode aplikasi tempat pertama bisa berjalan di mana fragmen siap digunakan adalah di onAttach (Activity), titik di mana fragmen sebenarnya terkait dengan aktivitasnya.

Jadi, letakkan setHasOptionsMenu (true) di onCreateView () atau onAttach () sebagai gantinya.

Ken Ratanachai S.
sumber
Anda tidak boleh menulis konstruktor Anda sendiri untuk fragmen khusus
aldorain
1
developer.android.com/reference/android/app/Fragment.html tl; dr 'Aplikasi seharusnya tidak menerapkan konstruktor [Fragmen].'
aldorain
0

Jika Anda memiliki tema yang tidak memberi Anda AppBar secara default dan Anda menggunakan tampilan toolbar untuk menyediakan fitur ini, JANGAN LUPA memanggil setSupportActionBar (toolbar) dalam metode onCreate () dari aktivitas yang menghosting Anda fragmen.

Setelah itu panggil setHasOptionsMenu (true) dalam metode fragmen onCreate () Anda.

:)

Moreno
sumber
-2

Set setHasOptionsMenu(true)di onCreateView()metode dalam fragmen.

@Override

 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
 {
    Viewroot=inflater.inflate(R.layout.fragment_client_requestfragment,container,false);
  hideKeyboard();
    getemail = getArguments().getString("email_id");
    Log.e("email_id from activity",getemail);
    setHasOptionsMenu(true);
    return root;
}
Nimisha Patel
sumber
1
Halo dan selamat datang di SO. Harap jangan hanya memposting jawaban hanya kode yang tidak diberi komentar dan diformat dengan buruk karena ini tidak menjelaskan apa sebenarnya masalah yang dijelaskan dalam pertanyaan. Periksa di sini untuk mengetahui beberapa tip umum tentang jawaban yang bagus.
Gero