From d298755e60e2c46c292f7a0f0eed091324be98a1 Mon Sep 17 00:00:00 2001 From: js Date: Fri, 26 May 2023 02:22:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E7=9A=84=E5=88=97=E8=A1=A8=E5=88=A0=E9=99=A4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 4 - .../aircraftwar/gui/ScoreboardActivity.kt | 121 ++++++++++++++---- .../imshit/aircraftwar/logic/game/Games.kt | 2 - .../main/res/drawable-night/ic_close_24.xml | 9 ++ app/src/main/res/drawable/ic_close_24.xml | 10 ++ .../main/res/layout/activity_scoreboard.xml | 2 +- .../main/res/layout/scoreboard_view_item.xml | 104 +++++++-------- .../{scoreboard.xml => scoreboard_action.xml} | 12 -- app/src/main/res/values-en/strings.xml | 1 + app/src/main/res/values-night/themes.xml | 6 +- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values-zh/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/themes.xml | 4 + 14 files changed, 178 insertions(+), 100 deletions(-) create mode 100644 app/src/main/res/drawable-night/ic_close_24.xml create mode 100644 app/src/main/res/drawable/ic_close_24.xml rename app/src/main/res/menu/{scoreboard.xml => scoreboard_action.xml} (57%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1b7ed69..31b8b7d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,7 +20,6 @@ android { versionCode = 1 versionName = "1.0" resourceConfigurations.addAll(listOf("zh", "en")) - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } signingConfigs { create("js") { @@ -66,7 +65,4 @@ dependencies { implementation("androidx.navigation:navigation-ui-ktx:2.5.3") implementation("com.google.android.material:material:1.9.0") implementation("com.squareup.okhttp3:okhttp:4.10.0") - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") } \ No newline at end of file diff --git a/app/src/main/java/net/imshit/aircraftwar/gui/ScoreboardActivity.kt b/app/src/main/java/net/imshit/aircraftwar/gui/ScoreboardActivity.kt index 6ed3359..da1878c 100644 --- a/app/src/main/java/net/imshit/aircraftwar/gui/ScoreboardActivity.kt +++ b/app/src/main/java/net/imshit/aircraftwar/gui/ScoreboardActivity.kt @@ -3,20 +3,23 @@ package net.imshit.aircraftwar.gui import android.content.Context import android.content.Intent import android.os.Bundle +import android.view.ActionMode import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.TextView -import android.widget.Toast import androidx.appcompat.app.AppCompatActivity -import androidx.cardview.widget.CardView import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.card.MaterialCardView import net.imshit.aircraftwar.R import net.imshit.aircraftwar.data.app.AppInfo import net.imshit.aircraftwar.data.scoreboard.ScoreInfo import net.imshit.aircraftwar.data.scoreboard.ScoreboardDaoSharedPreferences import net.imshit.aircraftwar.databinding.ActivityScoreboardBinding import net.imshit.aircraftwar.logic.game.Difficulty +import java.util.TreeMap class ScoreboardActivity : AppCompatActivity() { companion object { @@ -27,10 +30,11 @@ class ScoreboardActivity : AppCompatActivity() { }) } - class ScoreInfoAdapter(private val scoreInfoList: MutableList) : - RecyclerView.Adapter() { + class ScoreInfoAdapter( + private val activity: AppCompatActivity, + private val scoreInfoList: MutableList + ) : RecyclerView.Adapter() { class ScoreInfoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - val view: CardView = itemView.findViewById(R.id.sbvi_card) private val nameView: TextView = itemView.findViewById(R.id.sbvi_name) private val scoreView: TextView = itemView.findViewById(R.id.sbvi_score) private val timeView: TextView = itemView.findViewById(R.id.sbvi_time) @@ -41,17 +45,76 @@ class ScoreboardActivity : AppCompatActivity() { } } + inner class ActionModeCallback : ActionMode.Callback { + override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean { + mode?.menuInflater?.inflate(R.menu.scoreboard_action, menu) + return true + } + + override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean { + return true + } + + override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean { + return when (item?.itemId) { + R.id.item_delete -> { + removeSelected() + mode?.finish() + true + } + + else -> false + } + } + + override fun onDestroyActionMode(mode: ActionMode?) { + onExitActionMode() + } + } + + private val callback = ActionModeCallback() + private var isMultiSelect = false + private val selected: MutableMap = TreeMap() + private var actionMode: ActionMode? = null + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ScoreInfoViewHolder { val view = LayoutInflater.from(parent.context) - .inflate(R.layout.scoreboard_view_item, parent, false) - val scoreInfoViewHolder = ScoreInfoViewHolder(view) - scoreInfoViewHolder.view.setOnLongClickListener { - val position = scoreInfoViewHolder.adapterPosition - scoreInfoList.removeAt(position) - notifyItemRemoved(position) - false + .inflate(R.layout.scoreboard_view_item, parent, false) as MaterialCardView + val holder = ScoreInfoViewHolder(view) + view.setOnLongClickListener { + isMultiSelect = true + updateSelection(holder.adapterPosition, view) + return@setOnLongClickListener true + } + view.setOnClickListener { + if (isMultiSelect) { + updateSelection(holder.adapterPosition, view) + } + } + return holder + } + + private fun updateActionMode() { + if (actionMode == null) { + actionMode = activity.startActionMode(callback) + } + if (selected.isEmpty()) { + actionMode?.finish() + } else { + actionMode?.title = + activity.getString(R.string.scoreboard_action_title, selected.size) } - return scoreInfoViewHolder + } + + private fun updateSelection(index: Int, view: MaterialCardView) { + if (view.isChecked) { + selected.remove(index) + view.isChecked = false + } else { + selected[index] = view + view.isChecked = true + } + updateActionMode() } override fun getItemCount(): Int = scoreInfoList.size @@ -59,7 +122,24 @@ class ScoreboardActivity : AppCompatActivity() { override fun onBindViewHolder(holder: ScoreInfoViewHolder, position: Int) { holder.bind(scoreInfoList[position]) } + + fun removeSelected() { + selected.keys.sortedDescending().forEach { + scoreInfoList.removeAt(it) + notifyItemRemoved(it) + } + } + + fun onExitActionMode() { + selected.values.forEach { + it.isChecked = false + } + selected.clear() + isMultiSelect = false + actionMode = null + } } + } private lateinit var dao: ScoreboardDaoSharedPreferences @@ -74,9 +154,7 @@ class ScoreboardActivity : AppCompatActivity() { scoreInfo = getParcelableExtra("scoreInfo", ScoreInfo::class.java) } this.dao = ScoreboardDaoSharedPreferences(this, gameMode) - scoreInfo?.let { - this.dao.addItem(scoreInfo) - } + scoreInfo?.let(this.dao::addItem) // draw with(ActivityScoreboardBinding.inflate(layoutInflater)) { setContentView(root) @@ -84,23 +162,20 @@ class ScoreboardActivity : AppCompatActivity() { asTb.setNavigationOnClickListener { this@ScoreboardActivity.finish() } - asTb.setOnMenuItemClickListener { item -> when (item.itemId) { R.id.item_about -> AppInfo.showAboutDialog(this@ScoreboardActivity) - - R.id.item_delete -> Toast.makeText( - this@ScoreboardActivity, "长按删除", Toast.LENGTH_SHORT - ).show()// TODO } return@setOnMenuItemClickListener true } - asRv.adapter = ScoreInfoAdapter(dao.buffer) + + asRv.adapter = ScoreInfoAdapter(this@ScoreboardActivity, dao.buffer) + } } override fun onDestroy() { - super.onDestroy() this.dao.close() + super.onDestroy() } } \ No newline at end of file diff --git a/app/src/main/java/net/imshit/aircraftwar/logic/game/Games.kt b/app/src/main/java/net/imshit/aircraftwar/logic/game/Games.kt index ba56d0e..cf9581f 100644 --- a/app/src/main/java/net/imshit/aircraftwar/logic/game/Games.kt +++ b/app/src/main/java/net/imshit/aircraftwar/logic/game/Games.kt @@ -8,7 +8,6 @@ import android.graphics.Paint import android.os.Handler import android.os.Message import android.util.AttributeSet -import android.util.Log import android.view.SurfaceHolder import android.view.SurfaceView import android.view.ViewTreeObserver @@ -59,7 +58,6 @@ sealed class Games(context: Context, attrs: AttributeSet?, soundMode: Boolean) : game.update() game.draw() val elapseTime = System.currentTimeMillis() % REFRESH_INTERVAL - Log.e(">>>", elapseTime.toString()) sleep(REFRESH_INTERVAL - elapseTime) } } catch (_: InterruptedException) { diff --git a/app/src/main/res/drawable-night/ic_close_24.xml b/app/src/main/res/drawable-night/ic_close_24.xml new file mode 100644 index 0000000..6f6c876 --- /dev/null +++ b/app/src/main/res/drawable-night/ic_close_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_close_24.xml b/app/src/main/res/drawable/ic_close_24.xml new file mode 100644 index 0000000..35b1348 --- /dev/null +++ b/app/src/main/res/drawable/ic_close_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_scoreboard.xml b/app/src/main/res/layout/activity_scoreboard.xml index c0b2acd..8bc4122 100644 --- a/app/src/main/res/layout/activity_scoreboard.xml +++ b/app/src/main/res/layout/activity_scoreboard.xml @@ -16,7 +16,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true" - app:menu="@menu/scoreboard" + app:menu="@menu/main" app:navigationContentDescription="@string/navback" app:navigationIcon="@drawable/ic_arrow_back_24" app:title="@string/scoreboard_label" diff --git a/app/src/main/res/layout/scoreboard_view_item.xml b/app/src/main/res/layout/scoreboard_view_item.xml index e0f99ba..2c27a63 100644 --- a/app/src/main/res/layout/scoreboard_view_item.xml +++ b/app/src/main/res/layout/scoreboard_view_item.xml @@ -1,67 +1,57 @@ - - - + + + android:paddingHorizontal="10dp"> - - - - - - - - - - - - - - - \ No newline at end of file + android:fontFamily="sans-serif" + android:textFontWeight="450" + android:textSize="24sp" + app:layout_constraintBottom_toTopOf="@id/sbvi_time" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="1.0" + tools:text="哈小深" /> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/scoreboard.xml b/app/src/main/res/menu/scoreboard_action.xml similarity index 57% rename from app/src/main/res/menu/scoreboard.xml rename to app/src/main/res/menu/scoreboard_action.xml index 64ea116..0034180 100644 --- a/app/src/main/res/menu/scoreboard.xml +++ b/app/src/main/res/menu/scoreboard_action.xml @@ -13,16 +13,4 @@ android:tooltipText="@string/item_delete_long" android:visible="true" app:showAsAction="ifRoom|withText|collapseActionView" /> - \ No newline at end of file diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index b03df6e..d6e9c96 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -27,4 +27,5 @@ Register User Info Return + %d item(s) selected. \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 7972f51..c24af62 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -14,5 +14,9 @@ @android:color/transparent true always - + + true + @drawable/ic_close_24 + @style/ThemeOverlay.Material3.Dark.ActionBar + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a89e264..d4793a6 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -27,4 +27,5 @@ 注册 用户信息 返回 + 已选中 %d 项 \ No newline at end of file diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index a89e264..d4793a6 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -27,4 +27,5 @@ 注册 用户信息 返回 + 已选中 %d 项 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0243ef0..223d6eb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,4 +31,5 @@ 注册 用户信息 返回 + 已选中 %d 项 \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 8a7b55f..27450a9 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -14,5 +14,9 @@ @android:color/transparent true always + + true + @drawable/ic_close_24 + @style/ThemeOverlay.Material3.Dark.ActionBar \ No newline at end of file