Enhanced theme system with immediate UI updates, improved progression speed, and added visual/haptic feedback for theme selection

This commit is contained in:
cmclark00 2025-03-28 09:11:59 -04:00
parent ae5ad1ed03
commit 809ae33e5e
8 changed files with 316 additions and 46 deletions

View file

@ -5,39 +5,46 @@ import android.os.Bundle
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import android.view.View
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.mintris.databinding.HighScoreEntryBinding
import com.mintris.model.HighScore import com.mintris.model.HighScore
import com.mintris.model.HighScoreManager import com.mintris.model.HighScoreManager
import com.mintris.model.PlayerProgressionManager
import android.graphics.Color
class HighScoreEntryActivity : AppCompatActivity() { class HighScoreEntryActivity : AppCompatActivity() {
private lateinit var binding: HighScoreEntryBinding
private lateinit var highScoreManager: HighScoreManager private lateinit var highScoreManager: HighScoreManager
private lateinit var nameInput: EditText private lateinit var progressionManager: PlayerProgressionManager
private lateinit var scoreText: TextView private var currentTheme = PlayerProgressionManager.THEME_CLASSIC
private lateinit var saveButton: Button private var score: Int = 0
// Track if we already saved to prevent double-saving // Track if we already saved to prevent double-saving
private var hasSaved = false private var hasSaved = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.high_score_entry) binding = HighScoreEntryBinding.inflate(layoutInflater)
setContentView(binding.root)
highScoreManager = HighScoreManager(this) highScoreManager = HighScoreManager(this)
nameInput = findViewById(R.id.nameInput) progressionManager = PlayerProgressionManager(this)
scoreText = findViewById(R.id.scoreText)
saveButton = findViewById(R.id.saveButton)
val score = intent.getIntExtra("score", 0) // Load and apply theme
val level = intent.getIntExtra("level", 1) currentTheme = loadThemePreference()
scoreText.text = getString(R.string.score) + ": $score" applyTheme(currentTheme)
saveButton.setOnClickListener { score = intent.getIntExtra("score", 0)
binding.scoreText.text = "Score: $score"
binding.saveButton.setOnClickListener {
// Only allow saving once // Only allow saving once
if (!hasSaved) { if (!hasSaved) {
val name = nameInput.text.toString().trim() val name = binding.nameInput.text.toString().trim()
if (name.isNotEmpty()) { if (name.isNotEmpty()) {
hasSaved = true hasSaved = true
val highScore = HighScore(name, score, level) val highScore = HighScore(name, score, 1)
highScoreManager.addHighScore(highScore) highScoreManager.addHighScore(highScore)
// Set result and finish // Set result and finish
@ -50,10 +57,49 @@ class HighScoreEntryActivity : AppCompatActivity() {
// Prevent accidental back button press from causing issues // Prevent accidental back button press from causing issues
override fun onBackPressed() { override fun onBackPressed() {
super.onBackPressed()
// If they haven't saved yet, consider it a cancel // If they haven't saved yet, consider it a cancel
if (!hasSaved) { if (!hasSaved) {
setResult(Activity.RESULT_CANCELED) setResult(Activity.RESULT_CANCELED)
} }
finish() finish()
} }
private fun loadThemePreference(): String {
val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE)
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
}
private fun applyTheme(themeId: String) {
// Set background color
val backgroundColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832")
PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10")
else -> Color.BLACK
}
binding.root.setBackgroundColor(backgroundColor)
// Set text color
val textColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.WHITE
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#FF00FF")
PlayerProgressionManager.THEME_MONOCHROME -> Color.LTGRAY
PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#FF5A5F")
PlayerProgressionManager.THEME_MINIMALIST -> Color.BLACK
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#66FCF1")
else -> Color.WHITE
}
// Apply text color to score and input
binding.scoreText.setTextColor(textColor)
binding.nameInput.setTextColor(textColor)
binding.nameInput.setHintTextColor(Color.argb(128, Color.red(textColor), Color.green(textColor), Color.blue(textColor)))
// Apply theme to submit button
binding.saveButton.setTextColor(textColor)
}
} }

View file

@ -2,44 +2,116 @@ package com.mintris
import android.os.Bundle import android.os.Bundle
import android.widget.Button import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.mintris.databinding.HighScoresBinding
import com.mintris.model.HighScoreAdapter import com.mintris.model.HighScoreAdapter
import com.mintris.model.HighScoreManager import com.mintris.model.HighScoreManager
import com.mintris.model.PlayerProgressionManager
import android.graphics.Color
import android.util.Log
class HighScoresActivity : AppCompatActivity() { class HighScoresActivity : AppCompatActivity() {
private lateinit var binding: HighScoresBinding
private lateinit var highScoreManager: HighScoreManager private lateinit var highScoreManager: HighScoreManager
private lateinit var highScoreAdapter: HighScoreAdapter private lateinit var highScoreAdapter: HighScoreAdapter
private lateinit var highScoresList: RecyclerView private lateinit var progressionManager: PlayerProgressionManager
private lateinit var backButton: Button private var currentTheme = PlayerProgressionManager.THEME_CLASSIC
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.high_scores)
highScoreManager = HighScoreManager(this) try {
highScoresList = findViewById(R.id.highScoresList) binding = HighScoresBinding.inflate(layoutInflater)
backButton = findViewById(R.id.backButton) setContentView(binding.root)
highScoreAdapter = HighScoreAdapter() highScoreManager = HighScoreManager(this)
highScoresList.layoutManager = LinearLayoutManager(this) progressionManager = PlayerProgressionManager(this)
highScoresList.adapter = highScoreAdapter
updateHighScores() // Load and apply theme
currentTheme = loadThemePreference()
backButton.setOnClickListener { // Initialize adapter before applying theme
highScoreAdapter = HighScoreAdapter()
// Set up RecyclerView
binding.highScoresList.layoutManager = LinearLayoutManager(this)
binding.highScoresList.adapter = highScoreAdapter
// Now apply theme to UI
applyTheme(currentTheme)
// Load high scores
updateHighScores()
// Set up back button
binding.backButton.setOnClickListener {
finish()
}
} catch (e: Exception) {
Log.e("HighScoresActivity", "Error in onCreate", e)
// Show an error message if necessary, or finish gracefully
finish() finish()
} }
} }
private fun loadThemePreference(): String {
val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE)
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
}
private fun applyTheme(themeId: String) {
try {
// Set background color
val backgroundColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832")
PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10")
else -> Color.BLACK
}
binding.root.setBackgroundColor(backgroundColor)
// Set text color
val textColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.WHITE
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#FF00FF")
PlayerProgressionManager.THEME_MONOCHROME -> Color.LTGRAY
PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#FF5A5F")
PlayerProgressionManager.THEME_MINIMALIST -> Color.BLACK
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#66FCF1")
else -> Color.WHITE
}
// Apply theme to back button
binding.backButton.setTextColor(textColor)
// Update adapter theme
highScoreAdapter.applyTheme(themeId)
} catch (e: Exception) {
Log.e("HighScoresActivity", "Error applying theme: $themeId", e)
}
}
private fun updateHighScores() { private fun updateHighScores() {
val scores = highScoreManager.getHighScores() try {
highScoreAdapter.updateHighScores(scores) val scores = highScoreManager.getHighScores()
highScoreAdapter.updateHighScores(scores)
} catch (e: Exception) {
Log.e("HighScoresActivity", "Error updating high scores", e)
}
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
updateHighScores() try {
updateHighScores()
} catch (e: Exception) {
Log.e("HighScoresActivity", "Error in onResume", e)
}
} }
} }

