From 442124baa483f8d1c4aaca7ff81e15dd3f122363 Mon Sep 17 00:00:00 2001
From: 罗明文 <125975490@qq.com>
Date: 星期四, 22 五月 2025 13:14:36 +0800
Subject: [PATCH] save

---
 app/src/main/java/com/dollearn/student/ui/home/MemoryActivity.kt |  265 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 249 insertions(+), 16 deletions(-)

diff --git a/app/src/main/java/com/dollearn/student/ui/home/MemoryActivity.kt b/app/src/main/java/com/dollearn/student/ui/home/MemoryActivity.kt
index 6ab0321..766e45b 100644
--- a/app/src/main/java/com/dollearn/student/ui/home/MemoryActivity.kt
+++ b/app/src/main/java/com/dollearn/student/ui/home/MemoryActivity.kt
@@ -1,17 +1,34 @@
 package com.dollearn.student.ui.home
 
-import android.os.CountDownTimer
+import android.os.Handler
+import android.util.Log
 import androidx.core.os.bundleOf
 import androidx.recyclerview.widget.GridLayoutManager
+import cn.sinata.xldutils.gone
+import cn.sinata.xldutils.utils.SPUtils
+import cn.sinata.xldutils.utils.showAllowingStateLoss
+import cn.sinata.xldutils.visible
 import com.dollearn.student.R
 import com.dollearn.student.dialog.TipDialog
+import com.dollearn.student.network.HttpManager
 import com.dollearn.student.network.entity.Card
 import com.dollearn.student.network.entity.MemoryBean
+import com.dollearn.student.network.request
 import com.dollearn.student.ui.TransparentStatusBarActivity
 import com.dollearn.student.ui.home.adapter.CardAdapter
+import com.dollearn.student.utils.AudioUtils
+import com.dollearn.student.utils.Const
+import com.dollearn.student.utils.event.EmptyEvent
 import kotlinx.android.synthetic.main.activity_memory.*
+import kotlinx.android.synthetic.main.item_card.view.*
+import org.greenrobot.eventbus.EventBus
+import org.jetbrains.anko.imageResource
+import kotlin.math.abs
+import kotlin.math.max
+import kotlin.math.min
+import kotlin.math.sqrt
 
