横竖屏切换加载不同的布局、

笔记,最近开发遇到了关于pad适配横竖屏的问题,现在根据自己搜索的知识点进行一下整理和总结。

两种方式实现锁定Activity运行时屏幕的方向:

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

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

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

(2)通过java代码实现:


public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //通过代码设置屏幕方向,注意要在setContentView之前设置
        //设置竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        //设置横屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        setContentView(R.layout.activity_main);

    }


}

两种方式实现Activity全屏显示:

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

<!--你可以在application的theme的节点中设置为全屏显示方式  -->
<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen">

(2)通过java代码实现:

注意:java代码实现全屏显示分为两个步骤:

1.去标题栏

//通过代码去标题栏设置屏幕方向,注意要在setContentView之前设置         
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                        WindowManager.LayoutParams.FLAG_FULLSCREEN);

2.去标题

//通过代码去标题设置屏幕方向,注意要在setContentView之前设置
        requestWindowFeature(Window.FEATURE_NO_TITLE);

实现方式Dialog(对话框)实现Activity显示

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.DeviceDefault.Dialog"
        >

旋转屏幕导致Activity重建怎么办?(最佳)

Android开发文档上专门有一小节解释这个问题。简单来说,Activity是负责与用户交互的最主要机制,任何“设置”(Configuration)的改变都可能对Activity的界面造成影响,这时系统会销毁并重建Activity以便反映新的Configuration。 “屏幕方向”(orientation)是一个Configuration,通过查看Configuration类的javadoc可以看到其他Configuration还有哪些:如fontScale、keyboardHidden和locale等等。 当屏幕旋转时,这个Configuration就发生了改变,因此当前显示的Activity需要被重建,Activity对象会被终止,它的onPause()、onStop()和onDestroy()方法依次触发,然后一个新的Activity对象被创建,onCreate()方法被触发。假设屏幕旋转前,用户正在手机上填写一个注册表单,如果处理不当,用户会发现旋转后的表单变成空白的了,严重影响使用体验。

要解决这个问题有三种方法:

方法1:禁止旋转屏幕

毫无疑问,这是最懒的办法了,相当于回避了本文提出的问题,方法如下看看就好:

<activity android:name=".MyActivity"
          android:screenOrientation="portrait"
          android:label="@string/app_name">


