2017-03-04 91 views
2

過去3天,我每天都花費6-8小時搜索,閱讀和執行有關共享首選項的各種示例,但沒有任何成功。我已經走到死衚衕了......一直非常沮喪!我的問題是:使用共享首選項存儲數據

- 目的: 我正在做一個很基本的數學遊戲,在這裏玩家將獲得一個(隨機)方程,有兩個數字乘以海誓山盟。玩家只需按下三個選項按鈕中的一個(其中一個包括正確的答案)就可以給出答案。爲每個正確答案添加分數。

- 問題: 現在,我想包括一個高分的遊戲存儲最高分。如何使用共享首選項或任何其他工作方法來存儲我的數據。

「得分:」(@ + id/textScore)是包含得分(TESTActivity.java)的我的TextView。 「Top Scores」(@ + id/textTopScores)是我的TextView,我想存儲我的高分(HighScoreActivity.java)。

- 應用程序的結構:

My app looks like this: 
(a) MainActivity - main page with a start button leading the player to the Menu (= MenuActivity) 
(b) MenuActivity - here the player have 3 buttons options which includes: 
     Play Button --> leading to the TESTActivity 
     High Score button -->> leading to the HighScoreActivity 
     Help button -->> leading to the HelpActivity 

activity_test.xml

<?xml version="1.0" encoding="utf-8"?> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:id="@+id/activity_test" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:paddingBottom="@dimen/activity_vertical_margin" 
     android:paddingLeft="@dimen/activity_horizontal_margin" 
     android:paddingRight="@dimen/activity_horizontal_margin" 
     tools:context="com.example.android.laboration2.TESTActivity"> 

     <TextView 
      android:id="@+id/textOperator" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignTop="@+id/textPartA" 
      android:layout_centerHorizontal="true" 
      android:text="x" 
      android:textSize="55sp" /> 

     <TextView 
      android:text="=" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/textOperator" 
      android:layout_alignLeft="@+id/textOperator" 
      android:layout_alignStart="@+id/textOperator" 
      android:layout_marginTop="70dp" 
      android:id="@+id/textView" 
      android:textSize="70sp" /> 

     <TextView 
      android:id="@+id/textPartA" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignEnd="@+id/buttonChoice1" 
      android:layout_alignParentTop="true" 
      android:layout_alignRight="@+id/buttonChoice1" 
      android:layout_marginTop="36dp" 
      android:text="2" 
      android:textSize="60sp" /> 

     <TextView 
      android:id="@+id/textPartB" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="2" 
      android:textSize="60sp" 
      android:layout_alignTop="@+id/textOperator" 
      android:layout_alignLeft="@+id/buttonChoice3" 
      android:layout_alignStart="@+id/buttonChoice3" /> 

     <Button 
      android:id="@+id/buttonChoice2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignTop="@+id/buttonChoice1" 
      android:layout_centerHorizontal="true" 
      android:text="4" 
      android:textSize="30sp" /> 

     <Button 
      android:id="@+id/buttonChoice3" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignBottom="@+id/buttonChoice2" 
      android:layout_alignParentEnd="true" 
      android:layout_alignParentRight="true" 
      android:text="6" 
      android:textSize="30sp" /> 

     <Button 
      android:id="@+id/buttonChoice1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentLeft="true" 
      android:layout_alignParentStart="true" 
      android:layout_below="@+id/textView" 
      android:layout_marginTop="70dp" 
      android:text="2" 
      android:textSize="30sp" /> 

     <TextView 
      android:id="@+id/textScore" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Score:" 
      android:textSize="24sp" 
      android:layout_alignParentBottom="true" 
      android:layout_toLeftOf="@+id/buttonChoice2" 
      android:layout_toStartOf="@+id/buttonChoice2" 
      android:layout_marginRight="30dp" 
      android:layout_marginEnd="30dp" 
      android:layout_marginBottom="14dp" /> 

     <TextView 
      android:id="@+id/textLevel" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Level:" 
      android:textSize="24sp" 
      android:layout_alignBaseline="@+id/textScore" 
      android:layout_alignBottom="@+id/textScore" 
      android:layout_alignRight="@+id/textPartB" 
      android:layout_alignEnd="@+id/textPartB" /> 

    </RelativeLayout> 

TESTActivity.java

package com.example.android.laboration2; 
 

 
import android.content.Context; 
 
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; 
 
