Development Tip

onPrepareOptionsMenu가 메뉴 항목을 전환 할 때 ActionBar를 어떻게 새로 고칠 수 있습니까?

yourdevel 2020. 12. 2. 22:02
반응형

onPrepareOptionsMenu가 메뉴 항목을 전환 할 때 ActionBar를 어떻게 새로 고칠 수 있습니까?


내 앱 내에서 종종 메뉴 항목을 활성화 / 비활성화하고 onPrepareOptionsMenu에서 볼 수 있도록합니다.

오늘 저는 Android 2.x 앱 중 일부에 android : showAsAction 메뉴 속성을 추가하여 ActionBar에서 가장 많이 사용되는 메뉴 항목을 표시하기 시작했습니다.

ActionBar는 활성화 / 비활성화 및 가시성을 즉시 반영하지 않습니다. 이 변경 사항을 확인하려면 오른쪽의 메뉴 드롭 다운을 클릭해야합니다.

좋아, 메뉴가 onPrepareOptionsMenu를 실행한다는 것을 이해합니다. 하지만 ActionBar를 새로 고치려면 어떻게해야합니까? 이 변경 사항은 onOptionsItemSelected 내에서 적용해야한다고 생각하지만 무엇을 호출해야하는지 모르겠습니다.

메뉴는 다음과 같습니다.

<item
    android:icon="@drawable/ic_menu_mapmode"
    android:id="@+id/men_mapview"
    android:showAsAction="ifRoom|withText"
    android:title="@string/txt_mapview" />

<item
    android:icon="@drawable/ic_menu_mapmode"
    android:id="@+id/men_satelliteview"
    android:showAsAction="ifRoom|withText"
    android:title="@string/txt_satelliteview" />

다음은 onPrepareOptionsMenu입니다.

@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
    MenuItem menuItemMapView = menu.findItem(R.id.men_mapview);
    MenuItem menuItemSatelliteView = menu.findItem(R.id.men_satelliteview);

    if (mapView.isSatellite()) {
        menuItemMapView.setEnabled(true).setVisible(true);
        menuItemmenuItemSatelliteView.setEnabled(false).setVisible(false);
    } else {
        menuItemMapView.setEnabled(false).setVisible(false);
        menuItemmenuItemSatelliteView.setEnabled(true).setVisible(true);
    }

    return super.onPrepareOptionsMenu(menu);
}

다음은 onOptionsItemSelected입니다.

@Override
public boolean onOptionsItemSelected(final MenuItem menuItem) {
    switch (menuItem.getItemId()) {
        case R.id.men_mapview:
            mapView.setSatellite(false);
            mapView.setStreetView(true);
            mapView.invalidate();

            invalidateOptionsMenu(); // This works on Android 3.x devices only
            return true;
        case R.id.men_satelliteview:
            mapView.setSatellite(true);
            mapView.setStreetView(false);
            mapView.invalidate();

            invalidateOptionsMenu(); // This works on Android 3.x devices only
            return true;
    }

    return super.onOptionsItemSelected(menuItem);
}

편집 : invalidateOptionsMenu를 추가하면 Android 3.x 앱에서 작동하지만 누락 된 방법으로 인해 Android 2.x 장치에서 충돌합니다. 올바르게 수행하는 권장 방법은 무엇입니까?


내 선택 방법은 도우미 클래스를 만드는 것입니다. 예를 들면 :

class VersionHelper
{
    static void refreshActionBarMenu(Activity activity)
    {
        activity.invalidateOptionsMenu();
    }
}

이제 위의 코드에서 다음으로 바꿉니다 invalidateOptionsMenu();.

if (Build.VERSION.SDK_INT >= 11)
{
    VersionHelper.refreshActionBarMenu(this);
}

이 방법에 대한 크레딧은 CommonsWare로 이동합니다 (HoneycombHelper를 검색하고 그의 책을 확인하십시오-적극 권장).


받아 들여진 답변 덕분입니다. ActionBarActivity를 사용하고 있습니다. 이 수업에서 당신은 사용할 수 있습니다

