10

我已经设置了 am 活动来处理配置更改并且它可以工作,这意味着onConfigurationChanged()当方向更改时会调用它。

该活动有一个按钮来显式更改方向。单击时,它调用 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT).

然后方向被不可撤销地设置并且onConfigurationChanged()不再被调用。

onConfigurationChanged()当用户在不丢失回调的情况下单击按钮时,如何更改方向?

4

5 回答 5

8

这就是我解决它的方法。我知道它正在重新发明轮子,但它符合我的要求,我没有找到使用标准 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,而是在 Manifest 中保留以下行: android:configChanges="orientation|screenSize"

于 2012-12-12T16:31:46.380 回答
4

通话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);

我们只能假设用户会在延迟时间内自行将设备转向强制方向,这会导致用户体验不佳。

于 2014-10-16T13:18:08.980 回答
1
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT)

这会使您的 onConfigurationChanged 停止工作。如果您希望它工作,请尝试将其添加到该活动中的清单中:

android:configChanges="orientation|screenSize"

screenSize 属性仅适用于 API 13+,因此如果低于该属性,则不需要它

于 2012-10-25T17:04:00.960 回答
0

..经过多次搜索这个解决的正确代码组合。请享用!

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);

OrientationEventListener orientationEventListener = new 
OrientationEventListener(getApplicationContext()) {
    @Override
    public void onOrientationChanged(int orientation) {
        boolean isPortrait = isPortrait(orientation);
        if (!isPortrait && savedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            savedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
        } else if (isPortrait && savedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
            savedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
        }
    }
};
orientationEventListener.enable(); 
}

private int savedOrientation;
private boolean isPortrait(int orientation) 
{
    if (orientation < 45 || orientation > 315) {
        return true;
    }
    return false;
}    

@Override
public void onConfigurationChanged(Configuration newConfig) 
{
  super.onConfigurationChanged(newConfig);

  if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE)
  {
      currentOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
      // do what you need in landscape mode....
  }
  else if(newConfig.orientation==Configuration.ORIENTATION_PORTRAIT)
  {
        currentOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        // do what you need in portrait mode....
  }
}  

public void rotateScreenByUIButton() {
if (currentOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
else
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
于 2018-04-21T00:43:39.283 回答
0

您只需要将方向重新设置为 SCREEN_ORIENTATION_UNSPECIFIED,将再次调用 onConfiguration 更改

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE)
->
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
于 2020-11-16T07:42:08.737 回答