《安卓开发官方文档》学习笔记一安卓基础以及相同activity间的Intent
文章开始把我喜欢的这句话送个大家:这个世界上还有什么比自己写的代码运行在一亿人的电脑上更酷的事情吗,如果有那就是让这个数字再扩大十倍
app/src/main/res/layout/activity_my.xml
这是刚才用Android Studio创建项目时新建的Activity对应的xml布局文件,按照创建新项目的流程,Android Studio会同时展示这个文件的文本视图和图形化预览视图,该文件包含一些默认设置和一个显示内容为“Hello world!”的TextView元素。
app/src/main/java/com.mycompany.myfirstapp/MyActivity.java
用Android Studio创建新项目完成后,可在Android Studio看到该文件对应的选项卡,选中该选项卡,可以看到刚创建的Activity类的定义。编译并运行该项目后,Activity启动并加载布局文件activity_my.xml,显示一条文本:"Hello world!"
app/src/main/AndroidManifest.xml
manifest文件描述了项目的基本特征并列出了组成应用的各个组件,接下来的学习会更深入了解这个文件并添加更多组件到该文件中。
创建一个LinearLayout
- 在Android Studio 中,从 res/layout 目录打开 content_my.xml 文件。
上一节创建新项目时生成的BlankActivity 包含一个 content_my.xml 文件,该文件根元素是一个包含 TextView 的 RelativeLayout。
- 在 Preview 面板点击 关闭右侧Preview 面板。
在Android Studio 中打开布局文件时,可以看到一个Preview 面板。点击这个面板中的标签,可利用WYSIWYG(所见即所得)工具在Design 面板看到对应的图形化效果。但在本节中,我们将学习如何直接修改XML 文件。
- 删除[<TextView>] 标签。
- 把[<RelativeLayout>] 标签改为[<LinearLayout>]。
- 为[<LinearLayout>] 添加 android:orientation 属性并设置值为 "horizontal"。
- 去掉 android:padding 属性和 tools:context 属性。
修改后结果如下:
res/layout/content_my.xml
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main">
LinearLayout 是 ViewGroup 的子类,用于放置水平或者垂直方向的子视图部件,放置方向由属性 android:orientation 决定。LinearLayout 里的子布局按照XML 里定义的顺序显示在屏幕上。
所有的Views 都会用到 android:layout_width 和 android:layout_height 这两个属性来设置自身的大小。不建议指定宽度和高度的具体尺寸,应使用 "wrap_content"
。因为这样可以保证视图只占据内容大小的空间
由于 LinearLayout 是整个视图的根布局,所以通过指定width 和height 属性为 "match_parent" 可以使其宽度和高度充满整个屏幕。该值表示子View 扩张自己宽度和高度来 匹配 父控件的宽度和高度。
res/layout/content_my.xml
<EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
各属性说明:
android:id
这是视图的唯一标识符。可以在程序代码中通过该标识符引用对象。例如对这个对象进行读和修改的操作(在下一课里将会用到)。
当需要从XML 里引用资源对象时,必须使用 @
符号。紧随 @
之后的是资源的类型(这里是 id
),然后是资源的名字(这里使用的是 edit_message
)。
+
号只在第一次定义一个资源ID 的时候需要。它是告诉SDK——此资源ID 需要被创建。在应用程序被编译之后,SDK 就可以直接使用这个ID。edit_message 是在项目文件 gen/R.java
中创建一个新的标识符,这个标识符和 EditText 关联。一旦资源ID 被创建了,其他资源如果引用这个ID 就不再需要 +
号。
1.这时按钮占据的大小就是按钮里文本的大小。这个按钮不需要指定 android:id 的属性,因为Activity 代码中不会引用该Button。-----send 按钮
当文本框为空的时候,会默认显示这个字符
在项目文件 gen/R.java
中,每个资源都有一个与之对应的资源对象。你可以使用 R
类中的对象名称代指资源(如:在指定 android:hint 属性时需要的字符串)。同时,也可以通过 android:id 属性随时为View 创建资源ID,以便在代码中引用这个View。
每次编译APP 时,SDK 工具都会生成 R.java
文件。所以,请永远不要修改这个文件。
增加字符串资源
默认情况下,你的Android 项目包含一个字符串资源文件,即 res/values/string.xml
。打开这个文件,为 "edit_message"
增加一个定义,其值为“Enter a message”。
让输入框充满整个屏幕的宽度
即利用 android:layout_weight 属性。
权重的值指的是每个部件所占剩余空间的大小,该值与同级部件所占空间大小有关。,我们定义一个权重为2 的View,另一个View 的权重是1,那么总数就是3;这时第一个View 占据2/3 的空间,第二个占据1/3 的空间。如果再加入第三个View,权重设为1,那么第一个View(权重为2 的)会占据1/2 的空间,剩余的另外两个View 各占1/4。(请注意,使用权重的前提一般是给View 的宽或者高的大小设置为0dp,然后系统根据上面的权重规则来计算View 应该占据的空间。但在很多情况下,如果给View 设置了match_parent 的属性,那么在计算权重时则不是通常的正比,而是反比。也就是说,权重值大的反而占据空间小)。
对于所有的View 默认的权重是0,如果只设置了一个View 的权重大于0,则该View 将占据除去别的View 本身占据的空间的所有剩余空间。因此这里设置EditText 的权重为1,使其能够占据除了按钮之外的所有空间。
<EditText
android:layout_weight="1"//占据除去别的view本身空间的所有空间。
android:layout_width="0dp"
... />
我们在调用setContentView设置布局的时候其实都是被放置在id为content的FrameLayout 布局中的
我们平时在Activity中调用的setContentView方法其实都是调用的PhoneWindow中的setContentView方法,其首先会判断mContentParent是否为null,如果为null,则执行installDecor()方法,在installDecor()方法中会对mDecor进行判断是否为null,为null则进行初始化,mDecor为DecorView类型,DecorView继承自FrameLayout。接下来继续判断mContentParent是否为null,为null则执行generateLayout方法,在generateLayout方法中最重要的逻辑就是根据我们设置的不同feature找到对应布局文件,并且inflate为View,通过addView方法加入到mDecor中,然后找到布局文件中ID为content的View作为generateLayout方法最终返回值返回。接下来回到installDecor方法将generateLayout返回值赋值给mContentParent,最后回到setContentView,将我们自己的布局文件layoutResID加载到mContentParent中。
DecorView继承自FrameLayout,我们知道 FrameLayout继承自ViewGroup,最终就是调用ViewGroup中的dispatchTouchEvent方法进行事件分发
3. <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send"
android:onClick="sendMessage" />
为使系统能够将该方法(你刚在MyActivity.java中添加的sendMessage方法)与在android:onClick属性中提供的方法名字匹配,它们的名字必须一致,特别需要注意的是,这个方法必须满足以下条件:
- 是public函数
- 无返回值
- 参数唯一(为View类型,代表被点击的视图)
构建一个Intent
Intent是在不同组件中(比如两个Activity)提供运行时绑定的对象。Intent
代表一个应用"想去做什么事",你可以用它做各种各样的任务,不过大部分的时候他们被用来启动另一个Activity。
Intent intent = new Intent(this, DisplayMessageActivity.class);
在这个Intent构造函数中有两个参数:
- 第一个参数是Context(之所以用
this
是因为当前Activity是Context
的子类) - 接受系统发送Intent的应用组件的Class(在这个案例中,指将要被启动的activity)
- 导入缺失的类(在Mac中使用option + return)
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
5 把EditText的文本内容关联到一个本地message 变量,并使用putExtra()方法把值传给intent.
1.1.4
在MyActivity class,定义EXTRA_MESSAGE :
java/com.mycompany.myfirstapp/MyActivity.java
public class MyActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = "com.mycompany.myfirstapp.MESSAGE";
...
}
Intent可以携带称作 extras 的键-值对数据类型。 putExtra()方法把键名作为第一个参数,把值作为第二个参数。
调用startActivity()完成新activity的启动
使用Android Studio创建新的Activity
--------------即 DisplayMessageActivity--------
核心:Intent intent = getIntent();
String message = intent.getStringExtra(MyActivity.EXTRA_MESSAGE);
代码如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
Intent intent = getIntent();
String message = intent.getStringExtra("abc");
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.content);
layout.addView(textView);
}
加油吧,程序员!