• Android杂谈layout的横竖屏处理


    我的博客搬家了,以前是http://hualang.iteye.com/,现在挪到这里了

      横竖屏处理是开发应用是比较基础的一个要点,几乎都会用到。网上有一大堆的横竖屏切换的文章,但是翻了n页以后发现竟然清一色的是转载,所以不想浪费时间到这个上面,还是自己根据自己的需求与体会总结一下吧,也方便以后查阅

    一、layout-land和layout-prot的区别与使用

    默认情况下,创建的Android项目里只有一个layout文件夹,尽管这样也可以横竖屏切换用,但是某些布局横屏过后闲的格外的丑,如下图

    横屏过后就显示的不全了,有时候看着比较纠结。所以需要在横屏的使用重新载入新的布局文件

    解决办法是:先把layout目录删除了,因为可能跟之后的产生冲突。然后新建两个文件夹,一个layout-land,另一个是layout-prot。

    layout-land:存放横屏布局文件,如main.xml。布局名字与layout-prot的一样

    layout-prot:存放竖屏布局文件,名字与layout-land的一样

    剩下的事情就可以交由手机处理了,手机会自动处理横竖屏时布局之间的切换(前提是你的手机支持横竖屏,并且:设置-显示-自动旋转屏幕)

    先看看两个布局文件吧,Activity可以不用管

    layout-land/main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width
    ="match_parent"
    android:layout_height
    ="match_parent"
    android:orientation
    ="horizontal" >

    <LinearLayout
    android:orientation="vertical"
    android:layout_width
    ="fill_parent"
    android:layout_height
    ="wrap_content"
    android:layout_gravity
    ="center"
    android:paddingLeft
    ="20dip"
    android:paddingRight
    ="20dip"
    >
    <TextView
    android:text="cnblogs-花郎"
    android:layout_width
    ="wrap_content"
    android:layout_height
    ="wrap_content"
    android:layout_gravity
    ="center"
    android:layout_marginBottom
    ="20dip"
    android:textSize
    ="24.5sp"
    />
    <TableLayout
    android:layout_width="wrap_content"
    android:layout_height
    ="wrap_content"
    android:layout_gravity
    ="center"
    android:stretchColumns
    ="*"
    >
    <TableRow>
    <Button
    android:text="吃饭"
    />
    <Button
    android:text="睡觉"
    />
    </TableRow>
    <TableRow>
    <Button
    android:text="旅游"
    />
    <Button
    android:text="盗墓"
    />
    </TableRow>
    </TableLayout>
    </LinearLayout>

    </LinearLayout>

    layout-prot/main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width
    ="fill_parent"
    android:layout_height
    ="fill_parent"
    android:background
    ="#3500ffff"
    android:padding
    ="30dip"
    android:orientation
    ="horizontal" >

    <LinearLayout
    android:orientation="vertical"
    android:layout_height
    ="wrap_content"
    android:layout_width
    ="fill_parent"
    android:layout_gravity
    ="center"
    >
    <TextView
    android:text="cnblogs-花郎"
    android:layout_width
    ="wrap_content"
    android:layout_height
    ="wrap_content"
    android:layout_gravity
    ="center"
    android:layout_marginBottom
    ="25dip"
    android:textSize
    ="24.5sp"
    />
    <Button
    android:layout_width="fill_parent"
    android:layout_height
    ="wrap_content"
    android:text
    ="吃饭"
    />
    <Button
    android:layout_width="fill_parent"
    android:layout_height
    ="wrap_content"
    android:text
    ="睡觉"
    />
    <Button
    android:layout_width="fill_parent"
    android:layout_height
    ="wrap_content"
    android:text
    ="旅游"
    />
    <Button
    android:layout_width="fill_parent"
    android:layout_height
    ="wrap_content"
    android:text
    ="盗墓"
    />
    </LinearLayout>

    </LinearLayout>

    下面有图有真相,是横屏时的布局。

    注:切换模拟器的命令式CTRL+F12

    这里有一点需要注意的是,横竖屏切换的生命周期的问题。

    在上面的那种情况下,横竖屏切换的时候,会销毁Activity后然后再次创建。

    在不加入任何设置的时候,它的生命周期是这样的:

    onCreate-onStart-onResume   开始运行时

    onPause-onStop-onDestroy-onCreate-onStart-onResume   横竖屏切换的时候都是这样

    当在AndroidManifest.xml中的activity标签中加入了:

    android:configChanges="orientation|keyboardHidden"

    或者android:configChanges="orientation"后

    横竖屏切换就不需要重新载入了,也就是说不用销毁Activity后再重新创建Activity了。

    另外一种横竖屏切换时生命周期的样子是另外的样子,是与onConfigureChanges方法有关的,它的生命周期跟我的有些不同呢?

    参考:http://hi.baidu.com/%C2%E4%C2%E4%E7%F7%E7%F7%B0%A1/blog/item/dcc19ce5a9c274cc2e2e2178.html

    二、如何限定横屏或者竖屏?

      有些人讨厌玩手机的时候横竖屏来回的切换,有些应用也限定了应用程序只使用横屏或者只使用竖屏,即使手机设置了“自动切换横竖屏”。比如“水果忍者”是不能竖屏的(双人模式除外了)

    解决办法:只需要在AndroidManifest.xml的Activity标签中加入:android:screenOrientation="landscape"

    android:screenOrientation="landscape"表示横屏

    android:screenOrientation="protrait"表示竖屏

    这样,所设定的应用程序就只能是横屏或者竖屏了

    三,横竖屏切换时关于Activity重新载入的问题(onConfigurationChanged()方法)

    例如上面的那个例子,Activity每次横竖屏切换的时候是重新载入的,但是比如我们在玩游戏的时候切换了一下屏幕,我们不可能要重新玩起,所以需要有一种解决横竖屏切换的时候保存当前状态,不用重新载入的方法

    解决方案:可以使用onConfigurationChanged方法,该方法可以在用户切换横竖屏的时候就不用重新执行onCreate方法了

    提醒:这个方法的使用场景比如播放影音的时候转换了一下屏幕,如果是分别设置了两个布局的话,那么横竖屏要对应不同布局,也意味着还是要执行onCreate方法,所以布局最好是一个(不知对不对,求高手指点)

    1、需要在AndroidManifest.xml中的对应的activity标签里加入

    android:configChanges="orientation|keyboardHidden"

    这条语句的意思是:横竖屏切换或者实体键盘推出合上的时候配置信息的改变

    2、需要在AndroidManifest.xml中加入权限

    <uses-permission android:name="andorid.permission.CHANGE_CONFIGURATION"/>

    3、需要在横竖屏切换时共用的那个Activity里覆盖onConfigurationChanged方法,如下

        @Override
    public void onConfigurationChanged(Configuration newConfig) {
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);
    if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE )
    {
    Toast.makeText(getApplicationContext(), "切换为横屏", Toast.LENGTH_SHORT).show();
    }else if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
    {
    Toast.makeText(getApplicationContext(), "切换为竖屏", Toast.LENGTH_SHORT).show();
    }
    }

    这里需要说的事,代码中的if语句是判断当前设备是横屏还是竖屏,然后有其对应的操作。之前竟然在屏幕切换的时候设置不同的布局,虽然能够显示不同的布局,但是这个方法就已经毫无意义了,因为横竖屏切换到不同的布局我们可以用上面的第一种方法,而这种最好只是对应一个布局吧,然后在里面进行横竖屏时候的其他操作,防止了重新载入

    下面还是看一个例子吧,下面的是一个播放rtsp流的的例子

    package com.loulijun.demo07;

    import android.app.Activity;
    import android.content.res.Configuration;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.Toast;
    import android.widget.VideoView;

    public class Demo07Activity extends Activity {
    private VideoView video;
    private String rtspUrl = "rtsp://218.205.231.149:554/mobile/1/2CBE124B67C85A59/48f313651199829e.sdp?id=guest&t=1305313158&en=f2ed024c7963e179f65c65689fdd9887&rs=wap";
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    video = (VideoView)findViewById(R.id.play);
    video.setVideoURI(Uri.parse(rtspUrl));
    video.requestFocus();
    video.start();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);
    if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE )
    {
    Toast.makeText(getApplicationContext(), "切换为横屏", Toast.LENGTH_SHORT).show();
    }else if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
    {
    Toast.makeText(getApplicationContext(), "切换为竖屏", Toast.LENGTH_SHORT).show();
    }
    }


    }

    main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <VideoView
    android:id="@+id/play"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />

    </LinearLayout>

    这里需要说一下VideoView的全屏显示的问题,横屏后右边总是空出一块黑色区域,即使通过WindowManager的方式也不能解决,索性只能设置布局为居中显示了,至少好看些

    所以只是在清单文件中加入了样式:android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

    这种方式在播放视频的时候不能全屏,希望大牛们可以提出自己的解决方案
    AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.loulijun.demo07"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
    android:label="@string/app_name"
    android:configChanges="orientation|keyboardHidden"
    android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
    android:name=".Demo07Activity" >
    <intent-filter >
    <action android:name="android.intent.action.MAIN" />

    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    </activity>
    </application>

    <uses-permission android:name="andorid.permission.CHANGE_CONFIGURATION"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    </manifest>

    看看运行效果吧

          

    文章精选:

    http://www.blogjava.net/zh-weir/archive/2010/01/24/310617.html

    http://www.cnblogs.com/hibraincol/archive/2010/09/18/1829862.html

    http://hi.baidu.com/gaogaf/blog/item/6ef7184c3b20bff6d72afc2a.html

  • 相关阅读:
    架构-LAMP特级学习(网站加速解决方案)
    架构-LAMP特级学习(网站大存储量解决方案)
    架构-LAMP特级学习(网站大访问量解决方案)
    Shell-学习笔记
    算法-随手写的冒泡排序
    算法-随手写的二分查找
    cocos2dx 3.x ccPositionTextureColor_vert与ccPositionTextureColor_noMVP_vert
    cocos2dx当节点存在缩放时要注意的问题
    cocos2dx 3.x draw debug
    cocos2dx 3.x ccDrawLine一个坑
  • 原文地址:https://www.cnblogs.com/loulijun/p/2296505.html
Copyright © 2020-2023  润新知