Android开发--教你巧妙应对屏幕旋转

Android手机支持屏幕旋转功能,手机屏幕旋转直接引发了我们的App视图变化,我们选择怎样去处理手机的翻转以及当我们的手机屏幕发生了旋转的时候我们选择何种策略去进行处理视图直接影响了我们的App的用户体验。今天我们一起来学习一下手机屏幕旋转的相关知识。

设置屏幕方向切换的属性

为了使Activity在屏幕旋转方向适应不同的场合,在AndroidManifest文件的activity标签下提供了android:screenOrientation属性用于满足不同的屏幕旋转需求。

  • unspecified:默认值,该属性支持的屏幕旋转方向与具体的设备有关;
  • user:用户当前的首选方向,通常与unspecified的效果相同;
  • behind:与当前Activity在回退栈中下面的那个窗口的方向一致;
  • landspace:使屏幕永远保持横屏,手机正常方向逆时针旋转90度;
  • portrait:使屏幕永远保持竖屏,即手机的正常方向;
  • reverseLandscape:师屏幕永远保持反向横屏,手机正常方向顺时针旋转90度;
  • sensorLandscape:系统会利用Android设备的传感器切换到横屏或反向横屏;
  • sensorPortrait:系统会利用Android设备的传感器切换到竖屏或反向竖屏;
  • sensor:系统会利用Android设备的传感器切换到相应的方向,理论上是4个,但很多设备只支持3个;
  • fullSensor:使系统支持4个方向的屏幕旋转;
  • nosensor:不会发生屏幕的旋转,但有可能会发生Activity的销毁和重建(与unspecified策略相同)。

阻止Activity的销毁和重建

在默认情况下,当我们的手机屏幕发生旋转的情况下,当前的Activity会被销毁,接着重新创建该Activity,当我们在屏幕旋转时不需要改变布局的话(后面会讲如何在屏幕旋转时改变布局)这样的做法显然有点多余。Android支持开发人员在activity标签下设置android:configChanges以处理Android设备的设置变化。

在API 12(即Android 3.1)以下我们需要设置android:configChanges=”orientation”即可阻止Activity的销毁和重建,在API 12以上我们需要设置android:configChanges=”orientation|screenSize”

改变布局,获得良好用户体验

由于Android设备的长和高一般不同,当我们手机的屏幕方向发生改变后如果继续沿用之前的布局有可能会降低用户体验,下面介绍一下如何在屏幕旋转时改变布局。当我的手机出于横屏时,Android会找到并使用res/layout-land目录下的布局文件,这样我们就知道如何处理了。举一个简单的例子,在手机竖屏时我们手机屏幕顶端有一排tab,当手机翻转后将tab标签置于左侧以获得良好的用户体验:

在Android工程之下的res/layout目录中为新建布局文件activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <RadioGroup
        android:id="@+id/main_radioGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <RadioButton
            android:id="@+id/main_radio0"
            android:checked="true"
            android:text="ShowOne"
            style="@style/radio_style" />

        <RadioButton
            android:id="@+id/main_radio1"
            android:text="ShowTwo"
            style="@style/radio_style" />

        <RadioButton
            android:id="@+id/main_radio2"
            android:text="ShowThree"
            style="@style/radio_style" />
    </RadioGroup>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="20sp"
        android:text="TextView" />

</LinearLayout>

接下来在res/layout-land目录(若没有该目录,可以直接新建该目录)下创建activity_main.xml文件,布局如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <RadioGroup
        android:id="@+id/main_radioGroup"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <RadioButton
            android:id="@+id/main_radio0"
            android:checked="true"
            android:text="ShowOne"
            android:layout_width="100dp"
            style="@style/radio_style" />

        <RadioButton
            android:id="@+id/main_radio1"
            android:text="ShowTwo"
            android:layout_width="100dp"
            style="@style/radio_style" />

        <RadioButton
            android:id="@+id/main_radio2"
            android:text="ShowThree"
            android:layout_width="100dp"
            style="@style/radio_style" />
    </RadioGroup>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="20sp"
        android:text="TextView" />

</LinearLayout>

需要注意的是:我们不能阻止Activity销毁和重建,否则布局不会发生改变。

保存Activity状态

为了防止Activity在旋转过程中丢失数据,我们可以在设备旋转前保存下数据:

  1. 覆盖onSaveInstanceState将我们的数据保存在Bundle下;
  2. 在onCreate方法中获取数据
package com.example.rotatetest;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;

public class MainActivity extends Activity {

    private RadioGroup mRadioGroup;
    private TextView mTextView;

    private static final String LAST_CHOICE = "last_choice";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRadioGroup = (RadioGroup) findViewById(R.id.main_radioGroup);
        mTextView = (TextView) findViewById(R.id.textView1);
        //获取销毁前选择的RadioButton的Id
        int checkId = R.id.main_radio0;
        if (savedInstanceState != null) {
            checkId = savedInstanceState.getInt(LAST_CHOICE);
        }
        ((RadioButton) findViewById(checkId)).setChecked(true);
        switch (mRadioGroup.getCheckedRadioButtonId()) {
        case R.id.main_radio0:
            mTextView.setText("Show One");
            break;
        case R.id.main_radio1:
            mTextView.setText("Show Two");
            break;
        case R.id.main_radio2:
            mTextView.setText("Show Three");
            break;
        default:
            break;
        }
        mRadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                // TODO Auto-generated method stub
                switch (checkedId) {
                case R.id.main_radio0:
                    mTextView.setText("Show One");
                    break;
                case R.id.main_radio1:
                    mTextView.setText("Show Two");
                    break;
                case R.id.main_radio2:
                    mTextView.setText("Show Three");
                    break;
                default:
                    break;
                }
            }
        });
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        super.onSaveInstanceState(outState);
        //保存选择RadioButton的Id
        outState.putInt(LAST_CHOICE, mRadioGroup.getCheckedRadioButtonId());
    }

}

