Home
2018年3月22日 星期四

[程式] Android Studio : Simple High Score Screen

Android Studio : Simple High Score Screen

上一篇 [程式] Android Studio : Simple Quiz Game 有說到,要增加一個排行榜(leaderboard)的功能,剛好也有範例,就直接來實作吧!


範例網址:

https://www.youtube.com/watch?v=_cV7cgQFDo0

相關資訊圖片:

Simple High Screen Screen View1畫面
Simple High Screen Screen View1 (activity_main.xml)畫面

Simple High Screen Screen View2畫面
Simple High Screen Screen View2 (activity_best.xml)畫面

初始畫面
初始畫面

High Score Screen畫面
High Score Screen畫面

Source Code:

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns: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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="20dp"
    tools:context="tw.idv.wenyen.simplehighscorescreen.MainActivity">


    <Button
        android:id="@+id/b_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:text="1" />

    <Button
        android:id="@+id/b_end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:text="END" />

    <TextView
        android:id="@+id/tv_score"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textSize="24dp"
        android:text="SCORE: 0" />
</RelativeLayout>

activity_best.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="20dp">

    <TextView
        android:id="@+id/tv_score"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="" />
</LinearLayout>


MainActivity.java
package tw.idv.wenyen.simplehighscorescreen;

import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView tv_score;
    Button b_add, b_end;

    int score = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv_score = findViewById(R.id.tv_score);
        b_add = findViewById(R.id.b_add);
        b_end = findViewById(R.id.b_end);

        tv_score.setText("SCORE: " + score);

        b_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                score++;
                tv_score.setText("SCORE: " + score);
            }
        });

        b_end.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //save score in SharedPreferences
                SharedPreferences preferences = getSharedPreferences("PREFS", 0);
                SharedPreferences.Editor editor = preferences.edit();
                editor.putInt("lastScore", score);
                editor.apply();

                //go to BestActivity
                Intent intent = new Intent(getApplicationContext(), BestActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
}

BestActivity.java
package tw.idv.wenyen.simplehighscorescreen;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

/**
 * Created by kingbow on 2018/3/22.
 */

public class BestActivity extends AppCompatActivity {

    TextView tv_score;

    int lastScore;
    int best1, best2, best3;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_best);

        tv_score = findViewById(R.id.tv_score);

        // load old score
        SharedPreferences preferences = getSharedPreferences("PREFS", 0);
        lastScore = preferences.getInt("lastScore", 0);
        best1 = preferences.getInt("best1", 0);
        best2 = preferences.getInt("best2", 0);
        best3 = preferences.getInt("best3", 0);

        // replace if there is a high score
        // ex : init status
        // best1(5), best2(3), best3(1), lastScore(6)
        if (lastScore > best3) {
            best3 = lastScore;
            SharedPreferences.Editor editor = preferences.edit();
            editor.putInt("best3", best3);
            editor.apply();
        }
        // best1(5), best2(3), best3(6), lastScore(6)
        if (lastScore > best2) {
            int temp = best2;
            best2 = lastScore;
            best3 = temp;
            SharedPreferences.Editor editor = preferences.edit();
            editor.putInt("best3", best3);
            editor.putInt("best2", best2);
            editor.apply();
        }
        // best1(5), best2(6), best3(3), lastScore(6)
        if (lastScore > best1) {
            int temp = best1;
            best1 = lastScore;
            best2 = temp;
            SharedPreferences.Editor editor = preferences.edit();
            editor.putInt("best2", best2);
            editor.putInt("best1", best1);
            editor.apply();
        }
        // final status
        // best1(6), best2(5), best3(3), lastScore(6)

        // display score
        tv_score.setText("LAST SCORE: " + lastScore + "\n" +
                "BEST1: " + best1 + "\n" +
                "BEST2: " + best2 + "\n" +
                "BEST3: " + best3);

    }

    @Override
    public void onBackPressed() {
        // go to MainActivity
        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
        startActivity(intent);
        finish();
    }
}

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="tw.idv.wenyen.simplehighscorescreen">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--新增activity-->
        <activity android:name=".BestActivity" />
    </application>

</manifest>

實作心得:

這個範例用到 Intent 與 SharedPreferences ,Intent 用於Activity的交換,除非是前面幾個簡單的範例遊戲,否則幾乎都會用到,所以要花些時間學習,另外 SharedPreferences 用於儲存、新增、刪除等資料處理,因此製作排行榜非常好用。
雖然使用到LinearLayout,不過只用的其中的一個欄位,將分數與前三名塞入,真的有點太簡單了,下次將資料塞入ListView,做個比較完整的排行榜吧!
在第一次安裝APP時,出現 INSTALL_FAILED_INSUFFICIENT_STORAGE 的錯誤訊息,上網查詢的答案是空間已滿,可是查詢手機內部空間,卻還有足夠的空間,原本以為是手機的問題,要改用另外一台筆記型電腦的AVD,結果發現是BestActivity.java的其中一行lastScore打錯成PREFS,改正後就可以成功安裝,所以說一種錯誤訊息所顯示的可能不只是一種錯誤,
        lastScore = preferences.getInt("PREFS", 0);
成功安裝後,再改回 PREFS ,APP卻能夠成功安裝,這個錯誤真有趣,有機會再找時間研究。

參考資料:


補充說明:

2018/03/23 忘記Activity的交換,要在AndroidManifest.xml新增權限的部分寫上來,還好有想到。

0 意見:

張貼留言