diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 0c0c338..7ce6325 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -3,7 +3,20 @@ - + + + + + + + + + + + + + + diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1deb434..882371f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -3,7 +3,6 @@ plugins { alias(libs.plugins.jetbrainsKotlinAndroid) id("com.google.gms.google-services") } - android { namespace = "com.example.chiecnonkydieu" compileSdk = 34 @@ -54,4 +53,8 @@ dependencies { //coroutine implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0") + + //wheel + implementation("androidx.navigation:navigation-dynamic-features-fragment:2.7.7") + implementation ("com.github.thanhniencung:LuckyWheel:a6110f5128") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5db1420..270e0e3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,10 +13,11 @@ android:theme="@style/Theme.ChiecNonKyDieu" tools:targetApi="31"> () + val luckyWheelView: LuckyWheelView = binding.luckyWheel + + wheelViewModel.initLuckyItemList(this) + luckyWheelView.setData(wheelViewModel.luckyItemsList) + luckyWheelView.setLuckyRoundItemSelectedListener { + Toast.makeText(this, "on click", Toast.LENGTH_LONG).show() + goToWheelActivity() + } + luckyWheelView.isTouchEnabled = false + binding.llWheel.setOnClickListener { + goToWheelActivity() + } + + + } + override fun onSupportNavigateUp(): Boolean { + onBackPressed() + return true + } + private fun goToWheelActivity() { + val intent = Intent(this, WheelActivity::class.java) + startActivity(intent) } private fun updateUi(gameModel: GameModel?) { diff --git a/app/src/main/java/com/example/chiecnonkydieu/ui/WaitingRoomActivity.kt b/app/src/main/java/com/example/chiecnonkydieu/ui/WaitingRoomActivity.kt index d0b13bd..b79b049 100644 --- a/app/src/main/java/com/example/chiecnonkydieu/ui/WaitingRoomActivity.kt +++ b/app/src/main/java/com/example/chiecnonkydieu/ui/WaitingRoomActivity.kt @@ -60,6 +60,7 @@ class WaitingRoomActivity : AppCompatActivity() { updateUi(gameModel) if (gameModel.gameStatus == GameStatus.INPROGRESS) { goToPlayingRoom() + finish() } }) @@ -148,8 +149,10 @@ class WaitingRoomActivity : AppCompatActivity() { } private fun goToPlayingRoom() { - val intent = Intent(this, PlayingRoomActivity::class.java) - intent.putExtra("room_id", binding.tvMaPhong.text.toString()) + val intent = Intent(this, PlayingRoomActivity::class.java).apply { + putExtra("room_id", binding.tvMaPhong.text.toString()) + flags = Intent.FLAG_ACTIVITY_SINGLE_TOP + } startActivity(intent) } } diff --git a/app/src/main/java/com/example/chiecnonkydieu/ui/WheelActivity.kt b/app/src/main/java/com/example/chiecnonkydieu/ui/WheelActivity.kt deleted file mode 100644 index eca307d..0000000 --- a/app/src/main/java/com/example/chiecnonkydieu/ui/WheelActivity.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.example.chiecnonkydieu.ui - -import android.os.Bundle -import androidx.activity.enableEdgeToEdge -import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.widget.Toolbar -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat -import com.example.chiecnonkydieu.R -import com.example.chiecnonkydieu.databinding.ActivityWheelBinding - -class WheelActivity : AppCompatActivity() { - private lateinit var binding: ActivityWheelBinding - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - enableEdgeToEdge() - binding = ActivityWheelBinding.inflate(layoutInflater) - val view = binding.root - setContentView(view) - ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> - val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) - insets - } - val toolbar: Toolbar = binding.toolbar - setSupportActionBar(toolbar) - - supportActionBar?.setDisplayHomeAsUpEnabled(true) - supportActionBar?.setDisplayShowHomeEnabled(true) - - } - override fun onSupportNavigateUp(): Boolean { - onBackPressed() - return true - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/chiecnonkydieu/ui/wheel/WheelActivity.kt b/app/src/main/java/com/example/chiecnonkydieu/ui/wheel/WheelActivity.kt new file mode 100644 index 0000000..25df369 --- /dev/null +++ b/app/src/main/java/com/example/chiecnonkydieu/ui/wheel/WheelActivity.kt @@ -0,0 +1,93 @@ +package com.example.chiecnonkydieu.ui.wheel + +import android.content.Intent +import android.os.Build +import android.os.Bundle +import android.os.CountDownTimer +import android.widget.Toast +import androidx.activity.enableEdgeToEdge +import androidx.activity.viewModels +import androidx.annotation.RequiresApi +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.get +import com.example.chiecnonkydieu.R +import com.example.chiecnonkydieu.databinding.ActivityWheelBinding +import rubikstudio.library.LuckyWheelView +import rubikstudio.library.model.LuckyItem + +class WheelActivity : AppCompatActivity() { + private lateinit var binding: ActivityWheelBinding + private lateinit var countDownTimer: CountDownTimer + + @RequiresApi(Build.VERSION_CODES.O) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + binding = ActivityWheelBinding.inflate(layoutInflater) + val view = binding.root + setContentView(view) + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> + val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) + insets + } + val toolbar: Toolbar = binding.toolbar + setSupportActionBar(toolbar) + + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowHomeEnabled(true) + + val wheelViewModel: WheelViewModel by viewModels() + val luckyWheelView: LuckyWheelView = binding.luckyWheel + + wheelViewModel.initLuckyItemList(this) + luckyWheelView.setData(wheelViewModel.luckyItemsList) + + luckyWheelView.isTouchEnabled = false + luckyWheelView.setOnTouchListener { v, event -> + val indexAns = wheelViewModel.getIndexAfterRotate() + luckyWheelView.setRound(3) + luckyWheelView.startLuckyWheelWithTargetIndex(indexAns) + Toast.makeText(this, wheelViewModel.getStringItemAtIndex(indexAns), Toast.LENGTH_LONG).show() + return@setOnTouchListener true + } + + + binding.btnQuay.setOnClickListener { + val indexAns = wheelViewModel.getIndexAfterRotate() + luckyWheelView.setRound(3) + luckyWheelView.startLuckyWheelWithTargetIndex(indexAns) + Toast.makeText(this, wheelViewModel.getStringItemAtIndex(indexAns), Toast.LENGTH_LONG).show() +// Toast.makeText(this, wheelViewModel.luckyItemsList.get(3).secondaryText, Toast.LENGTH_LONG).show() + } + + // count down timer + countDownTimer = object : CountDownTimer(7000, 1000) { + override fun onTick(millisUntilFinished: Long) { + val secondsLeft = millisUntilFinished / 1000 + binding.tvConLaiXGiay.text = String.format(getString(R.string.con_lai_x_giay), secondsLeft.toString()) + } + + override fun onFinish() { + binding.tvConLaiXGiay.text = String.format(getString(R.string.con_lai_x_giay), 0) + binding.btnQuay.performClick() + + } + } + + countDownTimer.start() + + } + override fun onSupportNavigateUp(): Boolean { + onBackPressed() + return true + } + + override fun onDestroy() { + super.onDestroy() + countDownTimer.cancel() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/chiecnonkydieu/ui/wheel/WheelViewModel.kt b/app/src/main/java/com/example/chiecnonkydieu/ui/wheel/WheelViewModel.kt new file mode 100644 index 0000000..3153000 --- /dev/null +++ b/app/src/main/java/com/example/chiecnonkydieu/ui/wheel/WheelViewModel.kt @@ -0,0 +1,87 @@ +package com.example.chiecnonkydieu.ui.wheel + +import android.content.Context +import android.graphics.Color +import androidx.core.content.ContextCompat +import androidx.lifecycle.ViewModel +import com.example.chiecnonkydieu.R +import rubikstudio.library.model.LuckyItem +class WheelViewModel: ViewModel() { + private val _luckyItemsList: MutableList = mutableListOf() + val luckyItemsList:List = _luckyItemsList + + fun initLuckyItemList(context: Context) { + val luckyItem: LuckyItem = LuckyItem() + luckyItem.secondaryText = "100" + luckyItem.color = ContextCompat.getColor(context, R.color.purple_300) + _luckyItemsList.add(luckyItem) + + val luckyItem2: LuckyItem = LuckyItem() + luckyItem2.secondaryText = "400" + luckyItem2.color = ContextCompat.getColor(context, R.color.green) + _luckyItemsList.add(luckyItem2) + + val luckyItem3: LuckyItem = LuckyItem() + luckyItem3.secondaryText = "800" + luckyItem3.color = ContextCompat.getColor(context, R.color.blue_200) + _luckyItemsList.add(luckyItem3) + + val luckyItem4: LuckyItem = LuckyItem() + luckyItem4.topText = "EXTRA TURN" + luckyItem4.icon = R.drawable.ic_man + luckyItem4.color = ContextCompat.getColor(context, R.color.purple_500) + _luckyItemsList.add(luckyItem4) + + val luckyItem5: LuckyItem = LuckyItem() + luckyItem5.secondaryText = "1200" + luckyItem5.color = ContextCompat.getColor(context, R.color.gray) + _luckyItemsList.add(luckyItem5) + + val luckyItem6: LuckyItem = LuckyItem() + luckyItem6.secondaryText = "600" + luckyItem6.color = ContextCompat.getColor(context, R.color.blue_200) + + _luckyItemsList.add(luckyItem6) + + val luckyItem7: LuckyItem = LuckyItem() + luckyItem7.topText = "MISS TURN" + luckyItem7.icon = R.drawable.ic_man + luckyItem7.color = ContextCompat.getColor(context, R.color.purple_500) + _luckyItemsList.add(luckyItem7) + + val luckyItem8: LuckyItem = LuckyItem() + luckyItem8.secondaryText = "800" + luckyItem8.color = ContextCompat.getColor(context, R.color.green) + _luckyItemsList.add(luckyItem8) + + val luckyItem9: LuckyItem = LuckyItem() + luckyItem9.secondaryText = "1500" + luckyItem9.color = ContextCompat.getColor(context, R.color.purple_300) + _luckyItemsList.add(luckyItem9) + + val luckyItem10: LuckyItem = LuckyItem() + luckyItem10.secondaryText = "400" + luckyItem10.color = ContextCompat.getColor(context, R.color.green) + _luckyItemsList.add(luckyItem10) + + val luckyItem11: LuckyItem = LuckyItem() + luckyItem11.topText = "ITEM" + luckyItem11.icon = R.drawable.ic_wheel + luckyItem11.color = ContextCompat.getColor(context, R.color.orange) + _luckyItemsList.add(luckyItem11) + } + + fun getIndexAfterRotate(): Int { + // TODO + val size = _luckyItemsList.size - 1 + return (0 .. size).random() + } + fun getStringItemAtIndex(index: Int): String { + return if (!_luckyItemsList[index].secondaryText.isNullOrEmpty()) { + _luckyItemsList[index].secondaryText + } + else { + _luckyItemsList[index].topText + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/chiecnonkydieu/ui/wheelSpinnerViewModel/WheelSpinnerViewModel.kt b/app/src/main/java/com/example/chiecnonkydieu/ui/wheelSpinnerViewModel/WheelSpinnerViewModel.kt new file mode 100644 index 0000000..d584f86 --- /dev/null +++ b/app/src/main/java/com/example/chiecnonkydieu/ui/wheelSpinnerViewModel/WheelSpinnerViewModel.kt @@ -0,0 +1,46 @@ +package com.example.chiecnonkydieu.ui.wheelSpinnerViewModel + +import com.example.chiecnonkydieu.R + +import android.content.Context +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import rubikstudio.library.LuckyWheelView +import rubikstudio.library.model.LuckyItem +import java.util.* + +class WheelSpinnerViewModel ( itemList: List, context: Context ): ViewModel() { + private val luckyItemList = MutableLiveData>() + val liveLuckyItemList: LiveData> + get() = luckyItemList + private val spinIndex = MutableLiveData() + val liveSpinIndex : LiveData + get() = spinIndex + private val colors = arrayOf(R.color.orange, R.color.black) + + init { + val listItems = mutableListOf() + + for (i in itemList.indices) run { + val luckyItem = LuckyItem() + luckyItem.secondaryText = itemList[i] + luckyItem.topText = ( i + 1 ).toString() + luckyItem.color = context.getColor( this.colors[if (i % 2 == 0) 0 else 1] ) + listItems.add(luckyItem) + } + + this.luckyItemList.value = listItems + } + + fun spinWheel() { + val rand = Random() + spinIndex.value = rand.nextInt(this.luckyItemList.value!!.size - 1) + 0 + } + + fun doneSpinning(){ + spinIndex.value = -1 + } + +} + diff --git a/app/src/main/res/drawable/ic_center_wheel.png b/app/src/main/res/drawable/ic_center_wheel.png new file mode 100644 index 0000000..5063bfc Binary files /dev/null and b/app/src/main/res/drawable/ic_center_wheel.png differ diff --git a/app/src/main/res/drawable/ic_cursor.png b/app/src/main/res/drawable/ic_cursor.png new file mode 100644 index 0000000..c275eb4 Binary files /dev/null and b/app/src/main/res/drawable/ic_cursor.png differ diff --git a/app/src/main/res/layout/activity_playing_room.xml b/app/src/main/res/layout/activity_playing_room.xml index 628334a..9976548 100644 --- a/app/src/main/res/layout/activity_playing_room.xml +++ b/app/src/main/res/layout/activity_playing_room.xml @@ -220,7 +220,6 @@ app:layout_constraintTop_toBottomOf="@+id/linearLayout"> - + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_wheel.xml b/app/src/main/res/layout/activity_wheel.xml index 2aa10fa..77346c7 100644 --- a/app/src/main/res/layout/activity_wheel.xml +++ b/app/src/main/res/layout/activity_wheel.xml @@ -4,8 +4,9 @@ xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" + android:background="@color/background" android:layout_height="match_parent" - tools:context=".ui.WheelActivity"> + tools:context=".ui.wheel.WheelActivity"> + + + + + + + Hint Đến lượt của bạn - Còn lại {O} s + Còn lại %s s Nhập lời giải \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 2107749..7548677 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,10 @@ buildscript { dependencies { classpath(libs.google.services) } + repositories { + maven { url = uri("https://www.jitpack.io") } + } + } // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { diff --git a/settings.gradle.kts b/settings.gradle.kts index c31862a..741499a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,9 @@ dependencyResolutionManagement { repositories { google() mavenCentral() + maven { + setUrl("https://jitpack.io") + } } }