- 用户界面设计
- Android 与MVC模式
- Activity生命周期
- 第二个Activity
- 心得体会
用户界面设计
用户界面是由组件构造而成的,它可以显示文字或图像,与用户交互,甚至布置屏幕上的其他组件。默认的activity布局是由
RelativeLayout
和TextView
两个组件构成。且一个activity只能有一个LinearLayout
根元素,作为根元素,必须指定Android XML的资源文件的命名空间(namespace)属性。
Android 与MVC模式
Android 应用是基于MVC模式开发的,模型——视图——控制器的架构模式。
模型对象:存储应用的数据和业务逻辑
视图对象:用户界面,由各类组件构成
控制器对象:包含应用的逻辑单元,响应视图对象触发的事件,管理视图对象和模型对象之间的数据流动。(Activity、Fragment、Service)
更新视图层
增加一个Next按钮
更新字符串资源
Next
新增问题字符串
Canberra is the capital of Ausrtalia .
The Pacific Ocean is larger than the Atlanic Ocean
The Suez Canal connects the Red Sea and the Indian Ocean
The source of the Nile River is in Egypt.
The Amazon River is the longer river in the Americas.
Lake Baikal is the world\'s oldest and deepest freshwater lake.
更新控制器层
增加按钮变量及Question对象数组
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,true),
new Question(R.string.question_africa,true),
new Question(R.string.question_americas,true),
new Question(R.string.question_asia,true)
};
使用UpdateQuestion()
封装公共代码
mNextButton =(Button)findViewById(R.id.next_button);
mNextButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
mCurrentIndex =(mCurrentIndex + 1)%mQuestionBank.length;
mIsCheater = false;
//int question = mQuestionBank[mCurrentIndex].getmTextResId();
//mQuestionTextView.setText(question);
updateQuestion();
}
});
mCheatButton = (Button) findViewById(R.id.cheat_button);
mCheatButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Start CheatActicity
//Intent intent=new Intent(QuizActivity.this,CheatActivity.class);
boolean answerIsTrue = mQuestionBank[mCurrentIndex].ismAnswerTrue();
Intent intent = CheatActivity.newIntent(QuizActivity.this,answerIsTrue);
//startActivity(intent);
startActivityForResult(intent,REQUEST_CODE_CHEAT);
}
});
updateQuestion();
}
private void updateQuestion() {
Log.d(TAG,"updating question",new Exception());
int question = mQuestionBank[mCurrentIndex].getmTextResId();
mQuestionTextView.setText(question);
}
增加checkAnswer()
方法——判断用户答案的正确性,修正之前代码的逻辑性错误(认为所有答案都是true)
private void checkAnswer(boolean userPressedTrue) {
boolean answerIsTrue = mQuestionBank[mCurrentIndex].ismAnswerTrue();
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();
}
调用checkAnswer()
方法,在按钮的监听器里
mTrueButton = (Button) findViewById(R.id.true_button);
mTrueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Toast.makeText(QuizActivity.this,
// R.string.correct_toast,
//Toast.LENGTH_SHORT).show();
//Dose nothing yet,but soon!
checkAnswer(true);
}
});
mFalseButton = (Button) findViewById(R.id.false_button);
mFalseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Toast.makeText(QuizActivity.this,
// R.string.incorrect_toast,
// Toast.LENGTH_SHORT).show();
//Does nothing yet, but soon!
checkAnswer(false);
}
});
Acticity的生命周期
activity的状态:不存在、停止、暂停、运行
用户可以与当前运行状态下的activity交互。但是任何时候只有一个activity能与用户进行交互。
activty的生命周期回调函数:onCreate()
、onDestory()
、onStart()
、onStop()
、onResume()
、onPause()
.
通过这几种方法可以在activity的生命周期状态发生关键性转换时完成某些工作。
日志跟踪理解activity生命周期
由于覆盖方法会输出日志,我们可以通过覆盖activity生命周期方法来了解activity的状态变化情况。
输出日志信息
新增一个日志常量
private static final String TAG = "QuizActivity";
为onCreate(Bundle)
方法添加日志输出代码
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
**Log.d(TAG,"onCreate(Bundle) calles");**
setContentView(R.layout.activity_quiz);
...
覆盖更多生命周期方法
...
@Override
protected void onStart() {
super.onStart();
Log.d(TAG,"onStart() called");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG,"onResume() called");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG,"onPause() called");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG,"onStop() called");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG,"onDestory() called");
}
...
创建水平模式布局
1.右键单击
res
目录后选择New
->Android resources directory
,选择layout
资源类型
2.将待选资源特征列表中的Orientation
单击>>按钮将其移动到已选资源特征区域中。
3.选中Screen orentation
中的Landsacpe
选项,目录名为layout-land
。
- Android 视图下的看不到
res/layout-land
目录,需要切换到Project视图下。
第二个Activity
一个activity控制一屏信息,新activity是用来方便用户偷看答案的
- 启动activity:基于intent的通信——intent对象是compoment用来与操作系统通信的一种媒介工具
- activity的数据传递:使用intent extra ,从子activity获取返回结果
具体代码如下:
QuizActivity.java
private static final String KEY_INDEX = "index";
private static final int REQUEST_CODE_CHEAT = 0;
...
mCheatButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Start CheatActicity
//Intent intent=new Intent(QuizActivity.this,CheatActivity.class);
boolean answerIsTrue = mQuestionBank[mCurrentIndex].ismAnswerTrue();
Intent intent = CheatActivity.newIntent(QuizActivity.this,answerIsTrue);
//startActivity(intent);
startActivityForResult(intent,REQUEST_CODE_CHEAT);
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE_CHEAT) {
if (data == null) {
return ;
}
mIsCheater = CheatActivity.wasAnswerShown(data);
}
}
...
CheatActivity.java
private static final String EXTRA_ANSWER_IS_TRUE ="cn.happy.qxy.geoquiz.answer_is_true";
private boolean mAnswerIsTrue;
public static Intent newIntent(Context packageContext,boolean answerIsTrue) {
Intent intent = new Intent(packageContext,CheatActivity.class);
intent.putExtra(EXTRA_ANSWER_IS_TRUE,answerIsTrue);
return intent;
}
public static boolean wasAnswerShown(Intent result) {
return result.getBooleanExtra(EXTRA_ANSWER_IS_TRUE,false);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat);
mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE,false);
mAnswerTexView = (TextView) findViewById(R.id.answer_text_view);
mShowAnswerButton = (Button) findViewById(R.id.show_answer_button);
mShowAnswerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mAnswerIsTrue) {
mAnswerTexView.setText(R.string.true_button);
}else {
mAnswerTexView.setText(R.string.false_button);
}
setAnswerShownResult(true);
}
});
}
private void setAnswerShownResult(boolean isAnswerShown) {
Intent data = new Intent();
data.putExtra(EXTRA_ANSWER_IS_TRUE,isAnswerShown);
setResult(RESULT_OK,data);
}
心得体会
以上就是本次项目一些重要的步骤,及详细的代码展示。麻雀虽小,组脏俱全。
了解到Android Studio 的独有的优势:
- 速度优于Eclipse
- 提示补全更加人性化
- 支持Google Cloud Platform
- 强大的UI编辑器
- 受欢迎的第三方GenyMoton虚拟机
- Android Studio特有的异常调试工具Android Lint