import android.widget.Toast; 
 
import java.util.Random; 
 

 

 
public class TESTActivity extends AppCompatActivity implements View.OnClickListener { 
 

 

 
    Button buttonObjectChoice1; 
 
    Button buttonObjectChoice2; 
 
    Button buttonObjectChoice3; 
 
    TextView textObjectPartA; 
 
    TextView textObjectPartB; 
 
    TextView textObjectScore; 
 
    TextView textObjectLevel; 
 
    TextView textObjectHighScoresScores; 
 

 
    int correctAnswer; 
 
    int currentScore = 0; 
 
    int currentLevel = 1; 
 

 

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

 

 
     textObjectPartA = (TextView) findViewById(R.id.textPartA); 
 
     textObjectPartB = (TextView) findViewById(R.id.textPartB); 
 
     textObjectHighScoresScores = (TextView) findViewById(R.id.textHighScoresScores); 
 

 
     textObjectScore = (TextView) findViewById(R.id.textScore); 
 
     textObjectLevel = (TextView) findViewById(R.id.textLevel); 
 

 
     buttonObjectChoice1 = (Button) findViewById(R.id.buttonChoice1); 
 
     buttonObjectChoice2 = (Button) findViewById(R.id.buttonChoice2); 
 
     buttonObjectChoice3 = (Button) findViewById(R.id.buttonChoice3); 
 

 
     buttonObjectChoice1.setOnClickListener(this); 
 
     buttonObjectChoice2.setOnClickListener(this); 
 
     buttonObjectChoice3.setOnClickListener(this); 
 

 
     //Storing the score 
 
     String highScore = textObjectHighScoresScores.getText().toString(); 
 
     int newHighScore = currentScore; 
 

 
     SharedPreferences prefs = this.getSharedPreferences("StoringScore", Context.MODE_PRIVATE); 
 
     SharedPreferences.Editor editor = prefs.edit(); 
 
     editor.putInt(highScore, newHighScore); 
 
     editor.apply(); 
 

 

 
     setQuestion(); 
 
    }//onCreate ends here 
 

 

 

 
    @Override 
 
    public void onClick(View view) { 
 
     //Declaring a new int which will be used in all the cases 
 
     int answerGiven = 0; 
 
     switch (view.getId()) { 
 

 
      //Initializes a new int with a value for buttonObjectChoice1,2,3 
 
      case R.id.buttonChoice1: 
 
       answerGiven = Integer.parseInt("" + buttonObjectChoice1.getText()); 
 
       break; 
 

 
      case R.id.buttonChoice2: 
 
       answerGiven = Integer.parseInt("" + buttonObjectChoice2.getText()); 
 
       break; 
 

 
      case R.id.buttonChoice3: 
 
       answerGiven = Integer.parseInt("" + buttonObjectChoice3.getText()); 
 
       break; 
 
     }//switch ends here 
 

 
     updateScoreAndLevel(answerGiven); 
 
     setQuestion(); 
 
     
 
    }//onClick ends here 
 

 

 

 
    void setQuestion() { 
 
     //Generates the parts of the question 
 
     int numberRange = currentLevel * 3; 
 
     Random randInt = new Random(); 
 

 
     int partA = randInt.nextInt(numberRange); 
 
     partA++;//To avoid a zero value 
 

 
     int partB = randInt.nextInt(numberRange); 
 
     partB++;//To avoid a zero value 
 

 
     correctAnswer = partA * partB; 
 
     int wrongAnswer1 = correctAnswer - 2; 
 
     int wrongAnswer2 = correctAnswer + 2; 
 

 
     textObjectPartA.setText("" + partA); 
 
     textObjectPartB.setText("" + partB); 
 

 
     //Gives a number between 0 and 2 for the multi choice buttons 
 
     int buttonLayout = randInt.nextInt(3); 
 
     switch (buttonLayout) { 
 
      case 0: 
 
       buttonObjectChoice1.setText("" + correctAnswer); 
 
       buttonObjectChoice2.setText("" + wrongAnswer1); 
 
       buttonObjectChoice3.setText("" + wrongAnswer2); 
 
       break; 
 

 
      case 1: 
 
       buttonObjectChoice2.setText("" + correctAnswer); 
 
       buttonObjectChoice3.setText("" + wrongAnswer1); 
 
       buttonObjectChoice1.setText("" + wrongAnswer2); 
 
       break; 
 

 
      case 2: 
 
       buttonObjectChoice3.setText("" + correctAnswer); 
 
       buttonObjectChoice1.setText("" + wrongAnswer1); 
 
       buttonObjectChoice2.setText("" + wrongAnswer2); 
 
       break; 
 
       
 
     }//switch ends here 
 
    }//setQuestion ends here 
 

 

 
    //Updates the Score & Level for the player 
 
    void updateScoreAndLevel(int answerGiven){ 
 
     if(isCorrect(answerGiven)){ 
 
      for(int i = 1; i <= currentLevel; i++){ 
 
       currentScore = currentScore + i; 
 
      } 
 
      currentLevel++; 
 
     }else{ 
 
      currentScore = 0; 
 
      currentLevel = 1; 
 
     } 
 
     //Updates the Score & Level TextViews 
 
     textObjectScore.setText("Score: " + currentScore); 
 
     textObjectLevel.setText("Level: " + currentLevel); 
 
    }//updateScoreAndLevel ends here 
 

 

 
    //Sends a toast message to the player - if right = Correct!, if wrong = Wrong! :(. 
 
    boolean isCorrect(int answerGiven){ 
 
     boolean correctTrueOrFalse; 
 
     if(answerGiven == correctAnswer){ 
 
      Toast.makeText(getApplicationContext(), "Correct!", Toast.LENGTH_LONG).show(); 
 
      correctTrueOrFalse=true; 
 
     }else{ 
 
      Toast.makeText(getApplicationContext(), "Wrong! :(", Toast.LENGTH_LONG).show(); 
 
      correctTrueOrFalse=false; 
 
     } 
 
     return correctTrueOrFalse; 
 
    }//isCorrect ends here 
 

 

 

 
}//TESTActivity ends here

