안드로이드에서 조각에 옵션 메뉴를 추가하는 방법


399

조각 그룹에서 옵션 메뉴에 항목을 추가하려고합니다.

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

코 틀린 :

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

어떤 이유로 인해 onCreateOptionsMenu실행되지 않는 것 같습니다.


어리석은 질문 일 수도 있습니다 ... 메뉴 버튼을 오른쪽으로 누르십니까?
Ovidiu Latcu

2
..lol ... yes 메뉴 버튼을 눌렀는지 여부와 상관없이 시도했습니다. fav.setShowAsAction (MenuItem.SHOW_AS_ACTION_ALWAYS);
misterbassman

안녕하세요, 스레드가 도움 될 수도 있고 실제 예제에 대한 api 데모 를 확인할 수도 있습니다.
kameny

답변:


604

super 메소드를 호출하십시오.

자바:

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

코 틀린 :

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

코드에 로그 문을 넣어 메소드가 호출되지 않거나 메뉴가 메뉴에서 수정되지 않는지 확인하십시오.

또한 프래그먼트가 옵션 메뉴 처리에 참여해야 함을 알리기 위해 호출 setHasOptionsMenu(boolean)하고 있는지 확인하십시오 onCreate(Bundle).


2
도움을 주셔서 감사합니다, 나는 슈퍼 메서드를 추가하고 @Override를 제거하여 이것을 다시 추가했다는 것을 깨달았습니다 .eclipse는 오류를 발생시켜 MenuInflater를 가져와 android.view.MenuInflater를 가져 왔습니다. import 대신 android.support.v4.view.MenuInflater; 그리고 지금 모두 작동합니다
misterbassman

183
조각 위치의에서 onCreate에서 setHasOptionsMenu (true)를 호출하지 두번 지금 저를 얻었다
joshkendrick

7
내 활동을 조각으로 옮기고이 문제가 발생했습니다. 메소드 서명이 public boolean에서 public void로 변경되었으며 인수도 변경되었습니다. 이 점에 유의하십시오!
you786

14
Fragment.onCreateOptionsMenu (Menu, MenuInflater)는 빈 메서드이므로 super를 호출 할 필요가 없습니다. 여기서 유일한 실수는 잘못된 메소드 서명과 onCreate ()에서 누락 된 setHasOptionsMenu ()입니다.
cmende

6
super.onCreateOptionsMenu를 inflater.inflate (R.menu.menu_custom, menu)로 바꿉니다.
Code_Worm

197

나는 같은 문제가 있었지만, 그것을 작동시키는 마지막 단계를 요약하고 소개하는 것이 낫다고 생각합니다.

  1. Fragment의 onCreate(Bundle savedInstanceState)메소드 에 setHasOptionsMenu (true) 메소드를 추가하십시오 .

  2. onCreateOptionsMenu(Menu menu, MenuInflater inflater)조각의 메뉴에서 다른 작업을 수행하려는 경우 조각의 재정 의 및 onOptionsItemSelected(MenuItem item)메서드.

  3. onOptionsItemSelected(MenuItem item)액티비티의 메소드 내 에서 메뉴 항목 조치가 onOptionsItemSelected(MenuItem item)프래그먼트의 메소드 로 구현 될 때 false를 리턴해야합니다 .

예를 들면 :

활동

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

2
그냥 누락 된 setHasOptionsMenu(true);감사
차드 빙햄

1
일부 장치의 viewPager에서 메뉴는 두 번째 조각으로 갈 때만 표시됩니다
Roel

3
@Marco HC 코드가 정상적으로 작동합니다. 그러나 Activity 또는 Fragment 메뉴를 숨기려면 어떻게해야합니까? 어떤 옵션 메뉴를 구현할 위치 (활동 및 조각)에 대해 언급했습니다. 하지만 메뉴를 숨기려면 어떻게해야합니까?
Shreyash Mahajan

@iDroidExplorer는 해당 MenuItem에 대한 참조를 유지하고 가시성을 사라지거나 보이지 않게 설정합니다. 그게 당신의 질문입니까?
Marco HC

@ iDroidExplorer 그의 코드를 시도했지만 다른 조각으로 전환 할 때 메뉴를 자동으로 숨기는 방법을 모르겠습니다.
Noor Ali Butt

156

onCreateOptionsMenu(Menu menu, MenuInflater inflater)메소드가 호출되지 않는 것을 발견 하면 Fragment의 onCreate(Bundle savedInstanceState)메소드 에서 다음을 호출하십시오 .

setHasOptionsMenu(true)

그것은 나에게 NullPointerException 같은 오류를 제공
Pratik Butani

2
좋은 지적. 정적 newInstance 메소드에서 setHasOptionMenu 메소드를 호출했습니다. savedInstanceState가 null 일 때만 조각을 첨부했기 때문에 화면 구성이 변경되면 메뉴가 만들어지지 않습니다. 프래그먼트의 onCreate 메소드는 setHasOptionMenu를 true로 설정하는 올바른 위치입니다.
argenkiwi

1
나는 a를 사용하고 Toolbar있으며 대신 전화 setHasOptionsMenu(true)onCreateView()걸어야 onCreate()했다.
CLOUGH

60

당신이 필요한 경우 menu를 새로 webview특정 내부에 Fragment, 당신은 사용할 수 있습니다 :

조각 :

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>

31

TL; DR

사용 android.support.v7.widget.Toolbar하고 그냥 하십시오 :

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

독립형 툴바

제안 된 솔루션의 대부분은 상위 활동에 레이아웃에 툴바가 있고 를 통해 선언 한 setHasOptionsMenu(true)경우에만 작동 합니다 . 그러면 Fragments는이 정확한 ActionBar 의 메뉴 인구에 참여할 수 있습니다 .setSupportActionBar()