View file

@ -102,7 +102,16 @@ class MainActivity : AppCompatActivity() {
// Set up theme selector // Set up theme selector
val themeSelector = binding.themeSelector val themeSelector = binding.themeSelector
themeSelector.onThemeSelected = { themeId -> themeSelector.onThemeSelected = { themeId ->
// Apply the new theme
applyTheme(themeId) applyTheme(themeId)
// Provide haptic feedback as a cue that the theme changed
gameHaptics.vibrateForPieceLock()
// Refresh the pause menu to immediately show theme changes
if (binding.pauseContainer.visibility == View.VISIBLE) {
showPauseMenu()
}
} }
// Set up title screen // Set up title screen
@ -381,6 +390,38 @@ class MainActivity : AppCompatActivity() {
binding.pauseLevelBadge.setLevel(progressionManager.getPlayerLevel()) binding.pauseLevelBadge.setLevel(progressionManager.getPlayerLevel())
binding.pauseLevelBadge.setThemeColor(getThemeColor(currentTheme)) binding.pauseLevelBadge.setThemeColor(getThemeColor(currentTheme))
// Get theme color
val textColor = getThemeColor(currentTheme)
// Apply theme color to pause container background
val backgroundColor = when (currentTheme) {
PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832")
PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10")
else -> Color.BLACK
}
binding.pauseContainer.setBackgroundColor(backgroundColor)
// Apply theme colors to buttons
binding.pauseStartButton.setTextColor(textColor)
binding.pauseRestartButton.setTextColor(textColor)
binding.resumeButton.setTextColor(textColor)
binding.highScoresButton.setTextColor(textColor)
binding.statsButton.setTextColor(textColor)
binding.pauseLevelText.setTextColor(textColor)
binding.pauseLevelUpButton.setTextColor(textColor)
binding.pauseLevelDownButton.setTextColor(textColor)
binding.settingsButton.setTextColor(textColor)
binding.musicToggle.setColorFilter(textColor)
// Apply theme colors to text elements
binding.settingsTitle.setTextColor(textColor)
binding.selectLevelText.setTextColor(textColor)
binding.musicText.setTextColor(textColor)
// Update theme selector // Update theme selector
updateThemeSelector() updateThemeSelector()
} }
@ -567,6 +608,10 @@ class MainActivity : AppCompatActivity() {
progressionScreen.applyTheme(themeId) progressionScreen.applyTheme(themeId)
} }
// Apply theme color to the stats button
val textColor = getThemeColor(currentTheme)
binding.statsButton.setTextColor(textColor)
// Update the game view to apply theme // Update the game view to apply theme
gameView.invalidate() gameView.invalidate()
} }