activit y_high_score.xml

<?xml version="1.0" encoding="utf-8"?> 
 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 
    xmlns:tools="http://schemas.android.com/tools" 
 
    android:id="@+id/activity_high_score" 
 
    android:layout_width="match_parent" 
 
    android:layout_height="match_parent" 
 
    android:paddingBottom="@dimen/activity_vertical_margin" 
 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
 
    android:paddingRight="@dimen/activity_horizontal_margin" 
 
    android:paddingTop="@dimen/activity_vertical_margin" 
 
    tools:context="com.example.android.laboration2.HighScoreActivity"> 
 

 
    <TextView 
 
     android:text="@string/high_scores" 
 
     android:layout_width="wrap_content" 
 
     android:layout_height="wrap_content" 
 
     android:layout_alignParentTop="true" 
 
     android:layout_centerHorizontal="true" 
 
     android:layout_marginTop="62dp" 
 
     android:id="@+id/textHighScore" 
 
     android:textSize="30sp"/> 
 

 
    <TextView 
 
     android:text="@string/top_scores" 
 
     android:layout_width="wrap_content" 
 
     android:layout_height="wrap_content" 
 
     android:id="@+id/textTopScores" 
 
     android:textSize="16sp" 
 
     android:layout_below="@+id/textHighScore" 
 
     android:layout_centerHorizontal="true" 
 
     android:layout_marginTop="86dp" /> 
 

 
</RelativeLayout>

HighScoreActivity.java

package com.example.android.laboration2; 
 

 
import android.content.Context; 
 
import android.content.SharedPreferences; 
 
import android.support.v7.app.AppCompatActivity; 
 
import android.os.Bundle; 
 

 
public class HighScoreActivity extends AppCompatActivity { 
 

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

 
     //getting preferences 
 
     SharedPreferences prefs = this.getSharedPreferences("StoringScore", Context.MODE_PRIVATE); 
 
     int newHighscore = prefs.getInt(highScore, null); //0 is the default value 
 
     
 
    }//onCreate ends here 
 

 

 
}//HighScoreActivity ends here

+0

是您的線textObjectHighScoresScores =(TextView的)findViewById(R.id.textHighScoresScores);正確?我無法在任何地方找到R.id.textHighScoresScores,你的意思是R.id.textHighScore? – Luke

+0

@Luke:我在那裏犯了一個錯誤(典型的!)。希望儘可能使事情變得清晰,並更改ID和任何可能的名稱以方便閱讀。顯然我錯過了我已經有一個TextView使用相同的ID(在activity_high_score.xml中)。因此,**「activity_high_score.xml」**中的第二個TextView帶有字符串文本:** android:text =「@ string/top_scores」**是我也在引用的那個,並且之前被命名爲textHighScoresScores,應該被稱爲** textTopScores **(而不是現在的textHighScore)。 –

