2012-10-25 19 views
6

mam ustawiony am aktywność obsłużyć zmiany konfiguracyjne i działa, co oznacza, że ​​ jest wywoływana podczas zmiany orientacji.nie onConfigurationChanged wywoływana raz setRequestedConfiguration został wykorzystany

Aktywność ma przycisk do jawnej zmiany orientacji. Po kliknięciu nazywał się setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT).

Następnie orientacja jest nieodwołalnie ustalone i nie nazywa się już.

Jak mogę zmienić orientację, gdy użytkownik kliknie przycisk jednocześnie nie tracąc zwrotnego?

Odpowiedz

4

ten jak to rozwiązałem. Zdaję sobie sprawę, że to jest ponowne wymyślenie koła, ale spełnia ono moje wymagania i nie znalazłem odpowiedniego sposobu radzenia sobie z tym za pomocą standardowych narzędzi sdk.

Najpierw należy utworzyć klasę OrientationManager że słuchać orientacji zmienia

public class OrientationManager extends OrientationEventListener{ 
private static final String TAG = OrientationManager.class.getName(); 

private int previousAngle; 
private int previousOrientation; 
private Context context; 
private OrientationChangeListener orientationChangeListener; 
private static OrientationManager instance; 
private OrientationManager(Context context) { 
    super(context); 
    this.context = context; 
} 

public static OrientationManager getInstance(Context context){ 
    if (instance == null){ 
     instance = new OrientationManager(context); 
    } 
    return instance; 
} 

public int getOrientation(){ 
    return previousOrientation; 
} 

public void setOrientation(int orientation){ 
    this.previousOrientation = orientation; 
} 


@Override 
public void onOrientationChanged(int orientation) { 
    if (orientation == -1) 
     return; 
    if(previousOrientation == 0){ 
     previousOrientation = context.getResources().getConfiguration().orientation; 
     if (orientationChangeListener != null){ 
      orientationChangeListener.onOrientationChanged(previousOrientation); 
     }   
    } 
    if (previousOrientation == Configuration.ORIENTATION_LANDSCAPE && 
      ((previousAngle > 10 && orientation <= 10) || 
      (previousAngle < 350 && previousAngle > 270 && orientation >= 350))){ 
     if (orientationChangeListener != null){ 
      orientationChangeListener.onOrientationChanged(Configuration.ORIENTATION_PORTRAIT); 
     } 
     previousOrientation = Configuration.ORIENTATION_PORTRAIT; 
    } 

    if (previousOrientation == Configuration.ORIENTATION_PORTRAIT && 
      ((previousAngle <90 && orientation >= 90 && orientation <270) || 
      (previousAngle > 280 && orientation <= 280 && orientation > 180)) ){ 
     if (orientationChangeListener != null){ 
      orientationChangeListener.onOrientationChanged(Configuration.ORIENTATION_LANDSCAPE); 
     } 
     previousOrientation = Configuration.ORIENTATION_LANDSCAPE; 
    } 
    previousAngle = orientation; 
} 

public void setOrientationChangedListener(OrientationChangeListener l){ 
    this.orientationChangeListener = l; 
} 

public interface OrientationChangeListener{ 
    public void onOrientationChanged(int newOrientation); 
} 
} 

Następnie w swojej działalności realizować OrientationChangeListener i zastąpić onOrientationChanged():

public class MyActivity extends Activity implements OrientationChangeListener{ 

    private OrientationManager orientationManager; 

    @Override 
    public void onCreate(Bundle b){ 
     orientationManager = OrientationManager.getInstance(this); 
     orientationManager.setOrientationChangedListener(this); 

    } 

@Override 
public void onOrientationChanged(int newOrientation) { 
    orientation = newOrientation; 
    if (newOrientation == Configuration.ORIENTATION_LANDSCAPE){ 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); 
     setLandscapeConfig(); 
    }else{ 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
     setPortraitConfig(); 
    } 
} 

więc nie używam onConfigurationChanged już jednak zachować następujący wiersz w Manifeście: android: configChanges = "orientation | screen size"

+0

Zaimplementuj swoje rozwiązanie, ale onOrientationChanged nigdy nie jest wywoływany, gdy obracam urządzenie. Jakieś pomysły? – Codebeat

+0

Okay, musi wywołać orientationManager.enable() w konstruktorze działań! – Codebeat

1
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) 

Spowoduje to przerwanie pracy urządzenia onConfigurationChanged. Jeśli chcesz go do pracy, warto dodać to do manifest w ramach tego działania:

android:configChanges="orientation|screenSize" 

atrybut Rozmiar ekranu jest tylko dla API 13+ więc jeśli poniżej, że nie trzeba go

+0

to już w manifeście, inaczej onConfigurationChanged nie działa w ogóle – znat

+0

@NathanZ Czy go rozwiązać, i zmierzyć się z tym samym problemem. – dreamtale

+0

Tak, zrobiłem. Zobacz moją odpowiedź – znat

2

Wywołanie setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); ponownie aktywuje onConfigurationChanged. Można ustawić timer tak:

// Force orientation to portrait 
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT); 

// Reactivate sensor orientation after delay 
Timer mRestoreOrientation = new Timer(); 
mRestoreOrientation.schedule(new TimerTask() { 
    @Override 
    public void run() { 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); 
    } 
}, 2000); 

Możemy jedynie przypuszczać, użytkownik włączy urządzenie przez siebie do przymusowej orientacji w zwłoki, a to może prowadzić do złych doświadczeń użytkownika.

+0

ActivityInfo.SCREEN_ORIENTATION_SENSOR pracował dla mnie. – Harry

Powiązane problemy