Android에서 메뉴 항목 텍스트를 동적으로 변경하는 방법


212

메뉴 항목의 제목을 외부에서 변경하려고합니다. onOptionsItemSelected(MenuItem item)메서드 .

나는 이미 다음을한다.

public boolean onOptionsItemSelected(MenuItem item) {
  try {
    switch(item.getItemId()) {
      case R.id.bedSwitch:
        if(item.getTitle().equals("Set to 'In bed'")) {
          item.setTitle("Set to 'Out of bed'");
          inBed = false;
        } else {
          item.setTitle("Set to 'In bed'");
          inBed = true;
        }
        break;
    }
  } catch(Exception e) {
    Log.i("Sleep Recorder", e.toString());
  }
  return true;
}

그러나이 방법 이외의 특정 메뉴 항목의 제목을 수정할 수 있기를 바랍니다.


답변:


127

JxDarkAngel가 제안한 것처럼, 당신의 어디에서나 호출 활동 ,

invalidateOptionsMenu();

그리고 재정의 :

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
  MenuItem item = menu.findItem(R.id.bedSwitch);
    if (item.getTitle().equals("Set to 'In bed'")) {
        item.setTitle("Set to 'Out of bed'");
        inBed = false;
    } else {
        item.setTitle("Set to 'In bed'");
        inBed = true;
    }
  return super.onPrepareOptionsMenu(menu);
}

훨씬 더 나은 선택입니다. https://stackoverflow.com/a/17496503/568197 의 답변을 사용했습니다.


최고의 솔루션. 이것은 바퀴를 재발 명하는 대신 안드로이드 방법을 무시하기 때문입니다.
Azlan Jamal

그냥 참고 onPrepareOptionsMenu()액티비티와 메뉴가 표시 될 때마다 표시 할 때, 예를 들어, 매우 자주 안드로이드 프레임 워크에 의해 호출됩니다. 따라서 메뉴가 자주 바뀌지 않으면 효율적이지 않을 수 있습니다.
Mr-IDE

1
invalidateOptionsMenu()또한 호출 onCreateOptionsMenu()하여 업데이트 논리를 넣을 수 onCreateOptionsMenu()있습니다.
Mr-IDE

질문과 관련하여이 내용을 편집하면 허용 된 답변으로 표시됩니다.
Garbit

@Garbit는 원래 질문의 코드를 사용하도록 업데이트되었습니다!
Todd DeLand

375

활동 내에서 onCreateOptionsMenu 에서받은 Menu 객체에 대한 참조를 유지 한 다음 필요에 따라 변경이 필요한 MenuItem을 검색하는 것이 좋습니다. 예를 들어 다음과 같은 내용을 따라 무언가를 수행 할 수 있습니다.

public class YourActivity extends Activity {

  private Menu menu;
  private String inBedMenuTitle = "Set to 'In bed'";
  private String outOfBedMenuTitle = "Set to 'Out of bed'";
  private boolean inBed = false;

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    // Create your menu...

    this.menu = menu;
    return true;
  }

  private void updateMenuTitles() {
    MenuItem bedMenuItem = menu.findItem(R.id.bedSwitch);
    if (inBed) {
      bedMenuItem.setTitle(outOfBedMenuTitle);
    } else {
      bedMenuItem.setTitle(inBedMenuTitle);
    }
  }

}

또는 onPrepareOptionsMenu 를 재정 의하여 메뉴가 표시 될 때마다 메뉴 항목을 업데이트 할 수 있습니다 .


1
나는 항상 안드로이드가 이러한 종류의 문제에 대해보다 우아한 해결책을 가질 것으로 기대합니다. 가장 간단한 답변이 가장 좋은 것 같습니다. 감사합니다.
Steven Wolfe

12

전역 "Menu"객체를 생성 한 다음 onCreateOptionMenu에 할당 할 수 있습니다.

public class ExampleActivity extends AppCompatActivity
    Menu menu;

그런 다음 여기에 할당

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

그런 다음 나중에 할당 된 Menu 객체를 사용하여 필요한 항목을 가져옵니다.

menu.findItem(R.id.bedSwitch).setTitle("Your Text");

5

setOptionsTitle () 메소드를 작성하고 클래스에서 필드를 설정하십시오. 같은 :

String bedStatus = "Set to 'Out of Bed'";

...

public void setOptionsTitle(String status)
{
    bedStatus = status;

}

이제 메뉴가 채워지면 제목을 현재 상태로 변경하십시오.

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(bedStatus);


        // Return true so that the menu gets displayed.
        return true;
    }

액티비티가 렌더링 된 후에 설정할 수 있어야합니다. 그래서 그러므로되지 않은 두 가지 방법 내부
Garbit