回答

4
//I hope this will help you 
public class TESTActivity extends AppCompatActivity implements View.OnClickListener{ 

Button buttonObjectChoice1; 
Button buttonObjectChoice2; 
Button buttonObjectChoice3; 
TextView textObjectPartA; 
TextView textObjectPartB; 
TextView textObjectScore; 
TextView textObjectLevel; 
TextView textObjectHighScoresScores; 

int correctAnswer; 
int currentScore = 0; 
int currentLevel = 1; 


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


    textObjectPartA = (TextView) findViewById(R.id.textPartA); 
    textObjectPartB = (TextView) findViewById(R.id.textPartB); 
    //textObjectHighScoresScores = (TextView) findViewById(R.id.textScore); 

    textObjectScore = (TextView) findViewById(R.id.textScore); 
    textObjectLevel = (TextView) findViewById(R.id.textLevel); 

    buttonObjectChoice1 = (Button) findViewById(R.id.buttonChoice1); 
    buttonObjectChoice2 = (Button) findViewById(R.id.buttonChoice2); 
    buttonObjectChoice3 = (Button) findViewById(R.id.buttonChoice3); 

    buttonObjectChoice1.setOnClickListener(this); 
    buttonObjectChoice2.setOnClickListener(this); 
    buttonObjectChoice3.setOnClickListener(this); 

    setQuestion(); 
}//onCreate ends here 



@Override 
public void onClick(View view) { 
    //Declaring a new int which will be used in all the cases 
    int answerGiven = 0; 
    switch (view.getId()) { 

     //Initializes a new int with a value for buttonObjectChoice1,2,3 
     case R.id.buttonChoice1: 
      answerGiven = Integer.parseInt("" + buttonObjectChoice1.getText()); 
      break; 

     case R.id.buttonChoice2: 
      answerGiven = Integer.parseInt("" + buttonObjectChoice2.getText()); 
      break; 

     case R.id.buttonChoice3: 
      answerGiven = Integer.parseInt("" + buttonObjectChoice3.getText()); 
      break; 
    }//switch ends here 

    updateScoreAndLevel(answerGiven); 
    setQuestion(); 

}//onClick ends here 



void setQuestion() { 
    //Generates the parts of the question 
    int numberRange = currentLevel * 3; 
    Random randInt = new Random(); 

    int partA = randInt.nextInt(numberRange); 
    partA++;//To avoid a zero value 

    int partB = randInt.nextInt(numberRange); 
    partB++;//To avoid a zero value 

    correctAnswer = partA * partB; 
    int wrongAnswer1 = correctAnswer - 2; 
    int wrongAnswer2 = correctAnswer + 2; 

    textObjectPartA.setText("" + partA); 
    textObjectPartB.setText("" + partB); 

    //Gives a number between 0 and 2 for the multi choice buttons 
    int buttonLayout = randInt.nextInt(3); 
    switch (buttonLayout) { 
     case 0: 
      buttonObjectChoice1.setText("" + correctAnswer); 
      buttonObjectChoice2.setText("" + wrongAnswer1); 
      buttonObjectChoice3.setText("" + wrongAnswer2); 
      break; 

     case 1: 
      buttonObjectChoice2.setText("" + correctAnswer); 
      buttonObjectChoice3.setText("" + wrongAnswer1); 
      buttonObjectChoice1.setText("" + wrongAnswer2); 
      break; 

     case 2: 
      buttonObjectChoice3.setText("" + correctAnswer); 
      buttonObjectChoice1.setText("" + wrongAnswer1); 
      buttonObjectChoice2.setText("" + wrongAnswer2); 
      break; 

    }//switch ends here 
}//setQuestion ends here 


//Updates the Score & Level for the player 
void updateScoreAndLevel(int answerGiven){ 
    if(isCorrect(answerGiven)){ 
     for(int i = 1; i <= currentLevel; i++){ 
      currentScore = currentScore + i; 
     } 
     currentLevel++; 
    }else{ 
     currentScore = 0; 
     currentLevel = 1; 
    } 
    //Updates the Score & Level TextViews 
    textObjectScore.setText("Score: " + currentScore); 
    textObjectLevel.setText("Level: " + currentLevel); 

    SharedPreferences sharedPreferences = getSharedPreferences("sharedPreferences",MODE_PRIVATE); 
    SharedPreferences.Editor editor = sharedPreferences.edit(); 
    int storedHighScore = sharedPreferences.getInt("highScore",0); 
    if (currentScore>storedHighScore){ 
     editor.putInt("highScore",currentScore); 
     editor.commit(); 
    } 
}//updateScoreAndLevel ends here 


