详解Android中Activity运行时屏幕方向与显示方式

现在我们的手机一般都内置有方向感应器,手机屏幕会根据所处位置自动进行横竖屏切换(前提是未锁定屏幕方向)。但有时我们的应用程序仅限在横屏或者竖屏状态下才可以运行,此时我们需要锁定该程序Activity运行时的屏幕方向。还有就是在我们用手机观看视频时,随意的进行横竖屏切换,但播放进度不会随着屏幕的转换而从头开始播放,为了实现这个功能,我们就需要在Activity转换时对当前数据进行保存。

现在根据以上两种需求,个人提出以下解决方案:

一、锁定Activity运行时屏幕方向,如下图(演示锁定横屏):

我们可以通过以下两种方式实现锁定Activity运行时屏幕的方向:

(1)通过修改AndroidMainfest.xml配置文件

修改Android/app/mainfests/AndroidMainfest.xml下的配置文件如下:

<activity>节点的android:screenOrientation属性可以完成该任务(portrait为保持竖屏,landscape为保持横屏)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.administrator.day18">
 <application
 android:allowBackup="true"
 android:icon="@mipmap/ic_launcher"
 android:label="@string/app_name"
 android:supportsRtl="true"
 android:theme="@style/AppTheme">
 <activity android:name=".Main2Activity"
 //添加screenOrientation属性(portrait为保持竖屏,landscape为保持横屏)
  android:screenOrientation="landscape">
  <intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
 </activity>
 </application>
</manifest>

(2)通过java代码实现:

import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
/**
 * Created by panchengjia on 2016/12/9.
 */
public class Test extends AppCompatActivity {
 @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main2);
 //添加setRequestedOrientation方法实现锁定横屏(portrait为保持竖屏,landscape为保持横屏)
 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
 }
}

现在第一种需求通过修改配置文件以及java代码的方式实现,但这里要注意的是当同时在配置文件以及java文件中设置了方向锁定时,系统会以配置文件设置为准(可以理解为配置文件优先级高于java代码

二、Activity转换方向时数据的保存

下面我们展示Activity转换方向时未保存数据的情况:

演示中,我们通过记录按钮的点击次数(土司)来判断数据是否被保存

我们发现当屏幕(Acticity)由横屏转为竖屏时,数据未实现保存,继续从0开始计数点击次数。

当我们设置保存数据后,演示情况如下:

保存数据后,点击数土司会继续竖屏状态的数据更新,而不是从零重新开始。

针对数据保存我们同样有两种方法实现,分别为在java代码中使用onSaveInstanceState()方法以及在属性。

下面我们详细分析这两种方法的实现:

(1)onSaveInstanceState详解

实现代码如下(这里写了Activity的全部生命周期,并打印log用于分析性能):

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
/**
 * Created by panchengjia on 2016/12/9.
 */
public class Main2Activity extends AppCompatActivity {
 int num=1;//初始点击次数为1
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main2);
 if(savedInstanceState!=null){
  num=savedInstanceState.getInt("data");
 }
 Log.i("Tag","onCreate");
 }
 //设置点击事件土司记录数据
 public void show(View v){
 Toast.makeText(this, num++ +"", Toast.LENGTH_SHORT).show();
 }
 @Override
 protected void onSaveInstanceState(Bundle outState) {
 super.onSaveInstanceState(outState);
 outState.putInt("data",num);
 Log.i("Tag","onSaveInstanceState");
 }
 @Override
 protected void onStart() {
 super.onStart();
 Log.i("Tag","onStart");
 }
 @Override
 protected void onResume() {
 super.onResume();
 Log.i("Tag","onResume");
 }
 @Override
 protected void onRestart() {
 super.onRestart();
 Log.i("Tag","onRestart");
 }
 @Override
 protected void onPause() {
 super.onPause();
 Log.i("Tag","onPause");
 }
 @Override
 protected void onStop() {
 super.onStop();
 Log.i("Tag","onStop");
 }
 @Override
 protected void onDestroy() {
 super.onDestroy();
 Log.i("Tag","onDestroy");
 }
}

功能实现的核心代码为protected void onSaveInstanceState(Bundle outState)方法。Activity旋转前后的Log如下:

从Log中可以得知屏幕(Acticity)旋转时,会销毁之前的Activity,然后重建旋转后的Activity。

(2)修改AndroidManifest.xml配置文件

在AndroidManifest.xml中添加configChanges属性,如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.administrator.day18">
 <application
 android:allowBackup="true"
 android:icon="@mipmap/ic_launcher"
 android:label="@string/app_name"
 android:supportsRtl="true"
 android:theme="@style/AppTheme">
 <activity android:name=".Main2Activity"
 //添加configChanges属性  android:configChanges="orientation|keyboard|screenSize">
  <intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
 </activity>
 <!--<activity android:name=".Main2Activity"></activity>-->
 </application>
</manifest>

在java中添加对应的onConfigurationChanged()方法用于Log打印分析,方法本身在功能实现上无实际意义:

@Override
 public void onConfigurationChanged(Configuration newConfig) {
 super.onConfigurationChanged(newConfig);
 Log.i("Tag","onConfigurationChanged");
 }

