2013-06-26 2 views
0

현재 Google Play 게임 서비스를 구현 한 후 동적 옵션 메뉴가 필요한 게임에서 작업하고 있습니다. 내 전체 게임은 strings.xml과 6 개의 활동 (가져온 라이브러리 프로젝트 제외)으로 구성됩니다. layout.xml을 사용하지 않고 옵션 메뉴를 작성한다는 의미이므로이 부분 만 언급합니다.invalidateOptionsMenu()를 사용하는 동적 옵션 메뉴

나는 로그인 상태에 따라 내 로그인 및 로그 아웃 버튼의 표시 상태를 변경하려고합니다. 현재 사용자가 로그인하면 메뉴가 올바르게 업데이트되고 로그인 버튼은 로그 아웃으로 대체됩니다. 그러나 로그 아웃 버튼을 클릭하면 사용자에게 올바르게 서명하는 동안 메뉴 업데이트가 실행되지 않습니다. 버튼을 통해 다시 로그 아웃하려고 시도하면 예외가 발생하지 않기 때문에 애플리케이션이 중단됩니다. 나중에 처리 할 수 ​​있습니다. 활동을 변경하면 메뉴가 제대로 업데이트됩니다. 내가 지금까지있어 무엇

내가이 내 확장 모든 다른 클래스 내 게임 전반에 걸쳐 일반적인 방법을 사용하도록 확장 클래스입니다 here

을 발견 한 것은 현저하게 유사합니다, 나는 할 항목은 관련이없는 제거했다 메뉴.

package com.domain.myapp; 

import android.annotation.SuppressLint; 
import android.content.Intent; 
import android.os.Build; 
import android.view.Menu; 
import android.view.MenuItem; 

public abstract class Extensions extends LicenseCheck { 
    private static final int SOM1= 1; 
    private static final int SOM2= 2; 
    private static final int SOM3= 3; 
    private static final int SOM4= 4; 
    private static final int SOM5= 5; 
    private static final int SOM6= 6; 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     if (Build.VERSION.SDK_INT >= 11) { 
      buildMenu(menu); 
     } 
     return true; 
    } 

    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) { 
     if (Build.VERSION.SDK_INT < 11) { 
      buildMenu(menu); 
     } 
     return true; 
    } 

    private void buildMenu(Menu menu) { 
     menu.clear(); 
     menu.add(Menu.NONE, SOM1, Menu.NONE, "Instructions"); 
     menu.add(Menu.NONE, SOM2, Menu.NONE, "View Achievements"); 
     menu.add(Menu.NONE, SOM3, Menu.NONE, "View Leaderboard"); 
     menu.add(Menu.NONE, SOM4, Menu.NONE, "Sign In"); 
     menu.add(Menu.NONE, SOM5, Menu.NONE, "Sign Out"); 
     menu.add(Menu.NONE, SOM6, Menu.NONE, "Exit Game"); 
     if (isSignedIn()) { 
      menu.findItem(SOM4).setVisible(false); 
      menu.findItem(SOM5).setVisible(true); 
     } 
     if (!isSignedIn()) { 
       menu.findItem(SOM4).setVisible(true); 
       menu.findItem(SOM5).setVisible(false); 
     } 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case SOM1: 
      Intent nextInstructionScreen = new Intent(getApplicationContext(), InstructionScreen.class); 
      startActivity(nextInstructionScreen); 
      break; 
     case SOM2: 
      viewAchievements(); 
      break; 
     case SOM3: 
      viewLeaderboards(); 
      break; 
     case SOM4: 
      beginUserInitiatedSignIn(); 
      break; 
     case SOM5: 
      getGamesClient().signOut(); 
      menuRefresh(); 
      break; 
     case SOM6: 
      moveTaskToBack(true); 
      break; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    @SuppressLint("NewApi") 
    public void menuRefresh() { 
     if (Build.VERSION.SDK_INT >= 11) { 
      invalidateOptionsMenu(); 
     } 
    } 
} 

또한, 나는 onSignOutComplete()를 사용하려고했지만 언젠가 잘못 했어야합니다. 어떤 도움이라도 대단히 감사하겠습니다. 부울을 사용하여 로그인 상태를 추적해도 동작이 변경되지 않았습니다. 반대 기능이 잘 작동하는 경우 로그 아웃 단추를 표시 한 다음 로그 아웃 단추를 표시 한 후 로그 아웃 단추가 숨겨진 이유를 알 수 없습니다.

답변

0

개인적으로는 onCreateOptionsMenu()만을 사용하고 onPrepareOptionsMenu() 메서드는 제거하십시오.

onPrepareOptionsMenu()은 메뉴가 표시 될 때마다 호출되는 반면 onCreateOptionsMenu()은 처음 메뉴를 만들 때와 invalidateOptionsMenu()을 수동으로 호출 할 때만 호출됩니다.

또한 두 메뉴 항목을 모두 추가 한 다음 그 중 하나를 제거/숨기기 대신 사용자가 로그인했는지 확인한 다음 적절한 메뉴를 추가하기 만하면됩니다.

그 외에 실제로는 귀하의 질문과 관련이 없지만 메뉴 항목 제목을 하드 코딩하는 대신 문자열 ressources를 사용해야합니다. res/values/strings.xml 파일을 확인한 다음 Java 코드에서 getString(R.string.id_of_string)을 사용하여 문자열을 가져옵니다.

추신. 내 생각에 LicenseCheck 클래스가 Activity까지 확장됩니까?

+0

IIRC 3.0의 Honeycomb (API 11) 옵션 메뉴는 생성 된 후에 항상 열리 며, 따라서 onPrepareOptionsMenu()는 처음에 invalidateOptionsMenu()를 호출하지 않는 한이를 업데이트하지 않습니다. 또한 둘 다 추가 한 다음 하나 또는 다른 것은 사용자가 자유롭게 내 애플리케이션에 로그인하거나 로그 아웃 할 수 있도록하는 것입니다. 때때로 게임에서 지출하는 시간을 줄이기 위해 우연히 성과 또는 점수를 공유 할 가능성을 원하지 않습니다. 내 사용자가 로그 아웃하면 더 이상 점수를 공유하거나 리더 보드에 제출할 수 없으며 다음 번 로그인시 업적이 부여됩니다. – DRW

+0

마지막 질문에 대답하려면 내 수업의 상속 체인 (내 MainActivity 및 내 게임에서 여기에 이름이 지정되지 않은 다른 세 클래스는 MainActivity => Extensions => LicenseCheck => BaseGameActivity – DRW

+0

예, onPrepareOptionsMenu()는 옵션 메뉴를 무효화 할 때 호출되지만 onCreateOptionsMenu()도 마찬가지입니다. onCreateOptionsMenu() 만 필요하므로 다른 것을 제거해도 안전합니다. 메뉴 항목과 관련하여 제안 할 수없는 이유가 여전히 표시되지 않습니다. onCreateOptionsMenu()를 체크하고 "로그인"에서 "로그 아웃"으로 변경해야 할 때마다 메뉴를 무효화하십시오. –