Android 中常用的计量单位
Android有时候需要一些计量单位,比如在布局Layout文件中可能需要指定具体单位等。
常用的计量单位有:px、dip(dp)、sp,以及一些不常用的pt、in、mm。下面详细介绍下这些计量单位之间的区别和联系。
in:英寸(长度单位);
mm:毫米(长度单位);
pt:磅/点,1/72英寸(一个标准的长度单位);
sp:全名 scaled pixels-best for text size,放大像素,与刻度无关,可以根据用户的字体大小就行缩放,主要用来处理字体的大小;
px:屏幕中的像素;
dip(dp):设备独立像素,一种基于屏幕密度的抽象单位;因为不通设备中有不同的显示效果,所以为了解决在不通分辨率手机上运行不至于相差太大的问题,引入了dip计量单位,这种计量单位与移动设备硬件无关。

说道密度,这里简单介绍下。手机密度值(Density)表示每英寸有多少个显示点,与手机的分辨率是两个概念,但是分辨率与密度之间又互相关联,两者转换公式为:
密度值是120,屏幕实际分辨率为:240px×400px(两个点对应一个分辨率);
密度值是160,屏幕实际分辨率为:320px×533px(3个点对应两个分辨率);
密度值是240,屏幕实际分辨率为:480px×800px(一个点对应一个分辨率)。

比如,QVGA与WQVGA屏的密度值是120,HVGA屏密度值是160,WVGA屏密度值是240.

res资源目录,因为运行的设备的不同,对应的资源文件目录也不同。其真正的原因是,资源目录是根据密度的不同来进行划分的:
密度值是120,对应的资源目录是drawable-ldpi;
密度值是160,对应的资源目录是drawable-mdpi;
密度值是240,对应的资源目录是drawable-hdpi。

根据以上介绍,在布局中应该尽量使用dip(dp)作为单位;而定义作为文字大小的单位则推荐使用sp。

Context
Context 类是一个抽象类,它的子类很多,比如 Activity 、 TabActivity 、Service 等。很多方法中需要传入 Context 参数才可实例对象,例如 Toast 实例对象时,第一个对象需传入 Context 对象。其实 Context 从字面上可以理解为类似于句柄,联系上下文的意思。因为 Activity 是 Context 的子类,所以一般在 Activity 中使用 Context 的时候,可以用 this 来代替,但是如果在内部类中(如利用内部类使用监听组件),就不能使用 this 来代替 Context ,而是使用 "ActName.this" ,这里的 ActName 指的是 Activity 类的类名。

在Android中的 Context 可以有很多操作,但是最主要的功能是加载和访问资源,具体可以看下官方文档:http://developer.android.com/reference/android/content/Context.html

Resources与getResources
在 Android 资源(Resource)都会自动由 R.java 资源文件生成对应的静态 ID ,通过 R 资源文件对资源生成的 ID 来引用。这样在资源需要修改的时候,就不用去程序源代码中修改,直接修改对应res下的资源文件即可。
在源代码中,如果需要对资源目录下的 string.xml 中定义的字符串变量进行访问,只需要通过 getResources 的方式引用即可。
例如,需要引用 string.xml 中的一个字符串,其变量为 "hello_world",获取方式如下:

getResources().getString(R.string.hello_world);

再如需要引用 drawable 目录下的一张名为"goodby_times.png"的图片,获取方式如下:

getResources().getDrawable(R.drawable.goodby_times);

当然一些函数不仅支持传入 String 类型,也支持传入引用 ID 。例如 TextView 中的setText() 函数,这个方法不仅支持传入 String 类型,还支持 R 文件引用 ID 的参数。"R.string.strName"中的 strName 表示在 string.xml 中定义的字符串在 R 资源文件中生成的对应 ID 索引。

findViewById与LayoutInflater
LayoutInflater 的作用类似于 findViewById(),两者不同之处在于 LayoutInflater 是用来实例化 xml 布局文件中的布局:而 findViewById,顾名思义,是通过 ID 来找到 xml 布局文件中定义的组件,比如 EditText、TextView、Button 等等。
关于用 LayoutInflater 来实例布局的方式有两种:
1.通过传入 Context 参数来获得 LayoutInflater 实例,然后调用 LayoutInflater 类中的 inflate 函数来得到布局实例。

LayoutInflater inflater = LayoutInflater.from(Context context) ;
View view = inflater.inflate(R.layout.activity_main, null);

2.通过系统服务来获取到 LayoutInflater 实例,然后调用 LayoutInflater 类中的 inflate 函数来得到布局实例。

LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.activity_main, null);

尽管实例布局的形式不同,但是这两种布局方式的性质没有区别。

多个Activity之间跳转/退出/传递数据操作

主要代码:

package yc.example.activityex;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;public class MainActivity extends Activity implements OnClickListener {private Button btnOpen, btnHide, btnExit;// 声明按钮private static String[] arrStr = new String[] { "有自己的目标,那就去实现它,语言总苍白无力。","他的速度快逾闪电,连残影都模糊不清,如同一团风。", "他脑海中,只有一个念头:快!再快一点!再快一点!" };private static int ARR_INT = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 实例化按钮btnOpen = (Button) this.findViewById(R.id.btnOpen);btnHide = (Button) this.findViewById(R.id.btnHide);btnExit = (Button) this.findViewById(R.id.btnExit);// 给每个按钮添加监听器btnOpen.setOnClickListener(this);btnHide.setOnClickListener(this);btnExit.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btnOpen:// 创建一个意图,并设置需打开的ActivityIntent intent = new Intent(MainActivity.this, OtherActivity.class);if(ARR_INT>=arrStr.length) ARR_INT =0;// 发送数据intent.putExtra("info", arrStr[ARR_INT++]);// 启动另外一个Activitythis.startActivity(intent);break;case R.id.btnHide:/** finish()函数表示退出当前 Activity 。* 执行此函数会调用生命周期中的onStop()与onDestory()函数,但是这仅仅是将当前的 Activity 推到后台,* 程序中的资源仍然存在,如果 Android 运行内存不是很紧张的情况下,程序是不会真正退出的。*/this.finish();break;case R.id.btnExit:/** System.exit(0) 函数表示退出当前的程序。 当 Android* 执行到此函数的时候,本应用程序的资源将被回收,并退出此程序。*/System.exit(0); // 退出程序break;}}}

package yc.example.activityex;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;public class OtherActivity extends Activity {private TextView tv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);tv = new TextView(this);setContentView(tv);//得到当前 Activity 的意图Intent intent = this.getIntent();//获取数据String info = intent.getStringExtra("info");//将获取到的数据设置成 TextView 文本
        tv.setText(info);}}

PS:记得在 AndroidManifest.xml 文件中声明新建的Activity,不然应用会由于找不到活动而报异常。

<!-- 下面是注册新建的Activity(OtherActivity) --><activity android:name="yc.example.activityex.OtherActivity"></activity>

横竖屏切换处理的三种方式
Android 手机中运行应用的时候,一般用户都是竖屏,但是如果突然将手机横屏,那么很可能就会造成程序出现异常,因为在 Android 中每次屏幕切换都会重启当前的 Activity 。这种情况下,异常的解决方式有一下三种。

1.锁定横竖屏切换
此方式只需要在 AndroidManifest.xml 文件中,对 Activity 定义屏幕方向属性只能为横屏或者竖屏即可
将屏幕固定为竖屏显示

<activity android:screenOrientation="portrait">

将屏幕固定为横屏显示

<activity android:screenOrientation="landscape">

其他参数:
"unspecified":默认值 由系统来判断显示方向.判定的策略是和设备相关的,所以不同的设备会有不同的显示方向.
"landscape":横屏显示(宽比高要长)
"portrait":竖屏显示(高比宽要长)
"user":用户当前首选的方向
"behind":和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)
"sensor":有物理的感应器来决定。如果用户旋转设备这屏幕会横竖屏切换。
"nosensor":忽略物理感应器,这样就不会随着用户旋转设备而更改了("unspecified"设置除外)。

因为一个 Android 应用程序中可能会有多个 Activity ,那么可以根据需要去配置每一个 Activity 的显示方式,如果不设置,默认可以横竖屏切换。

或者在源码中设置横竖屏:
设置竖屏

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

设置横屏

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

2.源代码中处理横竖屏切换事件
首先在AndroidManifest.xml中为Activity设置configChanges属性

android:configChanges="orientation|screenSize"

然后在对应的 Activity 源代码中重写 onConfigurationChanged() 函数即可。这样处理后,当横竖屏切换的时候,就会响应其 Activity 中的 onConfigurationChanged() 函数,然后对横竖屏做出判断处理。

package yc.example.helloworld;import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;public class MainActivity extends Activity {private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.i("--Main--", "onCreate");  textView=(TextView)findViewById(R.id.tv);  }@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);Log.i("--Main--", "onConfigurationChanged");  if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {textView.setText("当前屏幕为竖屏");  } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {textView.setText("当前屏幕为横屏");  }}}

此方式就不会在切换横竖屏的时候,Activity 默认重启了。

3.重写 onRestoreInstanceState() 与 onSaveInstanceState() 函数代码:

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.i("YInfo", "onRestoreInstanceState()");
}@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i("YInfo", "onSaveInstanceState()");
}

在屏幕切换横竖屏的时候,会响应 onSaveInstanceState() 函数,然后重启载入当前的 Activity ,最后响应 onRestoreInstanceState() 函数,所以可以通过重写这两个函数,进行屏幕横竖屏切换时的处理。

以上3种处理横竖屏切换方式,根据当前应用来进行选择。

