GeoQuiz項(xiàng)目總結(jié)


  • 用戶界面設(shè)計(jì)
  • Android 與MVC模式
  • Activity生命周期
  • 第二個(gè)Activity
  • 心得體會(huì)

用戶界面設(shè)計(jì)

用戶界面是由組件構(gòu)造而成的,它可以顯示文字或圖像,與用戶交互,甚至布置屏幕上的其他組件。默認(rèn)的activity布局是由RelativeLayoutTextView兩個(gè)組件構(gòu)成。且一個(gè)activity只能有一個(gè)LinearLayout根元素,作為根元素,必須指定Android XML的資源文件的命名空間(namespace)屬性。


Android 與MVC模式

Android 應(yīng)用是基于MVC模式開發(fā)的,模型——視圖——控制器的架構(gòu)模式。

模型對(duì)象:存儲(chǔ)應(yīng)用的數(shù)據(jù)和業(yè)務(wù)邏輯
視圖對(duì)象:用戶界面,由各類組件構(gòu)成
控制器對(duì)象:包含應(yīng)用的邏輯單元,響應(yīng)視圖對(duì)象觸發(fā)的事件,管理視圖對(duì)象和模型對(duì)象之間的數(shù)據(jù)流動(dòng)。(Activity、Fragment、Service)

更新視圖層

增加一個(gè)Next按鈕

<Button
        android:id="@+id/next_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawablePadding="4dp"
        android:text="@string/next_button" />

更新字符串資源

<string name="next_button">Next</string>

新增問題字符串

    <string name="question_australia">Canberra is the capital of Ausrtalia .</string>
    <string name="question_oceans">The Pacific Ocean is larger than the Atlanic Ocean</string>
    <string name="question_mideast">The Suez Canal connects the Red Sea and the Indian Ocean</string>
    <string name="question_africa">The source of the Nile River is in Egypt.</string>
    <string name="question_americas">The Amazon River is the longer river in the Americas.</string>
    <string name="question_asia">Lake Baikal is the world\'s oldest and deepest freshwater lake.</string>

更新控制器層

增加按鈕變量及Question對(duì)象數(shù)組

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()方法——判斷用戶答案的正確性,修正之前代碼的邏輯性錯(cuò)誤(認(rèn)為所有答案都是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();
    }

調(diào)用checkAnswer()方法,在按鈕的監(jiān)聽器里

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的狀態(tài):不存在、停止、暫停、運(yùn)行

用戶可以與當(dāng)前運(yùn)行狀態(tài)下的activity交互。但是任何時(shí)候只有一個(gè)activity能與用戶進(jìn)行交互。

activty的生命周期回調(diào)函數(shù):onCreate()onDestory()onStart()onStop()onResume()onPause().

通過這幾種方法可以在activity的生命周期狀態(tài)發(fā)生關(guān)鍵性轉(zhuǎn)換時(shí)完成某些工作。

日志跟蹤理解activity生命周期

由于覆蓋方法會(huì)輸出日志,我們可以通過覆蓋activity生命周期方法來了解activity的狀態(tài)變化情況。

輸出日志信息

新增一個(gè)日志常量

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");
    }
    ...

創(chuàng)建水平模式布局

1.右鍵單擊res目錄后選擇New->Android resources directory ,選擇layout資源類型
2.將待選資源特征列表中的Orientation單擊>>按鈕將其移動(dòng)到已選資源特征區(qū)域中。
3.選中Screen orentation中的Landsacpe選項(xiàng),目錄名為layout-land

  • Android 視圖下的看不到res/layout-land目錄,需要切換到Project視圖下。

第二個(gè)Activity

一個(gè)activity控制一屏信息,新activity是用來方便用戶偷看答案的

  • 啟動(dòng)activity:基于intent的通信——intent對(duì)象是compoment用來與操作系統(tǒng)通信的一種媒介工具
  • activity的數(shù)據(jù)傳遞:使用intent extra ,從子activity獲取返回結(jié)果

具體代碼如下:
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);
    }

心得體會(huì)

以上就是本次項(xiàng)目一些重要的步驟,及詳細(xì)的代碼展示。麻雀雖小,組臟俱全。
了解到Android Studio 的獨(dú)有的優(yōu)勢(shì):

  • 速度優(yōu)于Eclipse
  • 提示補(bǔ)全更加人性化
  • 支持Google Cloud Platform
  • 強(qiáng)大的UI編輯器
  • 受歡迎的第三方GenyMoton虛擬機(jī)
  • Android Studio特有的異常調(diào)試工具Android Lint
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,033評(píng)論 25 708
  • 1.什么是Activity?問的不太多,說點(diǎn)有深度的 四大組件之一,一般的,一個(gè)用戶交互界面對(duì)應(yīng)一個(gè)activit...
    JoonyLee閱讀 5,755評(píng)論 2 51
  • 這個(gè)時(shí)代,選擇太多,變化太快,每一次站在分岔路口,都是一次大考驗(yàn),糾結(jié),郁悶,迷茫,都會(huì)無端地浪費(fèi)大把光陰,而得不...
    丁少小蕾M(fèi)elody閱讀 944評(píng)論 0 7
  • 前兩天聽同學(xué)提起這部電影,是吳天明導(dǎo)演的電影,不過票房慘敗,美團(tuán)貓眼上的評(píng)分都很低,不過還是想去欣賞一下,就像去欣...
    樂君陶陶閱讀 1,333評(píng)論 0 1
  • 有些感情像爛了的水果 水果水分多,營(yíng)養(yǎng)豐富。 正如我們認(rèn)識(shí)的六年里,我吃過剝好皮的橙子覺得甜,我吃過削下來的蘋果皮...
    湯芍兒閱讀 198評(píng)論 0 0