활동이 렌더링 된 후 언제든지 setOptionsTitle을 호출하십시오. setContent (R.layout.id)를 호출 한 후 "활동이 렌더링 된 후에 설정할 수 있어야 함"이 의미하기 때문에 원하는 것을 이해하지 못하는 것 같습니다. 옵션을 변경해야 할 수도 있습니다. 메뉴 표시 (setOptionsTitle ()을 사용하여 언제 어디서나 모든 메소드에서 수행)

이 방법은 효과가 있지만 메뉴를 관리하는 Menu 객체는 제목이 변경된시기를 알 수 없으므로 제목 및 제목이 변경 될 때 필요한 작업 (예 : 레이아웃 및 줄 바꿈)을 수행 할 수 없으므로 권장되지 않습니다. .
Charles Harley

3

onPrepareOptionsMenu 재정의를 사용하는 것이 좋습니다.

menu.Clear ();
   if (TabActual == TabSelec.Anuncio)
   {
       menu.Add(10, 11, 0, "Crear anuncio");
       menu.Add(10, 12, 1, "Modificar anuncio");
       menu.Add(10, 13, 2, "Eliminar anuncio");
       menu.Add(10, 14, 3, "Actualizar");
   }
   if (TabActual == TabSelec.Fotos)
   {
       menu.Add(20, 21, 0, "Subir foto");
       menu.Add(20, 22, 1, "Actualizar");
   }
   if (TabActual == TabSelec.Comentarios)
   {
       menu.Add(30, 31, 0, "Actualizar");
   }

여기


실제로 의도 된 방법을 사용하십시오. :) 메뉴에 대한 로컬 참조를 유지하기로 결정한 경우 컨텍스트 누출에 대해 걱정할 필요가 있습니다. 아니면 아닐 수도 있습니다. 그러나 확실히이 접근법으로는 그렇지 않습니다.
William T. Mallard

3

이 코드를 사용하여 하단 탐색 항목을 계산합니다.

BottomNavigationView navigation = this.findViewById(R.id.my_bottom_navigation);
Menu menu = navigation.getMenu();
menu.findItem(R.id.nav_wall_see).setTitle("Hello");

2

메뉴 필드를 선언하십시오.

private Menu menu;

다음은 onCreateOptionsMenu () 메소드입니다.

public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
    try {
        getMenuInflater().inflate(R.menu.menu_main,menu);
    } catch (Exception e) {
        e.printStackTrace();
        Log.i(TAG, "onCreateOptionsMenu: error: "+e.getMessage());
    }
    return super.onCreateOptionsMenu(menu);
}

다음은 이름 설정 활동입니다. 버튼 클릭 또는 조건부 코드를 통해

public void setMenuName(){
menu.findItem(R.id.menuItemId).setTitle(/*Set your desired menu title here*/);
}

이것은 나를 위해 일했습니다.


0

로컬 메서드 내에서 메뉴의 내용을 변경하려는 것으로 보입니다.이 메서드는 이벤트가 발생할 때마다 또는 활동 UI 스레드에서 언제든지 호출됩니다.

이것이 오버라이드 되어이 메소드에서 사용될 때 onPrepareOptionsMenu의 전역 변수에서 Menu 인스턴스를 사용하지 않는 이유는 무엇입니까? 버튼 클릭과 같은 이벤트가 발생할 때마다 또는 활동 UI 스레드, 핸들러 또는 실행 후 실행 후이 메소드가 호출되는지 확인하십시오.

변경하려는이 메뉴 항목의 색인을 미리 알고 있어야합니다. 메뉴를 지우고 나면 메뉴 XML을 부풀려서 항목 이름이나 아이콘을 업데이트해야합니다.


0

제목을 정적으로 설정해야하는 사람들을 위해. 이것은 AndroidManifest.xml에서 수행 할 수 있습니다

<activity
    android:name=".ActivityName"
    android:label="Title Text" >
</activity>

옵션 메뉴 제목 텍스트


3
질문은 정적 인 것이 아니라 역동적 인 것입니다!
EngineSense

여전히 구글 검색에
올라와

0

조각의 메뉴 아이콘을 변경해야했습니다. 이 질문에 대한 Charles의 대답을 조각에 약간 변경했습니다.

    private Menu top_menu;

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

       setHasOptionsMenu(true);
       //...
       rootview = inflater.inflate(R.layout.first_content,null);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.fragment_menu, menu);
        this.top_menu = menu;
    }


    // my procedure
    private void updateIconMenu() {
         if(top_menu!= null) {
             MenuItem nav_undo = top_menu.findItem(R.id.action_undo);
             nav_undo.setIcon( R.drawable.back);
         }
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.