方法2:旋转后恢复现场
----------
package com.example.scareenchange;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
    private EditText editText1;
    private int i;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText1=(EditText) findViewById(R.id.editText1);

        //注意一定要加if语句,不然程序异常
        if(savedInstanceState!=null) {
            //通过Bundle对象取出
            int i=savedInstanceState.getInt("info");
        }

    }

    public void button1(View v) {

        editText1.setText((i++)+"");
    }
    /*
     *这个方法会在重新创建Activity之前调用
     *我们在这个方法里保存对象,以解决Activity重新创建问题
     *
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        super.onSaveInstanceState(outState);
        Toast.makeText(getApplicationContext(), i+"", 1000).show();
        outState.putInt("info", i);
    }
}


----------



方法3:手工处理旋转

,但也有办法让指定的Configuration改变时不重建Activity,方法是在AndroidManifest.xml里通过android:configChanges属性指定需要忽略的Configuration名字,例如下面这样:

<activity android:name=".MyActivity"
          android:configChanges="keyboard|keyboardHidden|screenSize|orientation"
          android:label="@string/app_name">

这样设置以后,当屏幕旋转时Activity对象不会被销毁——作为替代,Activity的onConfigurationChanged()方法被触
最佳实践考虑到旋转屏幕并不是使Activity被销毁重建的唯一因素,仍然推荐前文介绍过的方法:

onPause()里持久化Activity状态,在onCreate()里恢复现场,可以做到一举多得;

虽然Google不推荐设置android:configChanges属性的方式,但如果你的Activity横向纵向共用同一个layout文件,方法3无疑是最省事的。

横竖屏切换加载不同的布局、

缺省状态下,Activity每次横竖屏切换(包括用setRequestedOrientation调用)都会重新调用一轮onPause-> onStop-> onDestory-> onCreate->onStart->onResume操作,从而销毁原来的Activity对象,创建新的Activity对象,这是因为通常情况下软件在横竖屏之间切换,界面的高宽会发生转换,从而可能会要求不同的布局。具体的布局切换可以通过如下两种方法来实现:

扫描二维码关注公众号,回复: 2533325 查看本文章

1.直接新建两个布局文件,剩下的就什么也不用管了:右键单击‘res’文件夹  -> 'new'  ->  'Android resource directory'; 将 Directory name 填写 layout-land,Resource type 选择layout,这是建立了一个横屏的布局文件,同样的方式再建立一个layout-port资源文件夹,里面放一个竖屏的布局文件,名字要起一样的,这个很重要,然后再java文件中设置setvontentview就行  了。这样屏幕切换的时候他们会被自动加载

 

2.假如布局资源是不一样又不按照如上设置,则需要通过java代码来判断当前是横屏还是竖屏然后来加载相应的xml布局文件(比如mainP为竖屏mainL为横屏)。因为当屏幕变为横屏的时候,系统会重新呼叫当前Activity的onCreate方法,你可以把以下方法放在你的onCreate中来检查当前的方向,然后可以让你的setContentView来载入不同的layout xml。


首先在layout下,建立两个布局文件,一个是横屏的一个是竖屏的,然后再java文件中布置这两个文件就行了。

[java]  view plain  copy
  1. protected void onCreate(Bundle savedInstanceState) {  
  2.         super.onCreate(savedInstanceState);  
  3.   
  4.         int orientation = getResources().getConfiguration().orientation;  
  5.         if (orientation == Configuration.ORIENTATION_LANDSCAPE) {  
  6.             setContentView(R.layout.land);  
  7.         } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {  
  8.             setContentView(R.layout.port);  
  9.         }  
  10.         //接下来,就可以做一些初始化等操作了  
  11.   
  12.     }  
上面这两种方式实现对于横竖屏的切换加载不同的布局文件,都会让activity重新加载一次,那么必然就会导致数据的丢失或者是数据的重新获取,造成了过多的额外的功耗,那么我们可以在翻转之前保存一下现在已经获取到的数据,那么在翻转之后就可以直接使用,而不需要重新获取或者重新加载,具体在下面看
[java]  view plain  copy
  1. 重写Activity.onRetainNonConfigurationInstance(),用户横竖屏切换前保存数据  
  2.   
  3. @Override   
  4.   
  5. public Object onRetainNonConfigurationInstance() {   
  6.   
  7.     final MyDataObject data = collectMyLoadedData();   
  8.   
  9.     return data;   
  10.   
  11. }  
  12.   
  13. 在onCreate()函数中调用getLastNonConfigurationInstance(),获取onRetainNonConfigurationInstance()保存的数据  
  14.   
  15. @Override   
  16.   
  17. public void onCreate(Bundle savedInstanceState) {   
  18.   
  19.     super.onCreate(savedInstanceState);   
  20.   
  21.     setContentView(R.layout.main);   
  22.   
  23.    
  24.   
  25.     final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();   
  26.   
  27.     if (data == null) {   
  28.   
  29.         data = loadMyData();   
  30.   
  31.     }   
  32.   
  33.     ...   
  34.   
  35. }  

到这个地方,可能有人还会问,我就是同一个activity为什么切换个横竖屏一定要重新加载,我不想重新加载有没有办法呢,有的,需要拦截,具体如下:

首先需要配置文件中做点属性的配置

[java]  view plain  copy
  1. Andorid 3.2以前的SDK可以使用如下配置  
  2.   
  3. android:configChanges="orientation|keyboardHidden"  
  4.   
  5. 而Adnroid 3.2以后的SDK必须添加一个screenSize属性,具体如下  
  6.   
  7. android:configChanges="keyboardHidden|orientation|screenSize"  
  8.   
  9. 或者  
  10.   
  11. android:configChanges="orientation|screenSize"  


然后重写activity中onConfigurationChanged 方法,这里也分为三种情况:

[java]  view plain  copy
  1. //1.布局分别在layout-land和layout-port目录中的同名main.xml时,就是上面说的第一种情况  
  2.   
  3. @Override  
  4.   
  5. public void onConfigurationChanged (Configuration newConfig){  
  6.   
  7.     super.onConfigurationChanged(newConfig);  
  8.   
  9.     setContentView(R.layout.main);  
  10.   
  11.     //注意,这里删除了init(),否则又初始化了,状态就丢失  
  12.   
  13.     findViews();  
  14.   
  15.     setListensers();  
  16.   
  17. }  
  18.   
  19. //布局为不按照layout-land和layout-port目录,而自定义名字时  
  20.   
  21. @Override  
  22.   
  23. public void onConfigurationChanged (Configuration newConfig){  
  24.   
  25.     super.onConfigurationChanged(newConfig);  
  26.   
  27.     int mCurrentOrientation = getResources().getConfiguration().orientation;  
  28.   
  29.     if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ) {  
  30.   
  31.         // If current screen is portrait  
  32.   
  33.         setContentView(R.layout.mainP);  
  34.   
  35.         //注意,这里删除了init(),否则又初始化了,状态就丢失  
  36.   
  37.         findViews();  
  38.   
  39.         setListensers();  
  40.   
  41.     } else if ( mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE ) {  
  42.   
  43.         //If current screen is landscape  
  44.   
  45.         setContentView(R.layout.mainL);  
  46.   
  47.         //注意,这里删除了init(),否则又初始化了,状态就丢失  
  48.   
  49.         findViews();  
  50.   
  51.         setListensers();  
  52.   
  53.     }  
  54.   
  55. }  
  56.   
  57. 当然有时候连布局都不用更改的话,就可以直接对原有控件进行调用操作了,比如:  
  58.   
  59. public class MainActivity extends Activity {  
  60.   
  61.     private TextView textView;  
  62.   
  63.     @Override  
  64.   
  65.     public void onCreate(Bundle savedInstanceState) {  
  66.   
  67.         super.onCreate(savedInstanceState);  
  68.   
  69.         setContentView(R.layout.main);  
  70.   
  71.         Log.i("--Main--""onCreate");  
  72.   
  73.         textView=(TextView)findViewById(R.id.tv_id);  
  74.   
  75.     }  
  76.   
  77.          
  78.   
  79.     @Override  
  80.   
  81.     public void onConfigurationChanged(Configuration newConfig) {  
  82.   
  83.         super.onConfigurationChanged(newConfig);  
  84.   
  85.         Log.i("--Main--""onConfigurationChanged");  
  86.   
  87.         if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE){  
  88.   
  89.             textView.setText("当前屏幕为横屏");  
  90.   
  91.         }else{  
  92.   
  93.             textView.setText("当前屏幕为竖屏");  
  94.   
  95.         }  
  96.   
  97.     }     
  98.   
  99. }  
以下两篇博客写的非常好,学习了!!!!!!
参考博客:1.点击打开链接https://blog.csdn.net/u010365819/article/details/76618443
2.点击打开链接http://www.jb51.net/article/64735.htm
3.点击打开链接https://my.oschina.net/wangxnn/blog/395260?p={{page
4.点击打开链接http://blog.sina.com.cn/s/blog_5da93c8f01012pnd.html


猜你喜欢

转载自blog.csdn.net/yhy123456q/article/details/79791287