Android学习笔记(三六):横屏竖屏的切换

1、准备环境

  对模拟器,只要“Ctrl+F12“,就可以可以实现竖屏(portrait)和横屏(landscape)的切换。

2、UI的屏幕切换实现

下面一个简单的例子,如图。

我们需要写两个Android XML文件,假定文件为chapter_19_test1.xml,放在常规目录位置layout/内容如下:

[plain] view plaincopy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent">
  6. <Button android:id="@+id/c19_pick"
  7. android:layout_width="fill_parent"
  8. android:layout_height="fill_parent"
  9. android:layout_weight="1"
  10. android:text="Pick"
  11. android:enabled="true" />
  12. <Button android:id="@+id/c19_view"
  13. android:layout_width="fill_parent"
  14. android:layout_height="fill_parent"
  15. android:layout_weight="1"
  16. android:text="View"
  17. android:enabled="false" />
  18. </LinearLayout>

另一个位于layout-land/目录下面,文件名称一样,这里是landsapce的排版,简单地,我们只作少许改动,将LinearLayout中的android:orientation="vertical",修改为android:orientation="horizontal",这样就可以了。

3、切换中出现什么事情

Is it so easy?在Android,关于layout widget,系统会根据你的xml文件自动进行屏幕旋转,选择正确的xml文件来进行布局。很智能吧?是的,但是仅此而已。我们做个实验:在上面xml的基础上,每按一次pick按钮,计数器testNum就加一,为了直观简单,testNum的值通过System.out打印处理,并在Button上直接显示。测试代码如下:

[java] view plaincopy

  1. public class Chapter19Test1 extends Activity{
  2. private int testNum = 0; //实验:跟踪testNum
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.chapter_19_test1);
  7. Button pickButton = (Button)findViewById(R.id.c19_pick);
  8. pickButton.setText("Pick : " + testNum);
  9. pickButton.setOnClickListener(new View.OnClickListener() {
  10. /*每按pick按键一次,计数器testNum就加一*/
  11. public void onClick(View v) {
  12. testNum ++;
  13. System.out.println("Pick : " + testNum);
  14. ((Button)v).setText("Pick : " + testNum);
  15. }
  16. });
  17. viewButton.setEnabled(contact != null);
  18. }

我们在竖屏的情况下按pick的按键,三次后,然后通过"ctrl+F12"从竖屏转为横屏,再按,发现testNum没有按照与其,继续计数,而是重新开始计算,而我们希望的是能保留原来的状。在屏幕的切换中Android会destroy并re-create我们的activity。这就意味这你需要保存你的数据并且在切换的时候从保存的数据中恢复状态

4、保存数据

我们使用onSaveInstanceState()来进行数据保存,由于是re-create,在屏幕转换时会触发onCreate(),也可以在onRestoreInstanceState()中对数据进行恢复。

[java] view plaincopy

  1. protected void onCreate(Bundle savedInstanceState) {
  2. ... ...
  3. Button pickButton = (Button)findViewById(R.id.c19_pick);
  4. /*从Bundle中获取保存的数据,进行恢复*/
  5. if(savedInstanceState != null){
  6. testNum = savedInstanceState.getInt("count");
  7. }
  8. pickButton.setText("Pick : " + testNum);
  9. pickButton.setOnClickListener(new View.OnClickListener() {
  10. ......
  11. });
  12. }
  13. @Override
  14. /*通过onSaveInstanceState()来进行数据保存,存放如Bundle中。*/
  15. protected void onSaveInstanceState(Bundle outState) {
  16. // TODO Auto-generated method stub
  17. super.onSaveInstanceState(outState);
  18. outState.putInt("count", testNum);
  19. }

5、稍有趣一点的例子

在上面的例子中,我们按pick按钮,采用Intent方式进入contact列表,在列表中选择某个contact,并返回。通过startActivityForResult的调用方式,我们可以获得返回值。按View按钮,这可以显示该contact的详细信息。在这个例子中,我们学习下面的几个内容:
1)如何调用contact列表new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);,如何调用查看某个contact的详细内容new Intent(Intent.ACTION_VIEW,contact)
2)如何调用带返回的intent:startActivityForResult(intent,requestCode);
3)在横竖屏切换中,复习保存数据(contact)并恢复原来状态。值得注意的是:下面的处理并不仅仅是为了横竖屏,还包括其他的恢复,例如因为电池能源太低而造成的activity的close。

[java] view plaincopy

  1. public class Chapter19Test1 extends Activity{
  2. static final int PICK_REQUEST=1000;
  3. private Button viewButton = null;
  4. private Uri contact = null;
  5. protected void onCreate(Bundle savedInstanceState) {
  6. ... ...
  7. pickButton.setOnClickListener(new View.OnClickListener() {
  8. /* 下面给1)如何调用contact列表;2)如何调用代返回值的intent */
  9. public void onClick(View v) {
  10. Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
  11. startActivityForResult(intent, PICK_REQUEST);
  12. }
  13. });
  14. viewButton.setOnClickListener(new View.OnClickListener() {
  15. /* 1)如何调用显示某个contact的详细内容*/
  16. public void onClick(View v) {
  17. startActivity(new Intent(Intent.ACTION_VIEW,contact));
  18. }
  19. });
  20. restoreMe(savedInstanceState);
  21. viewButton.setEnabled(contact != null);
  22. }
  23. @Override
  24. /* 2)如何获取intent的返回数值,通过requestCode的匹配,确定是否我们所需*/
  25. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  26. super.onActivityResult(requestCode, resultCode, data);
  27. if(requestCode == PICK_REQUEST){
  28. if(resultCode == RESULT_OK){
  29. contact = data.getData();
  30. viewButton.setEnabled(true);
  31. }
  32. }
  33. }
  34. @Override
  35. /* 3)用于屏幕旋转等情况的数据保存,这是系统自动调用的。*/
  36. protected void onSaveInstanceState(Bundle outState) {
  37. super.onSaveInstanceState(outState);
  38. if(contact != null){
  39. outState.putString("contact", contact.toString());
  40. }
  41. }
  42. /* 3)在onCreate中调用,用与屏幕旋转时,恢复数据,其实还包括了其他的情况,例如电池电能太低*/
  43. private void restoreMe(Bundle  state){
  44. contact = null;
  45. if(state != null){
  46. String contactUri = state.getString("contact");
  47. if(contactUri != null){
  48. contact = Uri.parse(contactUri);
  49. }
  50. }
  51. }
  52. }

6、用onSaveInstanceState()保存数据的局限和替换方式

  在例子中,使用了 onSaveInstanceState()来保存数据,这个调用不仅仅是在横屏竖屏的切换,同时也在其他引起中断的处理,例如低memory,因此数据保存不仅是串行进行的同时和当前之执行的进程无关。局限在于只能通过bundle来保存。

  在一些activty的情况下,这样处理是没有问题,但是另一些,例如在线聊天,我们无法通过bundle将object(例如socket)保存起来,如果仅仅保存socket的信息(ip地址、端口)是没有意义的,也就是在横屏和竖屏的切换会导致连接的断开和重连接。显然不是我们期待的。

  解决方法是用onRetainNonConfigurationInstance()来替代onSaveInstanceState()。用它来保存object,并通过getLastNonConfigurationInstance()来获取。这样我们可以保存socket,thread等等。上面的例子,可以修订如下:

[java] view plaincopy

  1. public class Chapter19Test2 extends Activity{
  2. ... ...
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. ... ...
  6. /* 恢复数据 */
  7. restoreMe();
  8. ... ...
  9. }
  10. ... ...
  11. @Override
  12. /*通过onRetainNonConfigurationInstance()直接保存object,在之前的例子是保存了Uri的toString()信息*/
  13. public Object onRetainNonConfigurationInstance() {
  14. return contact;
  15. }
  16. /* 恢复数据,直接获得对象*/
  17. private void restoreMe(){
  18. contact = null;
  19. if(getLastNonConfigurationInstance()!= null){
  20. contact = (Uri)getLastNonConfigurationInstance();
  21. }
  22. }
  23. }

相关链接: 我的Android开发相关文章

时间: 2024-10-24 15:49:42

Android学习笔记(三六):横屏竖屏的切换的相关文章

【转】Android 模拟器横屏竖屏切换设置

http://blog.csdn.net/zanfeng/article/details/18355305# Android 模拟器横屏竖屏切换设置时间:2012-07-04   来源:设计与开发   作者:Daniel   点击:5571 摘要:  Android 模拟器旋转,横屏.竖屏切换设置,android 横屏布局,android 横屏模式,android 模拟器,android 模拟器横屏,android 模拟...       Android 模拟器旋转,横屏.竖屏切换设置,andr

Android学习笔记(三七):再谈屏幕切换

切换需注意数据保存和恢复 在Android学习笔记(三六):横屏竖屏的切换中,我们配置了两个layout,一个用户普通的portrait,一个用户landsapce方式.如果只有一个layout,我们沿用上一个例子,删除了在layout-land/中的xml文件,则在屏幕切换时,会按照原来的排版,适配新的屏幕.程序我进行了简化,每按一次pick,就加一,用此来跟踪是否需要进行数据保存和恢复,如下: [java] view plaincopy public class Chapter19Test3

Android之横屏竖屏显示问题

1.采用不同的布局文件 res文件下 选中layout  Ctrl+C 选中res Ctrl +V 创建layout-land横屏显示的layout 同理创建layout-port竖屏显示的layout 图片横屏竖屏 选中drawable-xhdpi Ctrl+C 选中res Ctrl + V 创建drawable-land-xhdpi 其他分辨率的也一样 字符串 values-land values-port 另外:(layout文件夹也可以使用hdip,mdip等关键字命名如layout-h

Android学习笔记进阶之在图片上涂鸦(能清屏)

Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java [java] view plaincopy package xiaosi.handWriting; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import andro

Android点九技术,横屏竖屏界面保持不失真

转载至:http://blog.csdn.net/heimabb/article/details/8481406 “点九”是android平台的应用软件开发里的一种特殊的图片形式,文件扩展名为:.9.png智能手机中有自动横屏的功能,同一幅界面会在随着手机(或平板电脑)中的方向传感器的参数不同而改变显示的方向,在界面改变方向后,界面上的图形会因为长宽的变化而产生拉伸,造成图形的失真变形.我们都知道android平台有多种不同的分辨率,很多控件的切图文件在被放大拉伸后,边角会模糊失真.OK,在an

android界面横屏和竖屏的切换

关于android横屏和竖屏的切换网上给了很多种.但是有些介绍的方法都是在android旧版本上. 我现在把握用到的情况写下来用于备忘: android 版本:4.0 - 4.4 要求:android 横竖屏转换时不需要重新调用oncreate方法 步骤: 1.在Androidmenifest相应的activity里面添加 android:configChanges="orientation|keyboardHidden|screenSize" 2.在代码中比如(RoomActivit

android 模拟器 横屏 竖屏切换

1.android 模拟器 横屏 竖屏切换 快捷方式:ctrl+F11 2.eclipse 开发使UI设计界面横屏显示

Pro Android学习笔记(二九):用户界面和控制(17):include和merge

xml控件代码重用:include 如果我们定义一个控件,需要在不同的layout中重复使用,或者在同一个layout中重复使用,可以采用include的方式.例如定义my_button.xml如下 <?xml version="1.0" encoding="utf-8"?> <Button xmlns:android="http://schemas.android.com/apk/res/android"     androi

Android学习笔记(三九):资源resource(下)

在上一次学习笔记中,学习了XML文件的解析,实际上一些简单的activity属性,一些简单的信息,我们也可以放入xml文件中,可以直接放入res/vaules,由系统来进行解析,而无须使用XmlPullParser来自己分析. Dimension 用于字体大小,间距pading等等.常用的尺寸大小详细见Android 学习笔记(十四):Activity-AutoCompleteTextView,一般我们使用dip/dp和sp,因为和in(inch),mm,以及px(像素点)不同,它和物理屏幕尺寸