//Sends a toast message to the player - if right = Correct!, if wrong = Wrong! :(. 
boolean isCorrect(int answerGiven){ 
    boolean correctTrueOrFalse; 
    if(answerGiven == correctAnswer){ 

     Toast.makeText(getApplicationContext(), "Correct!", Toast.LENGTH_LONG).show(); 
     correctTrueOrFalse=true; 
    }else{ 
     Toast.makeText(getApplicationContext(), "Wrong! :(", Toast.LENGTH_LONG).show(); 
     correctTrueOrFalse=false; 
     Intent intent = new Intent(this,HighScoreActivity.class); 
     startActivity(intent); 
    } 
    return correctTrueOrFalse; 
}//isCorrect ends here 



}//TESTActivity ends here 

// HighScoreActivity

public class HighScoreActivity extends AppCompatActivity { 

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

    SharedPreferences sharedPreferences = getSharedPreferences("sharedPreferences",MODE_PRIVATE); 
    int storedHighScore = sharedPreferences.getInt("highScore",0); 

    highScoreTextView=(TextView)findViewById(R.id.textHighScore); 
    highScoreTextView.setText(""+storedHighScore); 


    } 
} 
+0

Shehxhad:不起作用。每次我去TESTActivity播放應用程序時,都會每次崩潰:/。 –

+0

你想在應用程序崩潰時共享Android監視器的屏幕截圖 –

+0

我交換了上面的內容:textObjectHighScoresScores =(TextView)findViewById(R.id.textHighScoresScores);與** textObjectScore =(TextView)findViewById(R.id.textScore); **現在應用程序不會崩潰。也許你以前被誤解了。 ** R.id.textScore **是我的實際分數被添加的地方。 ** R.id.textObejctHighScoresScore **是我希望高分存儲和顯示的地方。 –

4

其實主要的問題是在這裏。

//Storing the score 
    String highScore = textObjectHighScoresScores.getText().toString(); 
    int newHighScore = currentScore; 

    SharedPreferences prefs = this.getSharedPreferences("StoringScore", Context.MODE_PRIVATE); 
    SharedPreferences.Editor editor = prefs.edit(); 
    editor.putInt(highScore, newHighScore); 
    editor.apply(); 

editor.putInt(key,value)您正在使用高分的關鍵,這將是變化的,但共享偏好可以通過使用存儲的時間相同的鍵搞定。

,可以儲存這樣

SharedPreferences prefs = this.getSharedPreferences("StoringScore", Context.MODE_PRIVATE); 
SharedPreferences.Editor editor = prefs.edit(); 
editor.putString("myKey", score); 
editor.apply(); 

獲取分數副>

SharedPreferences prefs = this.getSharedPreferences("StoringScore", Context.MODE_PRIVATE); 
int newHighscore = prefs.getInt("myKey", 0); 

主要的一點是KEY應該是相同的

+0

抱歉不回覆阿布舍克。如下所示,我複製/粘貼上面寫的相同代碼,但沒有成功。任何提示我做錯了什麼?因爲我之前在其他主題中看過您的帖子,並且之前也嘗試過。就像我沒有得到它的工作(可能是因爲我是新的和困惑)。 –

+0

@FisnikB。如果你是新的,那麼創建一個簡單的程序來測試共享偏好,然後執行到你當前的程序..我的觀點是。你的問題是這條線......'editor.putInt(highScore,newHightScore)'。而不是所有你需要做的就是編輯器,putInt(「high_score」,newhighscore)和獲得結果'pref.getInt(「high_score」,0)'。第一個參數是用來獲得空間值的關鍵。在存儲和獲得價值的時候,密鑰應該是相同的。只需使用我已經使用的相同字符串 –

+0

謝謝大家幫助Abishek。現在使用Sid Shehxad發給我的完整代碼解決問題。這對我來說容易得多,因爲現在我可以看到它應該如何執行(我認爲我的主要問題在之前)。 –