【读书笔记《Android游戏编程之从零开始》】8.Android 游戏开发常用的系统控件(系统控件常见问题)相关推荐

  1. 《Android游戏编程之从零开始》书评之基础的魅力

    拜读完<Android游戏编程之从零开始>的试读章节之后,感受颇深,对于游戏开发过程中用到的知识,有了初步的了解,此书就一些基本图形为例,展开对游戏开发的基本原理的阐述.本人感觉,介绍一种 ...

  2. 【Android】Android游戏编程之从零开始

    <Android游戏编程之从零开始>主要系统地讲解了Android游戏开发,从最基础部分开始,让零基础的Android初学者也能快速学习和掌握Android游戏开发.<Android ...

  3. 【通知】▁▂▃ Himi 著作《Android游戏编程之从零开始》★书籍源码+第4/6/7样章★博客系列源码整理打包-免费下载★ ▃▂▁

    2011年9月22日(Himi的22岁生日当天),Himi的著作:<Android游戏编程之从零开始>一书正式发售: (大家可以到新华书店.淘宝.拍拍.当当.亚马逊等进行购买): 感谢一直 ...

  4. [转] Himi 著作《Android游戏编程之从零开始》★书籍源码+第4/6/7样章—免费下载★...

    本文转自:http://blog.csdn.net/xiaominghimi/article/details/6802444 Himi 原创, 转载请注明出处,谢谢! 原文地址:http://blog ...

  5. [置顶]▁▂▃ Himi 著作《Android游戏编程之从零开始》★书籍源码免费下载★ ▃▂▁...

    Himi 原创, 转载请注明出处,谢谢! 原文地址:http://blog.csdn.net/xiaominghimi/article/details/6802444 2011年9月22日(Himi的 ...

  6. ★书籍源码免费下载★Himi 著作《Android游戏编程之从零开始》

    2011年9月22日(Himi的22岁生日当天),Himi的著作:<Android游戏编程之从零开始>一书正式发售:(请到书店.淘宝.当当网等进行购买) 感谢一直以来关注Himi的童鞋们. ...

  7. Windows游戏编程之从零开始d

    Windows游戏编程之从零开始d I'm back~~恩,几个月不见,大家还好吗? 这段时间真的好多童鞋在博客里留言说或者发邮件说浅墨你回来继续更新博客吧. woxiangnifrr童鞋说每天都在来 ...

  8. 【通知】▁▂▃ Himi 最新著作《iOS游戏编程之从零开始—Cocos2d-x与cocos2d引擎游戏开发》★书籍源码+第4/5/6样章★-免费下载★ ▃▂▁

    2013年新年,Himi的第二本著作:<iOS游戏编程之从零开始-Cocos2d-x与cocos2d引擎游戏开发>一书正式发售: (大家可以到新华书店.淘宝.拍拍.当当.亚马逊等进行购买) ...

  9. 【浅墨著作】 逐梦旅程 Windows游戏编程之从零开始 勘误 配套源代码下载

    这段时间真的好多童鞋在博客里留言说或者发邮件说浅墨你回来继续更新博客吧. woxiangnifrr童鞋说每天都在来浅墨的博客逛一下看有没有更新,"每天都来就像看女神那般不依不舍", ...

  10. 读书笔记——《Python编程从入门到实践》第二章

    读书笔记--<Python编程从入门到实践>第二章 读书笔记--<Python编程从入门到实践>第二章 变量 如何使用变量 如何规范变量命名 字符串 字符串是什么 如何修改字符 ...

最新文章

  1. LaxTex---问题1: ! I can't write on file `***.pdf'.(Press Enter to retry, or Control-Z to exit; \ldots
  2. 宋体节点hdoj 1520 Anniversary party(树形dp)
  3. Android-Binder进程间通讯机制-多图详解
  4. mysql连接超过8小时错误_mysql超过8小时数据库断掉连接的简单解决办法
  5. 理解Android进程创建流程
  6. 数据库分页和使用jstl标签替换分页的jsp代码
  7. android4.0 开机启动activity 4.0,如何正确理解和使用Activity的4种启动模式
  8. 简单的深度优先遍历和广度优先遍历
  9. 1.4编程基础之逻辑表达式与条件分支 05 整数大小比较
  10. Android 系统(153)--- M上默认接入点apn显示
  11. 箭头 运算符_论普通函数和箭头函数的区别以及箭头函数的注意事项和不适用场景...
  12. 百度云网盘高速通道加速破解版 去广告纯净版干净云
  13. ffmpeg的下载及安装
  14. 日志管理系统之保存日志到数据库
  15. Linux 性能优化全景指南
  16. 一键重装win10换win7系统重装系统
  17. 【es】elasticsearch生产数据备份和恢复方案
  18. 超市销售数据分析python、求某一个人的营业额总和_Python+pandas使用交叉表分析超市营业额数据!这超市怕是!...
  19. Ubuntu卸载安装包
  20. 字节跳动大数据研发面试——自我反省

热门文章

  1. 想用数据库“读写分离”,请先明白“读写分离”解决什么问题
  2. (2)Spring框架----IOC基础快速入门
  3. Django DetailView 多重继承 关系整理
  4. Redis 数据结构之dict(2)
  5. JS 一个简单的隔行变色函数
  6. Android Gradle 完整指南(转)
  7. unity, 判断可见性
  8. Android Sqite数据库 9
  9. VC++中视频采集系统(摄像头的制作,串口通信的应用)
  10. WCF服务启动时遇到AddressAccessDeniedException