如何在不重新创建布局的情况下旋转方向更改视图? [英] How to rotate views on orientation change without recreating layout?

查看:19
本文介绍了如何在不重新创建布局的情况下旋转方向更改视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我提到的链接中的答案表明我应该在 layout-land 中创建一个新的不同布局.显然,这不是我想要的.我不想重新创建活动或更改布局方向.我只想旋转一些视图,并在方向更改时保持其他视图不变.

旋转特定视图和改变或重新创建整个布局(都在方向改变)之间存在巨大差异.

使用此 link,我可以通过这个方法获取当前屏幕方向:

public static int getScreenOrientation(Context context) {WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);int 旋转 = windowManager.getDefaultDisplay().getRotation();DisplayMetrics dm = new DisplayMetrics();windowManager.getDefaultDisplay().getMetrics(dm);int 宽度 = dm.widthPixels;int 高度 = dm.heightPixels;整数方向;//如果设备的自然方向是纵向:if ((rotation == Surface.ROTATION_0||旋转 == Surface.ROTATION_180) &&高度 >宽度 ||(旋转 == Surface.ROTATION_90||旋转 == Surface.ROTATION_270) &&宽度 >高度) {开关(旋转){案例 Surface.ROTATION_0:方向 = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;休息;案例 Surface.ROTATION_90:方向= ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;休息;案例 Surface.ROTATION_180:方向 = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;休息;案例 Surface.ROTATION_270:方向 = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;休息;默认:Log.e("ScreenOrientation", "未知屏幕方向.默认为 " + "portrait.");方向 = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;休息;}}//如果设备的自然方向是横向或设备//是正方形的:别的 {开关(旋转){案例 Surface.ROTATION_0:方向= ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;休息;案例 Surface.ROTATION_90:方向 = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;休息;案例 Surface.ROTATION_180:方向 = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;休息;案例 Surface.ROTATION_270:方向 = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;休息;默认:Log.e("ScreenOrientation", "未知的屏幕方向.默认为 " + "landscape.");方向= ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;休息;}}返回方向;}

在改变方向时,我想做一些简单的事情:

RotateAnimation rotateAnimation = new RotateAnimation(0, getScreenOrientation(getContext()));旋转动画.setDuration(2000);for (int i = 0; i <63; i++) {按钮按钮 = (Button) rootView.findViewById(i);button.startAnimation(rotateAnimation);}

另一种改写我的问题的方法是有什么方法可以在不更改布局的情况下检测 onConfigurationChanged() 方法中的方向变化吗?".问题是如果我已经禁用布局方向更改,它将无法检测到任何方向更改.

有人知道它是怎么做的吗?我可能完全走错了步骤,我想我必须使用加速度计传感器或类似的东西来实现我想要的,所以请指导我.

解决方案

尝试使用OrientationEventListener.您不需要使用 onConfigurationChangedandroid:configChanges="orientation|keyboardHidden|screenSize".

您需要在AndroidManifest.xml 中为activity 设置android:screenOrientation="portrait".这是我使用 OrientationEventListener 的解决方案:

公共类 MyActivity 扩展 Activity{私人图像按钮菜单按钮;私有动画 toLandAnim, toPortAnim;私有方向监听器orientationListener;@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.layout_image_ruler);menuButton=(ImageButton)findViewById(R.id.menu_button);toLandAnim= AnimationUtils.loadAnimation(this, R.anim.menubutton_to_landscape);toPortAnim= AnimationUtils.loadAnimation(this, R.anim.menubutton_to_portrait);orientationListener = 新的 OrientationListener(this);}@Override 受保护的无效 onStart() {方向监听器.enable();super.onStart();}@Override 受保护的无效 onStop() {方向监听器.disable();超级.onStop();}私有类 OrientationListener 扩展 OrientationEventListener{最终 int ROTATION_O = 1;最终 int ROTATION_90 = 2;最终 int ROTATION_180 = 3;最终 int ROTATION_270 = 4;私人 int 旋转 = 0;公共OrientationListener(上下文上下文){超级(上下文);}@Override public void onOrientationChanged(intorientation) {if( (方向 < 35 || 方向 > 325) && 旋转!= ROTATION_O){//肖像旋转 = ROTATION_O;menuButton.startAnimation(toPortAnim);}else if( 方向 > 145 && 方向 < 215 && 旋转!=ROTATION_180){//反向肖像旋转 = ROTATION_180;menuButton.startAnimation(toPortAnim);}else if(orientation > 55 &&orientation < 125 && 旋转!=ROTATION_270){//反向景观旋转 = ROTATION_270;menuButton.startAnimation(toLandAnim);}else if(orientation > 235 &&orientation < 305 && 旋转!=ROTATION_90){//LANDSCAPE旋转 = ROTATION_90;menuButton.startAnimation(toLandAnim);}}}}

orientation 大约为 45、135... 等时,这也可以防止过于频繁的旋转.希望对您有所帮助.

This question has been asked before here but its answer is incorrect. I would like to rotate some views on screen orientation change, but I want to keep the layout unchanged. They should be rotated 90, 180, 270 or 360 degrees according to the current orientation (SCREEN_ORIENTATION_LANDSCAPE, SCREEN_ORIENTATION_PORTRAIT, SCREEN_ORIENTATION_REVERSE_LANDSCAPE, SCREEN_ORIENTATION_REVERSE_PORTRAIT).

This is what I want to achieve:

The answer in the link I mentioned stated that I should create a new different layout in layout-land. Clearly, this is not what I want. I don't want to recreate the activity or change layout orientation. I only want to rotate some views, and keep other views unchanged on orientation change.

There is a huge difference between rotating specific views and changing or recreating the whole layout (both on orientation change).

Using the answer in this link, I will be able to get the current screen orientation with this method:

public static int getScreenOrientation(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    int rotation = windowManager.getDefaultDisplay().getRotation();
    DisplayMetrics dm = new DisplayMetrics();
    windowManager.getDefaultDisplay().getMetrics(dm);
    int width = dm.widthPixels;
    int height = dm.heightPixels;
    int orientation;
    // if the device's natural orientation is portrait:
    if ((rotation == Surface.ROTATION_0
            || rotation == Surface.ROTATION_180) && height > width ||
            (rotation == Surface.ROTATION_90
                    || rotation == Surface.ROTATION_270) && width > height) {
        switch (rotation) {
            case Surface.ROTATION_0:
                orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                break;
            case Surface.ROTATION_90:
                orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                break;
            case Surface.ROTATION_180:
                orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                break;
            case Surface.ROTATION_270:
                orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                break;
            default:
                Log.e("ScreenOrientation", "Unknown screen orientation. Defaulting to " + "portrait.");
                orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                break;
        }
    }
    // if the device's natural orientation is landscape or if the device
    // is square:
    else {
        switch (rotation) {
            case Surface.ROTATION_0:
                orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                break;
            case Surface.ROTATION_90:
                orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                break;
            case Surface.ROTATION_180:
                orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                break;
            case Surface.ROTATION_270:
                orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                break;
            default:
                Log.e("ScreenOrientation", "Unknown screen orientation. Defaulting to " + "landscape.");
                orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                break;
        }
    }

    return orientation;
}

On orientation change, I would like to do something simple like this:

RotateAnimation rotateAnimation = new RotateAnimation(0, getScreenOrientation(getContext()));
rotateAnimation.setDuration(2000);

for (int i = 0; i < 63; i++) {
    Button button = (Button) rootView.findViewById(i);
    button.startAnimation(rotateAnimation);
}

Another way to rephrase my question would be "Is there any way to detect orientation change in onConfigurationChanged() method without changing the layout?". The problem is that it will not be able to detect any orientation change if I already disable layout orientation change.

Anyone knows how it is done? I might have totally gone through wrong steps, and I think I will have to use Accelerometer Sensor or something similar to that to achieve what I want, so please guide me through.

解决方案

Try to use OrientationEventListener. You don't need to use onConfigurationChanged and android:configChanges="orientation|keyboardHidden|screenSize".

You need set android:screenOrientation="portrait" for the activity in AndroidManifest.xml. Here is my solution with OrientationEventListener:

public class MyActivity extends Activity{

private ImageButton menuButton;

private Animation toLandAnim, toPortAnim;
private OrientationListener orientationListener;

@Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_image_ruler);

    menuButton=(ImageButton)findViewById(R.id.menu_button);
    toLandAnim= AnimationUtils.loadAnimation(this, R.anim.menubutton_to_landscape);
    toPortAnim= AnimationUtils.loadAnimation(this, R.anim.menubutton_to_portrait);

    orientationListener = new OrientationListener(this);
}

@Override protected void onStart() {
    orientationListener.enable();
    super.onStart();
}

@Override protected void onStop() {
    orientationListener.disable();
    super.onStop();
}

private class OrientationListener extends OrientationEventListener{
    final int ROTATION_O    = 1;
    final int ROTATION_90   = 2;
    final int ROTATION_180  = 3;
    final int ROTATION_270  = 4;

    private int rotation = 0;
    public OrientationListener(Context context) { super(context); }

    @Override public void onOrientationChanged(int orientation) {
        if( (orientation < 35 || orientation > 325) && rotation!= ROTATION_O){ // PORTRAIT
            rotation = ROTATION_O;
            menuButton.startAnimation(toPortAnim);
        }
        else if( orientation > 145 && orientation < 215 && rotation!=ROTATION_180){ // REVERSE PORTRAIT
            rotation = ROTATION_180;
            menuButton.startAnimation(toPortAnim);
        }
        else if(orientation > 55 && orientation < 125 && rotation!=ROTATION_270){ // REVERSE LANDSCAPE
            rotation = ROTATION_270;
            menuButton.startAnimation(toLandAnim);
        }
        else if(orientation > 235 && orientation < 305 && rotation!=ROTATION_90){ //LANDSCAPE
            rotation = ROTATION_90;
            menuButton.startAnimation(toLandAnim);
        }
    }
}
}

This also prevents from too frequent rotations when orientation is about 45, 135... etc. Hope it helps.

这篇关于如何在不重新创建布局的情况下旋转方向更改视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