View file

@ -7,12 +7,16 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.mintris.databinding.ActivityStatsBinding import com.mintris.databinding.ActivityStatsBinding
import com.mintris.model.StatsManager import com.mintris.model.StatsManager
import com.mintris.model.PlayerProgressionManager
import android.graphics.Color
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
class StatsActivity : AppCompatActivity() { class StatsActivity : AppCompatActivity() {
private lateinit var binding: ActivityStatsBinding private lateinit var binding: ActivityStatsBinding
private lateinit var statsManager: StatsManager private lateinit var statsManager: StatsManager
private lateinit var progressionManager: PlayerProgressionManager
private var currentTheme = PlayerProgressionManager.THEME_CLASSIC
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -20,6 +24,11 @@ class StatsActivity : AppCompatActivity() {
setContentView(binding.root) setContentView(binding.root)
statsManager = StatsManager(this) statsManager = StatsManager(this)
progressionManager = PlayerProgressionManager(this)
// Load and apply theme
currentTheme = loadThemePreference()
applyTheme(currentTheme)
// Set up back button // Set up back button
binding.backButton.setOnClickListener { binding.backButton.setOnClickListener {
@ -34,6 +43,54 @@ class StatsActivity : AppCompatActivity() {
updateStats() updateStats()
} }
private fun loadThemePreference(): String {
val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE)
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
}
private fun applyTheme(themeId: String) {
// Set background color
val backgroundColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221")
PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A")
PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832")
PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10")
else -> Color.BLACK
}
binding.root.setBackgroundColor(backgroundColor)
// Set text color
val textColor = when (themeId) {
PlayerProgressionManager.THEME_CLASSIC -> Color.WHITE
PlayerProgressionManager.THEME_NEON -> Color.parseColor("#FF00FF")
PlayerProgressionManager.THEME_MONOCHROME -> Color.LTGRAY
PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#FF5A5F")
PlayerProgressionManager.THEME_MINIMALIST -> Color.BLACK
PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#66FCF1")
else -> Color.WHITE
}
// Apply text color to all TextViews
binding.totalGamesText.setTextColor(textColor)
binding.totalScoreText.setTextColor(textColor)
binding.totalLinesText.setTextColor(textColor)
binding.totalPiecesText.setTextColor(textColor)
binding.totalTimeText.setTextColor(textColor)
binding.totalSinglesText.setTextColor(textColor)
binding.totalDoublesText.setTextColor(textColor)
binding.totalTriplesText.setTextColor(textColor)
binding.totalTetrisesText.setTextColor(textColor)
binding.maxLevelText.setTextColor(textColor)
binding.maxScoreText.setTextColor(textColor)
binding.maxLinesText.setTextColor(textColor)
// Apply theme to buttons
binding.backButton.setTextColor(textColor)
binding.resetStatsButton.setTextColor(textColor)
}
private fun showResetConfirmationDialog() { private fun showResetConfirmationDialog() {
AlertDialog.Builder(this) AlertDialog.Builder(this)
.setTitle("Reset Stats") .setTitle("Reset Stats")

View file

@ -1,5 +1,6 @@
package com.mintris.model package com.mintris.model
import android.graphics.Color
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -9,6 +10,8 @@ import com.mintris.R
class HighScoreAdapter : RecyclerView.Adapter<HighScoreAdapter.HighScoreViewHolder>() { class HighScoreAdapter : RecyclerView.Adapter<HighScoreAdapter.HighScoreViewHolder>() {
private var highScores: List<HighScore> = emptyList() private var highScores: List<HighScore> = emptyList()
private var currentTheme = "theme_classic" // Default theme
private var textColor = Color.WHITE // Default text color
fun updateHighScores(newHighScores: List<HighScore>) { fun updateHighScores(newHighScores: List<HighScore>) {
highScores = newHighScores highScores = newHighScores
@ -24,14 +27,19 @@ class HighScoreAdapter : RecyclerView.Adapter<HighScoreAdapter.HighScoreViewHold
override fun onBindViewHolder(holder: HighScoreViewHolder, position: Int) { override fun onBindViewHolder(holder: HighScoreViewHolder, position: Int) {
val highScore = highScores[position] val highScore = highScores[position]
holder.bind(highScore, position + 1) holder.bind(highScore, position + 1)
// Apply current text color to elements
holder.rankText.setTextColor(textColor)
holder.nameText.setTextColor(textColor)
holder.scoreText.setTextColor(textColor)
} }
override fun getItemCount(): Int = highScores.size override fun getItemCount(): Int = highScores.size
class HighScoreViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { class HighScoreViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val rankText: TextView = itemView.findViewById(R.id.rankText) val rankText: TextView = itemView.findViewById(R.id.rankText)
private val nameText: TextView = itemView.findViewById(R.id.nameText) val nameText: TextView = itemView.findViewById(R.id.nameText)
private val scoreText: TextView = itemView.findViewById(R.id.scoreText) val scoreText: TextView = itemView.findViewById(R.id.scoreText)
fun bind(highScore: HighScore, rank: Int) { fun bind(highScore: HighScore, rank: Int) {
rankText.text = "#$rank" rankText.text = "#$rank"
@ -39,4 +47,21 @@ class HighScoreAdapter : RecyclerView.Adapter<HighScoreAdapter.HighScoreViewHold
scoreText.text = highScore.score.toString() scoreText.text = highScore.score.toString()
} }
} }
fun applyTheme(themeId: String) {
currentTheme = themeId
// Update text color based on theme
textColor = when (themeId) {
"theme_classic" -> Color.WHITE
"theme_neon" -> Color.parseColor("#FF00FF")
"theme_monochrome" -> Color.LTGRAY
"theme_retro" -> Color.parseColor("#FF5A5F")
"theme_minimalist" -> Color.BLACK
"theme_galaxy" -> Color.parseColor("#66FCF1")
else -> Color.WHITE
}
notifyDataSetChanged()
}
} }

View file

@ -286,15 +286,15 @@ class PlayerProgressionManager(context: Context) {
private const val KEY_UNLOCKED_BADGES = "unlocked_badges" private const val KEY_UNLOCKED_BADGES = "unlocked_badges"
// XP curve parameters // XP curve parameters
private const val BASE_XP = 5000.0 // Base XP for level 1 (increased from 2500) private const val BASE_XP = 4000.0 // Base XP for level 1 (reduced from 5000)
private const val XP_CURVE_FACTOR = 2.2 // Exponential factor for XP curve (increased from 2.0) private const val XP_CURVE_FACTOR = 1.9 // Exponential factor for XP curve (reduced from 2.2)
// XP calculation constants // XP calculation constants
private const val LEVEL_MULTIPLIER = 0.1 // 10% bonus per level private const val LEVEL_MULTIPLIER = 0.15 // 15% bonus per level (increased from 10%)
private const val XP_PER_LINE = 10L private const val XP_PER_LINE = 15L // Increased from 10
private const val TETRIS_XP_BONUS = 50L private const val TETRIS_XP_BONUS = 75L // Increased from 50
private const val PERFECT_CLEAR_XP_BONUS = 200L private const val PERFECT_CLEAR_XP_BONUS = 250L // Increased from 200
private const val TIME_XP_PER_MINUTE = 5L private const val TIME_XP_PER_MINUTE = 8L // Increased from 5
// Theme IDs with required levels // Theme IDs with required levels
const val THEME_CLASSIC = "theme_classic" const val THEME_CLASSIC = "theme_classic"

View file

@ -86,16 +86,18 @@ class ThemeSelector @JvmOverloads constructor(
// Set card background color based on theme // Set card background color based on theme
setCardBackgroundColor(themeInfo.primaryColor) setCardBackgroundColor(themeInfo.primaryColor)
// Add stroke for selected theme // Add more noticeable visual indicator for selected theme
if (isSelected) { if (isSelected) {
setContentPadding(4, 4, 4, 4) setContentPadding(4, 4, 4, 4)
// Create a gradient drawable for the border // Create a gradient drawable for the border
val gradientDrawable = android.graphics.drawable.GradientDrawable().apply { val gradientDrawable = android.graphics.drawable.GradientDrawable().apply {
setColor(themeInfo.primaryColor) setColor(themeInfo.primaryColor)
setStroke(4, Color.WHITE) setStroke(6, Color.WHITE) // Thicker border
cornerRadius = 12f cornerRadius = 12f
} }
background = gradientDrawable background = gradientDrawable
// Add glow effect via elevation
cardElevation = 12f
} }
// Set card dimensions // Set card dimensions
@ -194,9 +196,29 @@ class ThemeSelector @JvmOverloads constructor(
card.setOnClickListener { card.setOnClickListener {
// Only trigger callback if this isn't already the selected theme // Only trigger callback if this isn't already the selected theme
if (themeId != selectedTheme) { if (themeId != selectedTheme) {
// Update visual state // Update previously selected card
themeCards[selectedTheme]?.cardElevation = 2f themeCards[selectedTheme]?.let { prevCard ->
card.cardElevation = 8f prevCard.cardElevation = 2f
// Reset any special styling
prevCard.background = null
prevCard.setCardBackgroundColor(getThemes()[selectedTheme]?.primaryColor ?: Color.BLACK)
}
// Update visual state of newly selected card
card.cardElevation = 12f
// Flash animation for selection feedback
val flashColor = Color.WHITE
val originalColor = themeInfo.primaryColor
// Create animator for flash effect
val flashAnimator = android.animation.ValueAnimator.ofArgb(flashColor, originalColor)
flashAnimator.duration = 300 // 300ms
flashAnimator.addUpdateListener { animator ->
val color = animator.animatedValue as Int
card.setCardBackgroundColor(color)
}
flashAnimator.start()
// Update selected theme // Update selected theme
selectedTheme = themeId selectedTheme = themeId

View file

@ -263,6 +263,7 @@
android:layout_marginBottom="32dp"> android:layout_marginBottom="32dp">
<TextView <TextView
android:id="@+id/settingsTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/settings" android:text="@string/settings"
@ -347,6 +348,7 @@
android:gravity="center"> android:gravity="center">
<TextView <TextView
android:id="@+id/selectLevelText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/select_level" android:text="@string/select_level"
@ -416,6 +418,7 @@
android:layout_marginTop="16dp"> android:layout_marginTop="16dp">
<TextView <TextView
android:id="@+id/musicText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/music" android:text="@string/music"