[英]How to rotate views on orientation change without recreating layout?
這個問題在此之前已經被問到,但答案是不正確的。 我想在屏幕方向更改上旋轉一些視圖,但我想保持布局不變。 它們應根據當前方向旋轉90度,180度,270度或360度( SCREEN_ORIENTATION_LANDSCAPE
, SCREEN_ORIENTATION_PORTRAIT
, SCREEN_ORIENTATION_REVERSE_LANDSCAPE
, SCREEN_ORIENTATION_REVERSE_PORTRAIT
)。
這就是我想要實現的目標:
我提到的鏈接中的答案表明我應該在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
。 你不需要使用onConfigurationChanged
和android: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.