我已设置am活动来处理配置更改并且它有效,这意味着在方向更改时调用onConfigurationChanged()
。
活动有一个显示更改方向的按钮。点击后,它会调用setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT)
。
然后不确定地设置了方向,并且不再调用onConfigurationChanged()
。
当用户点击按钮而不丢失onConfigurationChanged()
回调时,如何更改方向?
答案 0 :(得分:7)
这就是我解决它的方式。我知道它正在重新发明轮子,但它符合我的要求,我找不到用标准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中保留以下行:
机器人:configChanges = “取向|屏幕尺寸”
答案 1 :(得分: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);
我们只能假设用户会在延迟时间内将设备自动转为强制方向,这可能会导致糟糕的用户体验。
答案 2 :(得分:1)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT)
这会使你的onConfigurationChanged停止工作。如果您希望它起作用,请尝试将其添加到该活动中的清单中:
android:configChanges="orientation|screenSize"
screenSize属性仅适用于API 13+,因此,如果低于此值,则不需要它
答案 3 :(得分: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);
}
答案 4 :(得分:0)
您只需要将方向恢复为SCREEN_ORIENTATION_UNSPECIFIED,将再次调用onConfiguration更改
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE)
->
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)