簡體   English   中英

如何在不重新創建布局的情況下旋轉方向更改視圖?

[英]How to rotate views on orientation change without recreating layout?

這個問題在之前已經被問到,但答案是不正確的。 我想在屏幕方向更改上旋轉一些視圖,但我想保持布局不變。 它們應根據當前方向旋轉90度,180度,270度或360度( SCREEN_ORIENTATION_LANDSCAPESCREEN_ORIENTATION_PORTRAITSCREEN_ORIENTATION_REVERSE_LANDSCAPESCREEN_ORIENTATION_REVERSE_PORTRAIT )。

這就是我想要實現的目標:

LayoutExample

我提到的鏈接中的答案表明我應該在layout-land創建一個新的不同布局。 顯然,這不是我想要的。 我不想重新創建活動或更改布局方向。 我只想旋轉一些視圖,並保持其他視圖在方向更改時保持不變。

旋轉特定視圖與更改或重新創建整個布局(兩者都在方向更改)之間存在巨大差異。

使用此鏈接中的答案,我將能夠使用此方法獲取當前屏幕方向:

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

在改變方向時,我想做一些像這樣簡單的事情:

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

重新解釋我的問題的另一種方法是“有沒有辦法在不改變布局的情況下檢測onConfigurationChanged()方法中的方向變化?”。 問題是,如果我已經禁用布局方向更改,它將無法檢測到任何方向更改。

誰知道它是如何完成的? 我可能完全經歷了錯誤的步驟,我想我將不得不使用Accelerometer傳感器或類似的東西來實現我想要的,所以請指導我。

嘗試使用OrientationEventListener 你不需要使用onConfigurationChangedandroid:configChanges="orientation|keyboardHidden|screenSize"

您需要為AndroidManifest.xml中的活動設置android:screenOrientation="portrait" 這是我使用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);
        }
    }
}
}

orientation約為45,135 ......時,這也可以防止過於頻繁的旋轉。希望它有所幫助。

基礎知識實際上要容易得多。 看看處理運行時更改

首先,通過設置

android:configChanges="orientation|keyboardHidden|screenSize"

在您的活動標簽清單中,您可以自己處理方向更改。 orientation應該足夠,但有時會出現事件不會單獨觸發的問題。)

然后跳過onCreate ,然后調用onConfigurationChanged 覆蓋此方法並在此處應用布局更改。 您是在這里更改linearLayouts方向還是為不同的屏幕自定義視圖處理布局取決於您的具體情況,具體取決於您的實施。

如果它甚至是可能的,動畫將會有點棘手。 快速搜索說它不是


更新評論“我只想自己輪換一些視圖而不是旋轉布局”

從理論上講 ,可以創建自己的布局並處理子視圖的繪制。 我剛試過但是在適當的時候無法產生任何結果,但你需要做的是:

  • 保持您的最后測量值在視圖或類似方法上使用標記以保留最后的測量和布局,以便在方向更改后您可以區別
  • 等待方向更改 :觸發旋轉繪圖 - 旋轉畫布,使用先前尺寸布局視圖,並繪制子視圖以前的位置 ,以及
  • 最后一個開始動畫插值,將畫布從最后一個旋轉到新布局

我就是這樣做的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM