第一个APP的知识点以及对代码的理解
APP预览
主页面效果图
首先要做的就是界面设计
activity_quiz.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: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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button"/>
<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">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/prev_button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next_button"/>
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:text="@string/cheat_button"/>
</LinearLayout>
组件是用户界面的构造模块。组件可以显示文字或图像,与用户交互,甚至布置屏幕上的其他组件。按钮、文本输入控件和选择框等都是组件。
上图共含有如下几个组件:
一个垂直LinearLayout组件; 一个TextView组件; 三个个水平LinearLayout组件; 五个个Button组件。
创建字符串资源
字符串资源包含在一个独立的名为strings的XML文件中,需要在activity_quiz.xml文件中引用的字符串资源目前还不存在。现在我们来添加这些资源。 strings.xml
<resources>
<string name="app_name">GeoQuiz</string>
<string name="question_australia">堪培拉是澳大利亚的首都 </string>
<string name="true_button">TRUE</string>
<string name="false_button">FALSE</string>
<string name="prev_button">Prev</string>
<string name="cheat_button">Cheat!</string>
</resources>
现在,在GeoQuiz项目的任何XML文件中,只要引用到@string/false_button,应用运行时,就会得到文本“FALSE”
资源ID
要想对组件进行操作,首先要为组件生成资源ID,在activity_quiz.xml文件中,为按钮添加上android:id属性 为按钮添加资源ID(activity_quiz.xml),如:true button
android:id="@+id/true_button"
设置完id之后就可以在QuizActivity中直接获取它们
添加成员变量(QuizActivity.java)
private Button mTrueButton;
如果出现报错可能是因为没有导入包,按Alt+Enter组合键可以自动导入所需要的包
引用组件(QuizActivity.java)
添加完成员变量后就要开始引用
mTrueButton = (Button) findViewById(R.id.true_button);
设置监听器
监听器是实现特定监听器接口的对象,用来监听某类事件的发生。 当前应用需要监听用户的按钮单击事件,因此监听器需实现View.OnClickListener接口。
mTrueButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
}
});
当按钮mTrueButton被点击后,监听器会立即通知我们。传入setOnClickListener(OnClickListener)方法的参数是一个监听器。 该参数是一个实现了OnClickListener接口的对象。
创建提示消息
接下来要实现的就是,单击true按钮,弹出我们称为toast的提示消息。Android的toast是用来通知用户的简短弹出消息。 首先完善string.xml
<string name="correct_toast">Correct!</string>
<string name="incorrect_toast">Incorrect!</string>
使用代码自动补全,选择makeText(Context context, int resID, int duration)方法,完成makeText方法的全部参数设置
mTrueButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
Toast.makeText(QuizActivity.this,R.string.incorrect_toast,Toast.LENGTH_SHORT).show();
}
});
为了完善APP,增加题库,所有还需要为项目创建一个Question类,该类的一个实例代表一个问题,
然后再创建一个Question数组对象交由QuizActivity管理 Question.java
public class Question {
private int mTextResId;
private boolean mAnswerTrue;
public Question(int textResId,boolean answertrue){
mTextResId = textResId;
mAnswerTrue = answertrue;
}
public int getTextResId() {
return mTextResId;
}
public void setTextResId(int textResId) {
mTextResId = textResId;
}
public boolean isAnswerTrue() {
return mAnswerTrue;
}
public void setAnswerTrue(boolean answerTrue) {
mAnswerTrue = answerTrue;
}
}
Question类中封装的数据有两部分:问题文本和问题答案(true或false) 变量mTextResId用来保存地理知识问题字符串的资源ID。资源ID总是int类型,所以这里设置它为int而不是String类型
新增按钮以及文本视图的调整(activity_quiz.xml)
<TextView
android:id="@+id/question_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp" />
<Button
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next_button"/>
更新字符串资源定义(strings.xml)
<string name="next_button">Next</string>
添加问题库
<string name="question_oceans">太平洋比大西洋大</string>
<string name="question_mideast">苏伊士运河连接着红海和印度洋</string>
<string name="question_africa">尼罗河流域在埃及</string>
<string name="question_americas">亚马逊河是美国最长的河</string>
<string name="question_asia">贝加尔湖是世界上最古老最深的淡水湖</string>
下面要在QuizActivity.java文件中添加TextView和新Button变量。另外,再创建一个Question对象数组以及一个该数组的索引变量
增加按钮变量及Question对象数组(QuizActivity.java)
private Button mNextButton;
private TextView mQuestionTextView;
private Question[] mQuestionBank = new Question[]{
new Question(R.string.question_australia ,true),
new Question(R.string.question_oceans,true),
new Question(R.string.question_mideast,false),
new Question(R.string.question_africa,false),
new Question(R.string.question_americas,true),
new Question(R.string.question_asia,true)
};
private int mCurrentIndex=0;
引用TextView,并将其文本内容设置为当前数组索引所指向的地理知识问题
使用TextView(QuizActivity.java)
mQuestionTextView = (TextView) findViewById(R.id.question_text_view);
int question = mQuestionBank[mCurrentIndex].getTextResId();
mQuestionTextView.setText(question);
然后运行GeoQuiz应用。可看到数组存储的第一个问题显示在TextView上了
为Next按钮设置监听器
该监听器的作用是:递增数组索引并相应更新显示TextView的文本内容
mNextButton = (Button) findViewById(R.id.next_button);
mNextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCurrentIndex = (mCurrentIndex + 1) % mQuestionBank.length;
int question = mQuestionBank[mCurrentIndex].getTextResId();
mQuestionTextView.setText(question);
}
});
mCurrentIndex = (mCurrentIndex + 1) % mQuestionBank.length;这段代码表示向下切换,
所以在挑战练习中增加向上切换只需要把+1改成-1即可
使用updateQuestion()封装公共代码(QuizActivity.java)
private void updateQuestion(){
int question = mQuestionBank[mCurrentIndex].getTextResId();
mQuestionTextView.setText(question);
}
封装代码的只要目的是减少重复代码,可以直接调用
mNextButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
mCurrentIndex = (mCurrentIndex+1) % mQuestionBank.length;
updateQuestion();
}
});
增加方法checkAnswer(boolean)(QuizActivity.java)
private void checkAnswer(boolean userPressedTrue){
boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();
int messageResId = 0;
if(mIsCheater){
messageResId = R.string.judgment_toast;
}else {
if (userPressedTrue == answerIsTrue)
{
messageResId = R.string.correct_toast;
} else {
messageResId = R.string.incorrect_toast;
}
}
Toast.makeText(this,messageResId,Toast.LENGTH_SHORT).show();
}
private void checkAnswer(boolean userPressedTrue)该方法接受boolean类型的变量参数,判别用户单击了TRUE还是FAL S E按钮。 然后,将用户的答案同当前Question对象中的答案作比较。最后,判断答案正确与否,生成一个Toast消息反馈给用户。
调用方法checkAnswer(boolean)(QuizActivity.java)
在按钮的监听器里,调用checkAnswer(boolean)方法
mTrueButton = (Button) findViewById(R.id.true_button);
mTrueButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
//Toast.makeText(QuizActivity.this,R.string.incorrect_toast,Toast.LENGTH_SHORT).show();
checkAnswer(true);
}
});
为按钮添加图标,需要在XML文件中引用资源
<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"
/>
日志跟踪理解Activity生命周期
输出日志信息
Android的android.util.Log类能够发送日志信息到系统级别的共享日志中心。Log类有好几个日志记录方法。本书使用最多的是以下方法:public static int d(String tag, String msg), d代表着“debug”的意思,用来表示日志信息的级别。第一个参数表示日志的来源,第二个参数表示日志的具体内容。该方法的第一个参数通常以类名为值的TAG常量传入。这样,很容易看出日志信息的来源。
新增一个TAG常量(QuizActivity.java)
private static final String TAG = "QuizActivity";
为onCreate(...)方法添加日志输出代码(QuizActivity.java)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG,"onCreate(Bundle)called");
setContentView(R.layout.activity_quiz);
覆盖更多生命周期方法(QuizActivity.java)
@Override
public void onStart(){
super.onStart();
Log.d(TAG,"onStart() called");
}
@Override
public void onResume(){
super.onResume();
Log.d(TAG,"onResume() called");
}
@Override
public void onPause(){
super.onPause();
Log.d(TAG,"onPause() called");
}
@Override
public void onStop(){
super.onStop();
Log.d(TAG,"onStop() called");
}
@Override
public void onDestroy(){
super.onDestroy();
Log.d(TAG,"onDestroy() called");
}
创建CheatActivity,实现界面跳转
一个activity启动另一个activity最简单的方式是使用以下startActivity方法: public void startActivity(Intent intent)
基于intent的通信
intent对象是component用来与操作系统通信的一种媒介工具 在GeoQuiz应用中,intent用来告诉ActivityManager该启动哪个activity,因此可使用以下构造方法: public Intent(Context packageContext, Class<?> cls) 传入该方法的Class类型参数告诉ActivityManager应该启动哪个activity; Context参数告诉ActivityManager在哪里可以找到它
启动CheatActivity(QuizActivity.java)
在mCheatButton的监听器代码中,创建包含CheatActivity类的Intent实例,然后将其传入startActivity(Intent)方法
mCheatButton = (Button)findViewById(R.id.cheat_button);
mCheatButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(QuizActivity.this, CheatActivity.class);
startActivity(i);
}
})
转载于:https://www.cnblogs.com/mhhs/p/7525480.html