XML布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="@+id/question_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/true_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button" />
<Button
android:id="@+id/false_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/false_button" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/pre_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pre_button"
android:drawableLeft="@drawable/arrow_left"
android:drawablePadding="4dp" />
<Button
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next_button"
android:drawableRight="@drawable/arrow_right"
android:drawablePadding="4dp" />
</LinearLayout>
<Button
android:id="@+id/cheat_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cheat_button" />
</LinearLayout>
组件
LinearLayout、TextView、Button、…
组件可以显示文字或图像,与用户交互。每一个组件都是View类或其子类的一个具体实例。
组件属性
-
android:layout_width和android:layout_height
- match_parent:视图与其父视图大小相同
- wrap_content:视图将根据其内容自动调整大小
-
android:padding:内边距
- 24dp:dp表示密度无关像素
-
android:orientation:子组件的放置方向
- vertical:垂直放置
- horizontal:水平放置
-
android:text:组件要显示的文字内容
- @string/xxx:字符串资源的引用
样式、主题、主题属性
样式(style)是XML资源文件,含有用来描述组件行为和外观的属性定义。例如,下列样式资源能够配置组件,让其显示的文字大小大于正常值:
<style name="BigTextStyle">
<item name="android:textSize">20sp</item>
<item name="android:padding">3dp</item>
</style>
可以自己创建样式文件,将其保存在res/values/values中,然后在布局文件中以@style/xxx来引用。
主题是各种样式的集合。从结构上来说,主题本身也是一种样式资源,只不过它的属性指向了其他样式资源。
使用主题属性引用,可将预定义的应用主题样式添加给指定组件:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_title_label"
style="?android:listSeparatorTextViewStyle" />
字符串资源
string.xml
<resources>
<string name="app_name">知识测试</string>
<!-- MainActivity -->
<string name="question_week">每周的第一天是星期一。</string>
<string name="question_river">尼罗河是世界第一长河。</string>
<string name="question_marriage">我国法定结婚年龄是20岁。</string>
<string name="question_summer">夏天一般指4~6月。</string>
<string name="question_lightning">闪电和打雷是因果关系。</string>
<string name="true_button">正确</string>
<string name="false_button">错误</string>
<string name="pre_button">上一题</string>
<string name="next_button">下一题</string>
<string name="correct_toast">回答正确!</string>
<string name="incorrect_toast">回答错误!</string>
<!-- CheatActivity -->
<string name="warning_text">你确定要这么做吗?</string>
<string name="show_answer_button">显示答案</string>
<string name="cheat_button">作弊</string>
<string name="judgment_toast">作弊是不对的。</string>
</resources>
从布局XML到视图对象
/**
* 获取activity的用户界面
* @param id int
*/
setContentView(R.layout.activity_main);
为组件添加资源ID
Android为整个布局文件以及各个字符串生成资源ID,但activity_main.xml布局文件中的组件除外,因为不是所有的组件都需要资源ID。
- android:id
- @+id/xxx:为组件添加资源ID,标识符为xxx
组件的实际使用
引用组件
/**
* 引用已生成的组件
* @param id int
* @return View
*/
mTrueButton = (Button) findViewById(R.id.true_button);
设置监听器
/**
* 为按钮设置单击事件监听器
* @param 实现了OnClickListener接口的对象
*/
mTrueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkAnswer(true);
}
});
创建提示消息
/**
* 创建一个toast
* @param context Context
* @param resId int
* @param duration int
* @return Toast
*/
Toast.makeText(this, messageResId, Toast.LENGTH_SHORT).show();
为TextView更新内容
int questionId = mQuestionBank[mCurrentIndex].getTextResId();
mQuestionTextView.setText(questionId);
添加图标资源
切换到Project视图,在res目录下新建目录drawable-mdpi,然后添加图标文件。完成后为需要的组件添加属性:
-
android:drawableRight和android:drawableLeft
- @drawable/xxx
-
android:drawablePadding
- 4dp
Activity的生命周期
设备旋转与Activity生命周期
设备旋转时,系统会销毁当前MainActivity实例,然后创建一个新的MainActivity实例。
输出日志信息
public static final String TAG = "QuizActivity";
Log.d(TAG, "The current question index is " + mCurrentIndex);
设备旋转
创建水平模式布局
右键单击res目录,New => Android Resource Directory,Resource type选择layout,将Orientation添加至右侧,选择Landscape选项,单击OK。
复制或新建activity_main.xml至layout-land目录,注意布局文件名必须相同,修改布局文件:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/question_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="24dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:orientation="horizontal" >
<Button
android:id="@+id/true_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button" />
<Button
android:id="@+id/false_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/false_button" />
</LinearLayout>
<Button
android:id="@+id/cheat_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:text="@string/cheat_button" />
<Button
android:id="@+id/pre_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|left"
android:text="@string/pre_button"
android:drawableLeft="@drawable/arrow_left"
android:drawablePadding="4dp" />
<Button
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:text="@string/next_button"
android:drawableRight="@drawable/arrow_right"
android:drawablePadding="4dp" />
</FrameLayout>
FrameLayout不以特定方式安排其子视图的位置,其子视图的位置排列取决于它们各自的android:layout_gravity属性。
设备旋转前保存数据
可以通过覆盖Activity方法onSaveInstanceState来(Bundle)实现:
private static final String KEY_INDEX = "index";
/**
* 将数据(键值对)保存在bundle中
* @param outState Bundle
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG, "onSaveInstanceState...");
outState.putInt(KEY_INDEX, mCurrentIndex);
}
onSaveInstanceState(Bundle)方法通常在onPause()、onStop()、onDestroy()方法之前由系统调用。
Bundle是存储字符串键与限定类型值之间映射关系(键值对)的一种结构。
覆盖onCreate(Bundle)方法时,我们实际是在调用activity父类的onCreate(Bundle)方法,并传入收到的bundle。在父类代码的实现里,通过取出保存的视图状态数据,activity的视图层级结构得以重新创建。
获取存储的bundle信息
if (savedInstanceState != null)
mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0);
Android应用调试
记录日志
设置断点
使用异常断点
使用Android Lint
Android Lint是Android应用代码的静态分析器。
Analyze => Inspect Code => Whole project => OK