监听屏幕旋转事件

有时我们希望在设备发生旋转的时候可以得到通知以便我们处理一下事情,下面来看看如何捕获该通知。屏幕方向改变属于Android设备的设置改变,我们可以在onConfigurationChanged方法中获得。

  1. 在AndroidManifest文件中声明Activity要捕获的事件类型 android:configChanges=”orientation|screenSize”
  2. 重写Activity中的onConfigurationChanged方法
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub
        super.onConfigurationChanged(newConfig);

        if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            Toast.makeText(MainActivity.this, "现在是竖屏", Toast.LENGTH_SHORT)
                    .show();
        }
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            Toast.makeText(MainActivity.this, "现在是横屏", Toast.LENGTH_SHORT)
                    .show();
        }
    }

测试源码下载

点击下载源码

时间: 2024-11-13 09:51:06

Android开发--教你巧妙应对屏幕旋转的相关文章

Android开发之获取设备的屏幕信息

1 DisplayMetrics metric = new DisplayMetrics(); 2 getWindowManager().getDefaultDisplay().getMetrics(metric); 3 int width = metric.widthPixels; // 屏幕宽度(像素) 4 int height = metric.heightPixels; // 屏幕高度(像素) 5 float density = metric.density; // 屏幕密度(0.75

【转】Android开发笔记(序)写在前面的目录

原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入门上:其次是想拾缺补漏,写写虽然小众却又用得着的东西:另外就是想以实用为主,不求大而全,但求小而精:还有就是有的知识点是java的,只是Android开发也会经常遇上,所以蛮记下来.个人的经

Android开发安装实战教程

InstallAndroid安装 Android 开发工具Android 提供免费而且跨平台的整合开发环境,只要电脑能连接上网路,我们随时都能下载相关工具下来,并开始开发Android 应用程序.有了轻便易用的开发工具,我们可以把心力专注于如何将想法实现到应用程序上.系统需求撰写Android 的应用程序,需要一套个人电脑系统.至于操作系统的部份,几个主流操作系统都有支援.支援的操作系统如下:* Windows XP 或Vista* Mac OS X 10.4.8 或之后版本(适用x86 架构的

Android开发笔记(一百一十八)自定义悬浮窗

WindowManager 在前面<Android开发笔记(六十六)自定义对话框>中,我们提到每个页面都是一个Window窗口,许多的Window对象需要一个管家来打理,这个管家我们称之为WindowManager窗口管理.在手机屏幕上新增或删除页面窗口,都可以归结为WindowManager的操作,下面是该管理类的常用方法说明: getDefaultDisplay : 获取默认的显示屏信息.通常用该方法获取屏幕分辨率,详情参见<Android开发笔记(三)屏幕分辨率>. addV

【分享】迅为iTOP4412开发板-Android系统屏幕旋转设置

1.1概述 Android4.0,Androd4.4源代码能够编译成手机模式和平板模式,讯为iTop4412 开发平台 的Android系统默认编译为平板模式.客户须要依据自己的产品设计及应用环境,切换屏幕 的显示方向,或者固定好一个显示方向,比如产品中使用不同分辨率的显示屏,或者显示屏 在产品中的固定方向发生改变等等,都须要进行屏幕旋转功能.  那么怎样设置屏幕的旋转 呢?我们提供两种方式满足客户的这一需求. 1.2  安装屏幕旋转APK 迅为公司公布的  Android4.4镜像中含有  S

Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案

出处:http://blog.csdn.net/lmj623565791/article/details/37936275 1.概述 众所周知,Activity在不明确指定屏幕方向和configChanges时,当用户旋转屏幕会重新启动.当然了,应对这种情况,Android给出了几种方案: a.如果是少量数据,可以通过onSaveInstanceState()和onRestoreInstanceState()进行保存与恢复. Android会在销毁你的Activity之前调用onSaveInst

【Android开发进阶】Android屏幕适配全攻略(最权威的官方适配指导)

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的官方文档为基础,全面而深入的讲解了Android屏幕适配的原因.重要概念.解决方案及最佳实践,我相信如果你能认真的学习本文,对于Android的屏幕适配,你将有所收获! Android屏幕适配出现的原因 重要概念 屏幕尺寸 屏幕分辨率 屏幕像素密度 dpdipdpisppx mdpihdpixdpixxdpi 解决方案 支持

Android开发之手把手教你写ButterKnife框架(二)

欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52664112 本文出自:[余志强的博客] 上一篇博客Android开发之手把手教你写ButterKnife框架(一)我们讲了ButterKnife是什么.ButterKnife的作用和功能介绍以及ButterKnife的实现原理. 本篇博客主要讲在android studio中如何使用apt. 一.新建个项目, 然后创建一个module名叫processor 新建m

android开发2048时候屏幕过度敏感

============问题描述============ android开发2048时候屏幕过度敏感,在屏幕滑动的时候手势敏感,轻轻滑动一次就会移动好几次触发,在里面加入 thread.wait(1000)也没有用,只是时间延长了 ============解决方案1============ 常见的处理有 1. ACTION_DOWN 的时候记录按下的坐标,并标记正在"处理中". 2. ACTION_MOVE 的时候,如果正在"处理中",则与之前按下的坐标比较,看移动