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

作者:潘侯爷 时间:2022-02-12 03:51:06 

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

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

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

详解Android中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转换方向时未保存数据的情况:

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

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

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

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

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

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

针对数据保存我们同样有两种方法实现,分别为在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如下:

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

从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如下(演示两次旋转):

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

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

标签:android,activity
0
投稿

猜你喜欢

  • Java探索之Feign入门使用详解

    2023-08-18 03:38:06
  • Java下变量大小写驼峰、大小写下划线、大小写连线转换

    2022-04-19 15:20:18
  • Java.try catch finally 的执行顺序说明

    2022-07-06 00:30:25
  • Webview实现android简单的浏览器实例代码

    2023-04-20 15:21:57
  • 初步认识C#中的Lambda表达式和匿名方法

    2023-07-03 00:23:28
  • SpringBoot整合Mybatis自定义拦截器不起作用的处理方案

    2023-03-19 04:35:14
  • c#如何实现接口事件

    2023-10-02 18:31:28
  • C#中常使用进度条的代码

    2021-06-27 23:31:18
  • Springboot下RedisTemplate的两种序列化方式实例详解

    2021-09-11 11:48:47
  • Java Synchronized的偏向锁详细分析

    2021-07-09 00:35:23
  • C#模板方法模式(Template Method Pattern)实例教程

    2022-09-12 02:59:23
  • 关于Android中自定义ClassLoader耗时问题的追查

    2021-08-10 06:15:23
  • Input系统之InputReader处理触摸事件案例

    2022-12-18 07:32:35
  • Springboot 全局时间格式化操作

    2022-08-17 03:23:51
  • Java源码解析之Iterable接口

    2023-04-17 08:06:57
  • JAVA内存模型(JMM)详解

    2023-11-23 16:54:32
  • Spring注解驱动开发实现属性赋值

    2023-05-07 04:40:22
  • 使用jenkins部署springboot项目的方法步骤

    2022-06-05 05:18:31
  • Android编程开发之NotiFication用法详解

    2023-01-19 22:50:11
  • Android编程之SMS读取短信并保存到SQLite的方法

    2022-01-30 18:02:45
  • asp之家 软件编程 m.aspxhome.com