supportInvalidateOptionsMenu();

사용하다

ActivityCompat.invalidateOptionsMenu(Activity activity)

로부터 호환성 라이브러리 .

참조 : https://stackoverflow.com/a/14748687/435855


메뉴에 대한 참조를 저장하고 다음을 호출하십시오.

this.menu.clear();
this.onCreateOptionsMenu(this.menu);

위의 "Klaasvaak"답변을 기반으로합니다. 하위 메뉴를 사용하고 있습니다. 이것은 나를 위해 작동합니다.

// Declare and save the menu as global, so it can be called anywhere.
Menu absTopSubMenus;

public boolean onCreateOptionsMenu(Menu menu) {

absTopSubMenus = menu;  // Used for re-drawing this menu anywhere in the codes.

// The remainder of your code below
}

그런 다음 이것을 다시 그리려면 다음을 호출하십시오.

// Redraw the top sub-menu
absTopSubMenus.clear();
onCreateOptionsMenu(absTopSubMenus);

이제 지원 라이브러리와 함께 ActionbarActivity의 supportInvalidateOptionsMenu () 메서드를 사용할 수 있습니다. 따라서 sdk의 버전을 확인할 필요가 없습니다. API 7 이상까지 진행됩니다.

http://developer.android.com/reference/android/support/v7/app/ActionBarActivity.html

이렇게하려면 이것을 사용하여 지원 라이브러리의 v7을 가져와야합니다.

http://developer.android.com/tools/support-library/setup.html


이미 본 적이 있는지는 모르겠지만 액션 바를 광범위하게 사용하고 하위 API (> 8)를 지원할 계획이라면 actionBarSherlock 라이브러리를 살펴보세요. 이렇게하면 더 낮은 API와 더 높은 API에 대해 actionBar 코드를 섹션 할 필요가 없으며 다음을 실행할 수 있습니다.

runOnUiThread(new Runnable(){
  @Override
  public void run(){
    supportInvalidateOptionsMenu();
  }
});

getActivity (). invalidateOptionsMenu ();

작업을 완료합니다.


Kudos to @Klaasvaak for showing us the way here. I use the following which works on both pre- and post- API Level 11:

private void invalidOptionsMenuHelper() {
    if (Build.VERSION.SDK_INT >= 11) {
        invalidateOptionsMenu();

    } else if (mOptionsMenu != null) {
        mOptionsMenu.clear();
        onCreateOptionsMenu(mOptionsMenu);
    }
}

Of course, you must save a reference to the menu (mOptionsMenu in this case) which I accomplish via:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    mOptionsMenu = menu;

    //... create and manage the menu normally
}

Also make sure you are not calling

myAppCompatActivity.setToolbarTitle("some dynamic title");

shortly after you have refreshed your menu.

I had the issue that the drawables would not show up even if there was room for them to be displayed. Once I did an orientation change the drawables then appeared.. ?

In Summary:

MainActivity:

public class MainActivity extends AppCompatActivity {

    private boolean showMenu = true;

    public void setShowMenu(boolean show) {
        showMenu = show;
        supportInvalidateOptionsMenu();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.my_menu, menu);
        menu.findItem(R.id.menu_share).setVisible(showMenu);
        // menu.findItem(...
        return true;
    }
}

FragmentNoMenu:

public abstract class FragmentNoMenu extends Fragment {

    protected MainActivity mainActivity;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        mainActivity = (MainActivity) getActivity();
        if (mainActivity != null) {
            mainActivity.setShowMenu(false);
        }
    }

}

FragmentWithMenu:

public abstract class FragmentWithMenu extends Fragment {

    protected MainActivity mainActivity;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        mainActivity = (MainActivity) getActivity();
        if (mainActivity != null) {
            mainActivity.setShowMenu(true);
        }
    }

}

참고URL : https://stackoverflow.com/questions/7765184/how-can-i-refresh-the-actionbar-when-onprepareoptionsmenu-switched-menu-entries

반응형