Fragment.onCreateOptionsMenu () : Fragment 호스트의 표준 옵션 메뉴의 내용을 초기화합니다.

하나의 특정 조각에 대한 독립형 도구 모음 및 메뉴를 원하는 경우 다음을 수행 할 수 있습니다.

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

예, 그렇게 쉽습니다. onCreate()또는 을 재정의 할 필요도 없습니다 onCreateOptionsMenu().

추신 : 이것은와 만 작동 android.support.v4.app.Fragment하고 있습니다 android.support.v7.widget.Toolbar( AppCompatActivityAppCompat테마도 사용 하십시오 styles.xml).


1
정말 나에게 많은 도움
brahmy의 adigopula을

23

에서 menu.xml모든 메뉴 항목을 추가해야합니다. 그런 다음 초기 로딩에서 원하지 않는 항목을 숨길 수 있습니다.

menu.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 () 메소드에 추가 하여 Fragment 클래스의 메뉴 항목을 호출하십시오.

FragmentClass.java

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

onCreateOptionsMenuFragment 클래스에서 다시 재정 의 할 필요가 없습니다 . onPrepareOptionsMenuFragment에서 사용 가능한 방법 을 재정 의하여 메뉴 항목을 변경 (추가 / 제거) 할 수 있습니다 .

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

}

16

메뉴를 부풀리기 전에 menu.clear ()를 사용해야합니다.

@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
이것은 다른 프래그먼트에서 다른 메뉴를 원하고 프래그먼트를 교체하는 대신 프래그먼트를 추가 할 때 정확합니다.
Akshay Mahajan

감사합니다! menu.clear ()는 활동의 메뉴 옵션을 제거하는 데 도움이됩니다.
kimcy929

13

제 경우에는 다음 단계가 있습니다.

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

이미 menu.clear()이전 메뉴를 사용하여 주요 활동에 대한 메뉴가있었습니다 . 나를 위해 일했다 :)
Anbuselvan Rocky

8

메뉴 사용자 정의를 추가하려는 경우

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

탭보기가 있고 각 조각에 대해 다른 메뉴를 부 풀리려면 어떻게해야합니까?
Jainam Jhaveri

7

나는 같은 문제를 겪었고 내 조각은 ViewPager의 페이지였습니다. 그것이 발생한 이유는 FragmentPagerAdapter를 인스턴스화 할 때 활동 지원 조각 관리자 대신 하위 조각 관리자를 사용했기 때문입니다.


3

메뉴 파일 :

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

3

코드가 좋습니다. 이 방법에는 슈퍼 만 누락되었습니다.

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

2

나는 여기에 대한 답변 중 어느 것도 나를 위해 일하지 않았기 때문에 미쳤다.

전화해야 할 메뉴를 표시하려면 : setSupportActionBar(toolbar)

끝난!

참고 : toolbar뷰가 동일한 액티비티 레이아웃이 아닌 경우 액티비티 클래스에서 직접 위의 호출을 사용할 수 없습니다.이 경우 조각 클래스에서 해당 액티비티를 가져 와서을 호출해야합니다 setSupportActionBar(toolbar). 기억하십시오 : 활동 클래스는 AppCompatActivity를 확장해야합니다.

이 답변이 도움이 되길 바랍니다.


1

조각보기를 만든 후 옵션 메뉴를 설정하면 나에게 효과적이었습니다.

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

1

내 문제는 약간 달랐다. 나는 모든 것을 올바르게했다. 그러나 조각을 호스팅하는 활동에 대해 잘못된 클래스를 상속했습니다.

따라서 onCreateOptionsMenu(Menu menu, MenuInflater inflater)조각에서 재정의 하는 경우이 조각을 호스팅하는 활동 클래스를 상속하는지 확인하십시오 android.support.v7.app.ActionBarActivity(API 레벨 11 이하를 지원하려는 경우).

나는 android.support.v4.app.FragmentActivityAPI 레벨을 11 이하로 지원하도록 상속했습니다 .


1

한 가지 더하고 그것이 나를 위해 작동하지 않은 이유.

Napster의 답변과 비슷합니다.

  1. 조각의 호스팅 활동이 AppCompatActivity아닌 확장되는지 확인하십시오 FragmentActivity!

    public class MainActivity extends AppCompatActivity {
    
    }

    FragmentActivity에 대한 Google 참조 문서 에서 :

    참고 : 조치 표시 줄이 포함 된 활동을 구현하려면 대신이 클래스의 서브 클래스 인 ActionBarActivity 클래스를 사용해야하므로 API 레벨 7 이상에서 Fragment API를 사용할 수 있습니다.

  2. ActionBarActivity더 이상 사용되지 않는 Napster의 답변을 업데이트하려면 AppCompatActivity대신 사용하십시오.

  3. 를 사용할 때 AppCompatActivity'활동 테마 Theme.AppCompat또는 유사한 테마'(Google 문서) 를 설정해야합니다 .

참고 : android.support.v7.app.AppCompatActivity클래스의 하위 android.support.v4.app.FragmentActivity클래스입니다 ( AppCompatActivity 참조 문서 참조).


1

메뉴 폴더에서 .menu 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
                }
            });

}

0

위의 모든 기능이 작동하지 않으면 디버그하고 로그를 작성하여 onCreateOptionsMenu 함수가 호출되었는지 확인해야합니다.

실행되지 않으면 Android 테마가 작업 표시 줄을 지원하지 않는 것일 수 있습니다. AndroidManifest.xml을 열고 android:theme테마 지원 조치 표시 줄 의 값을 설정하십시오 .

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

0

onCreate 메소드에서 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);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.