屏幕旋转前后Log如下(演示两次旋转):

从Log中可以得知屏幕(Acticity)旋转时,使用第二种方法保存数据不会销毁Activity,不用重复的销毁建立Activity从而达到优化内存性能的目的。建议使用这种方法

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • Android中getActivity()为null的解决办法

    前言 在日常开发中的时候,我们经常会使用ViewPager+Fragment进行视图滑动,在某些部分逻辑也许我们需要利用上下文Context(例如基本的Toast),但是由于Fragment只是依附在Activity容器的一个试图,如果需要拿到当前的Activity的上下文Context就必须通过getActivity()获取. 然而,不知道各位程序猿有没有遇过出现getActivity()出现null的时候导致程序报出空指针异常. 其实原因可以归结于因为我们在: (一)切换fragment的时

  • Android设置Activity背景为透明style的简单方法(必看)

    方法一: 通过Theme.Translucent @android:style/Theme.Translucent @android:style/Theme.Translucent.NoTitleBar @android:style/Theme.Translucent.NoTitleBar.Fullscreen 只需要在Manifest中需要透明的Activity内设置theme为以上任意一个就可以了 <activity android:name="com.vixtel.simulate.

  • Android基于OpenGL的GLSurfaceView创建一个Activity实现方法

    本文实例讲述了Android基于OpenGL的GLSurfaceView创建一个Activity实现方法.分享给大家供大家参考,具体如下: Android提供了两个基本的类让我们使用OpenGL ES API来创建和操纵图形:GLSurfaceView和 GLSurfaceView.Renderer.因此我们首先需要了解这两个类. 1. GLSurfaceView: 这是一个视图类,你可以调用OpenGL API在上面绘制图形和操纵物体,功能和SurfaceView相似.我们可以创建一个GLSu

  • Android activity堆栈及管理实例详解

    本示例演示如何通过设置Intent对象的标记,来改变当前任务堆栈中既存的Activity的顺序. 1. Intent对象的Activity启动标记说明: FLAG_ACTIVITY_BROUGHT_TO_FRONT 应用程序代码中通常不设置这个标记,而是由系统给单任务启动模式的Activity的设置. FLAG_ACTIVITY_CLEAR_TASK 如果给Intent对象添加了这个标记,那么在Activity被启动之前,会导致跟这个Activity关联的任何既存的任务都被清除.也就是说新的Ac

  • Android实现Activity水平和垂直滚动条的方法

    本文实例讲述了Android实现Activity水平和垂直滚动条的方法.分享给大家供大家参考,具体如下: <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="

  • Android开发中Activity创建跳转及传值的方法

    在Android系统的江湖中有四大组件:活动(Activity), 服务(Service), 广播接收器(Broadcast Reciver)和内容提供者(Content Provider). 今天所介绍的就是Android开发中的四大组件之一:Activity,其他那三大组件以后再进行介绍.说道Android中的Activity,如果你做过iOS开发的话,Activity类似于iOS中的ViewController(视图控制器).在应用中能看到的东西都是放在活动中的.活动是安卓开发比较重要的东

  • Android使用Theme自定义Activity进入退出动画的方法

    本文实例讲述了Android使用Theme自定义Activity进入退出动画的方法.分享给大家供大家参考,具体如下: 有没有觉得Activity的默认动画太快了或者太难看了.. 我原来使用Activity.overridePendingTransition来自定义Activity的进入动画,却发现没法定义退出的动画.结果就发现了强大的Theme和Style,之后还需要好好研究一下. 具体是这样子的: 在AndroidManifest里面,对于application和activity标签可以定义t

  • 不依赖于Activity的Android全局悬浮窗的实现

    前言 当我们在手机上使用360安全卫士时,手机屏幕上时刻都会出现一个小浮动窗口,点击该浮动窗口可跳转到安全卫士的操作界面,而且该浮动窗口不受其他activity的覆盖影响仍然可见(多米音乐也有相关的和主界面交互的悬浮小窗口).那么这种不受Activity界面影响的悬浮窗口是怎么实现的呢? Android悬浮窗实现 实现基础 Android悬浮窗实现使用WindowManager WindowManager介绍 通过Context.getSystemService(Context.WINDOW_S

  • Android使用Dialog风格弹出框的Activity

    在Android中经常会遇到需要使用Dialog风格弹出框的activity,首先我们可能会首先想到的是在XML布局文件中设置android:layout_height="wrap_content"属性,让activity的高度自适应,显然这还不行,我们还需要为其DialogActivity设置自定义一个样式 <style name="dialogstyle"> <!--设置dialog的背景--> <item name="a

  • Android中activity跳转按钮事件的四种写法

    具体实现代码: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 方法1. 采用实现OnClickListener接口的类 ((Button) findViewById(R.i

  • Android中fragment与activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<详解Android中Fragment的两种创建方式>,就如何创建Fragment混合布局做了详细的分析,今天就来详细说道说道Fragment与宿主Activity之间是如何实现数据交互的. 我们可以这样理解,宿主Activity中的Fragment之间要实现信息交互,就必须通过宿主Activity,Fragment之间是不可能直接实现信息交互的. Fragmen

随机推荐