-class MemoryActivity : TransparentStatusBarActivity() {
+class MemoryActivity : TransparentStatusBarActivity(), AudioUtils.OnAudioStatusUpdateListener {
     override fun setContentView() = R.layout.activity_memory
 
     private val data by lazy {
@@ -19,32 +36,248 @@
     }
     private val list = arrayListOf<Card>()
     private val adapter = CardAdapter(list)
-    private val TIME = 600*1000L
-    private var timer:CountDownTimer? = null
+    val TAG = "Memory====>"
+
+    private var lastTime = 600 //剩余秒
+
+    private var totalCount = 0
+    private var rightCount = 0
+
+    var handler: Handler? = null
+    var time = 0 //学习秒数
+
+
+    val PLAY_VOICE = 1
+    private val STUDY_TIME = 2
+
+    val PLAY_RIGHT = 4
+    val PLAY_ERROR = 5
+
+    private val errorVoice by lazy { SPUtils.instance().getString(Const.EV) }
+    private val rightVoice by lazy { SPUtils.instance().getString(Const.RV) }
+
+    private var rightPlaying = false
+    private var errorPlaying = false
+
+    private val player by lazy { AudioUtils() }
+
+    var index = 0
+
+    var playing = false
 
     override fun initClick() {
-
+        tv_exit.setOnClickListener {
+            if (tv_exit.text == "提交"){
+                val right = list.filter { !it.isBack }.size / 2
+                val total = data.photoList.size
+                val score = right*data.data.answerIntegral/total
+                ResultActivity.startResult(this,0,0,0,7, total, right,score,time,data!!.data.id)
+                finish()
+            }else
+                onBackPressed()
+        }
     }
 
     override fun initView() {
-        rv_list.layoutManager = GridLayoutManager(this,5)
+        player.setOnAudioStatusUpdateListener(this)
+        player.stopPlayMusic()
+        handler = object : Handler(android.os.Looper.getMainLooper()){
+            override fun handleMessage(msg: android.os.Message) {
+                super.handleMessage(msg)
+                when(msg.what){
+                    STUDY_TIME->{
+                        time++
+                        lastTime --
+                        tv_timer.text = "${lastTime}S"
+                        if (lastTime == 0){
+                            val tipDialog = TipDialog()
+                            tipDialog.arguments = bundleOf("msg" to "答题时间已结束,停止作答!","isAlert" to true,"ok" to "查看成绩")
+                            tipDialog.setDismissCallback(object :TipDialog.OnDismiss{
+                                override fun onDismiss() {
+                                    val right = list.filter { !it.isBack }.size / 2
+                                    val total = data.photoList.size
+                                    val score = right*data.data.answerIntegral/total
+                                    ResultActivity.startResult(this@MemoryActivity,0,0,0,7,total,right
+                                        ,score,time,data.data.id)
+                                    finish()
+                                }
+                            })
+                            tipDialog.showAllowingStateLoss(supportFragmentManager,"finish")
+                        }else
+                            sendEmptyMessageDelayed(STUDY_TIME,1000)
+                    }
+                    PLAY_VOICE->{
+                        playing = true
+                        player.startPlayMusic(this@MemoryActivity,list[index].url)
+                        rv_list.getChildAt(index).iv_play.setImageResource(R.mipmap.playing_blue)
+                    }
+                    PLAY_RIGHT->{
+                        playing = true
+                        rightPlaying = true
+                        player.startPlayMusic(this@MemoryActivity,rightVoice)
+                    }
+                    PLAY_ERROR->{
+                        playing = true
+                        errorPlaying = true
+                        player.startPlayMusic(this@MemoryActivity,errorVoice)
+                    }
+                }
+            }
+        }
+
+        lastTime = data.data.answerTime //倒计时时间
+        tv_timer.text = "${lastTime}S"
+        handler?.sendEmptyMessageDelayed(STUDY_TIME,1000)
         rv_list.adapter = adapter
         list.addAll(data.photoList.map { Card(it.id,1,it.photo) })
         list.addAll(data.voiceList.map { Card(it.id,2,it.voice) })
         list.shuffle()
+        rv_list.postDelayed({
+            initRecycler(list.size)
+        },500)
+    }
+
+    /**
+     * 需要计算行列数
+     */
+    private fun initRecycler(total: Int){
+        var bestRows = 1
+        var bestColumns: Int = total
+        var i = 1
+        while (i <= sqrt(total.toDouble())) {
+            val rows = i
+            val columns: Int = if (total%i>0) (total / i)+1 else total / i
+            // Calculate the absolute difference between rows and columns
+            val diff = abs(rows - columns)
+            // Update the best rows and columns if this pair has a smaller difference
+            if (diff < abs(bestRows - bestColumns)) {
+                bestRows = rows
+                bestColumns = columns
+            }
+            i++
+        }
+        Log.e(TAG,"总数:$total,计算得到行数:${min(bestColumns,bestRows)},列数:${max(bestColumns,bestRows)}")
+        val lineHeight = rv_list.height.toDouble() / min(bestColumns, bestRows)
+        val lineWidth = rv_list.width.toDouble() / max(bestColumns, bestRows)
+        Log.e(TAG,"高度:${rv_list.height},计算得到行高:${lineHeight},宽度:${rv_list.width},计算得到行宽:${lineWidth}")
+        rv_list.layoutManager = GridLayoutManager(this, max(bestColumns,bestRows))
+        adapter.height = lineHeight.toInt()
+        adapter.widgh = lineWidth.toInt()
         adapter.notifyDataSetChanged()
+    }
 
-        timer = object :CountDownTimer(TIME,1000){
-            override fun onTick(millisUntilFinished: Long) {
-
-            }
-
-            override fun onFinish() {
-                val tipDialog = TipDialog()
-                tipDialog.arguments = bundleOf("msg" to "答题时间已结束,停止作答!")
-            }
-
+    /**
+     * 翻开卡片
+     */
+    fun flyover(position:Int){
+        val card = list[position]
+        if (card.type == 2){ //如果是语音 先播放语音
+            index = position
+            handler?.sendEmptyMessage(PLAY_VOICE)
+        }else{ //不是语音直接比较结果
+            checkResult()
         }
     }
 
+    private fun checkResult(){
+        if (adapter.position1!=-1&&adapter.position2!=-1){ //已经翻开2张卡片,比较结果是否匹配
+            totalCount++
+            val card1 = list[adapter.position1]
+            val card2 = list[adapter.position2]
+            if (card1.type!=card2.type&&card1.id == card2.id){//匹配成功
+                handler?.sendEmptyMessage(PLAY_RIGHT)
+                rightCount++
+                rv_list.getChildAt(adapter.position1).iv_result?.apply {
+                    imageResource = R.mipmap.successs
+                    visible()
+                    postDelayed({
+                        gone()
+                    },1500)
+                }
+                rv_list.getChildAt(adapter.position2).iv_result?.apply {
+                    imageResource = R.mipmap.successs
+                    visible()
+                    postDelayed({
+                        gone()
+                    },1500)
+                }
+                tv_timer.postDelayed({
+                    if (list.filter { !it.isBack }.size == list.size){ //全部答对
+                        tv_exit.text = "提交"
+                        handler?.removeMessages(STUDY_TIME) //停止计时
+                    }
+                },500)
+            }else{
+                handler?.sendEmptyMessage(PLAY_ERROR)
+                rv_list.getChildAt(adapter.position1).iv_result?.apply {
+                    imageResource = R.mipmap.zhifushibai
+                    visible()
+                    postDelayed({
+                        gone()
+                    },1500)
+                }
+                rv_list.getChildAt(adapter.position2).iv_result?.apply {
+                    imageResource = R.mipmap.zhifushibai
+                    visible()
+                    postDelayed({
+                        gone()
+                    },1500)
+                }
+            }
+        }
+    }
+
+    override fun onBackPressed() {
+        HttpManager.exitGameOrStory(time).request(this){ _, _->
+            super.onBackPressed()
+        }
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        handler?.removeMessages(PLAY_VOICE)
+        handler?.removeMessages(STUDY_TIME)
+        handler = null
+        EventBus.getDefault().post(EmptyEvent(Const.EventCode.STOP_TIMER))
+    }
+
+    override fun onPause() {
+        super.onPause()
+        player.stopPlayMusic()
+    }
+
+    override fun onUpdate(db: Double, time: Long) {
+
+    }
+
+    override fun onStop(filePath: String?) {
+    }
+
+    override fun onStartPlay() {
+        playing = true
+    }
+
+    override fun onFinishPlay() {
+        playing = false
+        if (errorPlaying){
+            errorPlaying = false
+            playing = true
+            tv_timer.postDelayed({
+                adapter.bothToBack()
+                playing = false //防止翻转过程中点击,造成缓存view被销毁
+            },500)
+        }else if (rightPlaying){
+            rightPlaying = false
+            val card1 = list[adapter.position1]
+            if (card1.type == 2)
+                index = adapter.position1
+            else
+                index = adapter.position2
+            adapter.releaseHolder()
+            handler?.sendEmptyMessage(PLAY_VOICE)
+        }else{
+            rv_list.getChildAt(index).iv_play.setImageResource(R.mipmap.play_blue)
+            checkResult()
+        }
+    }
 }

--
Gitblit v1.7.1