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);
}
}
}
'Development Tip' 카테고리의 다른 글
asp.net에서 데이터 테이블 열의 합계를 계산하는 방법은 무엇입니까? (0) | 2020.12.02 |
---|---|
Entity Framework Code First에 엔터티의 자식 및 손자 요소를 어떻게 열심히 포함합니까? (0) | 2020.12.02 |
JQuery의 텍스트 필드 값 지우기 (0) | 2020.12.02 |
Unix 쉘 스크립트에서 현재 날짜를 epoch로 가져옵니다. (0) | 2020.12.02 |
ServletFilter의 ServletResponse에서 HTTP 상태 코드를 얻으려면 어떻게해야합니까? (0) | 2020.12.02 |