2012-10-25 13 views
6

我已經設置了一個活動來處理配置更改並且它可以工作,這意味着在方向更改時被調用。onConfigurationChanged一旦使用setRequestedConfiguration就不會調用

活動有一個按鈕來明確地改變方向。點擊時,它叫setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT)

然後,方向不可撤銷地設置,並且不再被調用。

如何在不丟失回調的情況下單擊按鈕時更改方向?

回答

4

這我是如何解決它的。我知道這是重新發明輪子,但它符合我的要求,我沒有找到正確的方法來處理這與標準的SDK工具。

首先,創建一個OrientationManager類,聽取方向改變

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); 
} 
} 

然後在你的活動實施OrientationChangeListener並覆蓋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(); 
    } 
} 

所以我不使用onConfigurationChanged了,但保留在清單中的以下行: android:configChanges =「orientation | screenSize」

+0

實施您的解決方案,但在旋轉設備時onOrientationChanged永遠不會被調用。有任何想法嗎? – Codebeat

+0

好的,必須在活動構造函數中調用orientationManager.enable()! – Codebeat

1
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) 

這使得onConfigurationChanged停止工作。如果你想要的工作,嘗試活動中加入給你的清單:

android:configChanges="orientation|screenSize" 

的屏幕尺寸屬性僅對API 13+,所以如果你在下面,你不需要它

+0

它已經在清單中,否則onConfigurationChanged根本無法工作 – znat

+0

@NathanZ你解決了它,我面臨同樣的問題。 – dreamtale

+0

是的,我做到了。查看我的回答 – znat

2

調用setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);將重新激活onConfigurationChanged。您可以設置一個計時器這樣的:

// 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); 

我們只能假設用戶將自己打開設備的時延內被迫方向,這可能會導致糟糕的用戶體驗。

+0

ActivityInfo.SCREEN_ORIENTATION_SENSOR爲我工作。 – Harry

相關問題