diff --git a/app/src/main/java/com/coldmint/rust/pro/CreationWizardActivity.kt b/app/src/main/java/com/coldmint/rust/pro/CreationWizardActivity.kt index 825fcbc..9141f86 100644 --- a/app/src/main/java/com/coldmint/rust/pro/CreationWizardActivity.kt +++ b/app/src/main/java/com/coldmint/rust/pro/CreationWizardActivity.kt @@ -1,14 +1,10 @@ package com.coldmint.rust.pro import android.content.Intent -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import com.coldmint.rust.core.debug.LogCat import com.coldmint.rust.pro.adapters.GuideAdapter import com.coldmint.rust.pro.base.BaseActivity @@ -19,10 +15,7 @@ import com.coldmint.rust.pro.ui.StableLinearLayoutManager class CreationWizardActivity : BaseActivity() { - lateinit var createMod: ActivityResultLauncher - - //创建向导类型(模组,模板包) - lateinit var type: String + private lateinit var createMod: ActivityResultLauncher override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) { setReturnButton() title = getString(R.string.creation_assistant) @@ -34,59 +27,14 @@ class CreationWizardActivity : BaseActivity() { LogCat.d("创建单位", "没有收到数据。") } } - val temType = intent.getStringExtra("type") - if (temType.isNullOrBlank()) { - showToast("请传入类型") - finish() - return - } - type = temType viewBinding.recyclerView.layoutManager = StableLinearLayoutManager(this) - when (temType) { - "mod" -> { - loadMod() - } - "template" -> { - loadTemplate() - } - } - } - - /** - * 加载模板活动 - */ - private fun loadTemplate() { - val dataList = ArrayList() - dataList.add( - GuideData( - R.string.import_template, - R.string.import_template_describe, - R.drawable.folder - ) - ) - val adapter = GuideAdapter(this, dataList) - adapter.setItemEvent { i, itemGuideBinding, viewHolder, guideData -> - itemGuideBinding.root.setOnClickListener { - finish() - when (guideData.titleRes) { - R.string.import_template -> { - val startIntent = - Intent(this, FileManagerActivity::class.java) - val fileBundle = Bundle() - fileBundle.putString("type", "selectFile") - startIntent.putExtra("data", fileBundle) - startActivity(startIntent) - } - } - } - } - viewBinding.recyclerView.adapter = adapter + loadMod() } /** * 加载模组活动 */ - fun loadMod() { + private fun loadMod() { val dataList = ArrayList() dataList.add( GuideData( @@ -128,6 +76,7 @@ class CreationWizardActivity : BaseActivity() { ) createMod.launch(startActivity) } + R.string.import_mod -> { val startIntent = Intent(this, FileManagerActivity::class.java) @@ -137,6 +86,7 @@ class CreationWizardActivity : BaseActivity() { startActivity(startIntent) finish() } + R.string.import_mod_from_package_directory -> { val startIntent = Intent(this, FileManagerActivity::class.java) @@ -152,6 +102,7 @@ class CreationWizardActivity : BaseActivity() { startActivity(startIntent) finish() } + R.string.import_mod_from_recycle_bin -> { startActivity(Intent(this, RecyclingStationActivity::class.java)) finish() diff --git a/app/src/main/java/com/coldmint/rust/pro/SettingsActivity.kt b/app/src/main/java/com/coldmint/rust/pro/SettingsActivity.kt index 94e175b..638ac59 100644 --- a/app/src/main/java/com/coldmint/rust/pro/SettingsActivity.kt +++ b/app/src/main/java/com/coldmint/rust/pro/SettingsActivity.kt @@ -10,7 +10,6 @@ import android.widget.Toast import androidx.appcompat.app.AppCompatDelegate import androidx.preference.ListPreference import androidx.preference.Preference -import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat import com.bumptech.glide.Glide import com.coldmint.rust.core.tool.FileOperator diff --git a/app/src/main/java/com/coldmint/rust/pro/fragments/ModFragment.kt b/app/src/main/java/com/coldmint/rust/pro/fragments/ModFragment.kt index 3c4de6d..ea8ed31 100644 --- a/app/src/main/java/com/coldmint/rust/pro/fragments/ModFragment.kt +++ b/app/src/main/java/com/coldmint/rust/pro/fragments/ModFragment.kt @@ -2,51 +2,48 @@ package com.coldmint.rust.pro.fragments import android.annotation.SuppressLint import android.content.res.ColorStateList -import android.os.* +import android.os.Build +import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible -import androidx.recyclerview.widget.DividerItemDecoration -import androidx.recyclerview.widget.LinearLayoutManager +import androidx.lifecycle.lifecycleScope import com.bumptech.glide.Glide import com.coldmint.rust.core.ModClass import com.coldmint.rust.core.dataBean.ModConfigurationData -import com.coldmint.rust.core.tool.DebugHelper import com.coldmint.rust.core.tool.FileOperator import com.coldmint.rust.pro.R import com.coldmint.rust.pro.adapters.ModActionAdapter import com.coldmint.rust.pro.adapters.ModAdapter import com.coldmint.rust.pro.base.BaseFragment -import com.coldmint.rust.pro.databinding.ModDialogBinding import com.coldmint.rust.pro.databinding.FragmentModBinding +import com.coldmint.rust.pro.databinding.ModDialogBinding import com.coldmint.rust.pro.databinding.ModListItemBinding import com.coldmint.rust.pro.tool.AppSettings import com.coldmint.rust.pro.tool.GlobalMethod -import com.coldmint.rust.pro.tool.Tools import com.coldmint.rust.pro.ui.StableLinearLayoutManager import com.coldmint.rust.pro.viewmodel.ModViewModel import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.divider.MaterialDividerItemDecoration import com.google.android.material.snackbar.Snackbar -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.isActive +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import me.zhanghai.android.fastscroll.FastScrollerBuilder import java.io.File class ModFragment : BaseFragment() { - val viewModel: ModViewModel by lazy { + private val viewModel: ModViewModel by lazy { ModViewModel() } - lateinit var modAdapter: ModAdapter - val needRecycling by lazy { + private lateinit var modAdapter: ModAdapter + private val needRecycling by lazy { if (GlobalMethod.isActive) { AppSettings.getValue( - AppSettings.Setting.EnableRecoveryStation, - true + AppSettings.Setting.EnableRecoveryStation, + true ) } else { false @@ -55,19 +52,16 @@ class ModFragment : BaseFragment() { /** * 删除文件 - * @param handler Handler * @param modClass ModClass */ - fun delFile( - handler: Handler, - modClass: ModClass, - index: Int? = null + private fun delFile( + modClass: ModClass, + index: Int? = null ) { - val scope = CoroutineScope(Job()) - scope.launch { + lifecycleScope.launch(Dispatchers.IO) { val targetFile = modClass.modFile val errorFolder = - File(AppSettings.dataRootDirectory + "/modErrorReport/" + modClass.modName) + File(AppSettings.dataRootDirectory + "/modErrorReport/" + modClass.modName) if (errorFolder.exists()) { FileOperator.delete_files(errorFolder) } @@ -75,7 +69,7 @@ class ModFragment : BaseFragment() { requireActivity().applicationContext.dataDir.absolutePath + "/databases/" } else { FileOperator.getSuperDirectory( - requireContext().cacheDir + requireContext().cacheDir ) + "/databases/" } val name = modClass.modName @@ -86,13 +80,13 @@ class ModFragment : BaseFragment() { shmFile.delete() walFile.delete() if (needRecycling) { - var result = false + val result: Boolean val removePath: String val removeFile: File if (targetFile.isDirectory) { removePath = AppSettings.getValue( - AppSettings.Setting.RecoveryStationFolder, - requireContext().filesDir.absolutePath + "/backup/" + AppSettings.Setting.RecoveryStationFolder, + requireContext().filesDir.absolutePath + "/backup/" ).toString() + targetFile.name + "/" removeFile = File(removePath) if (!removeFile.exists()) { @@ -100,71 +94,77 @@ class ModFragment : BaseFragment() { } } else { removePath = AppSettings.getValue( - AppSettings.Setting.RecoveryStationFolder, - requireContext().filesDir.absolutePath + "/backup/" + AppSettings.Setting.RecoveryStationFolder, + requireContext().filesDir.absolutePath + "/backup/" ).toString() + targetFile.name removeFile = File(removePath) } if (removeFile.exists()) { FileOperator.delete_files(removeFile) } - handler.post { + withContext(Dispatchers.Main) { Snackbar.make( - viewBinding.modList, - String.format( - getString(R.string.recoverying_prompt), - modClass.modName - ), - Snackbar.LENGTH_INDEFINITE + viewBinding.modList, + String.format( + getString(R.string.recoverying_prompt), + modClass.modName + ), + Snackbar.LENGTH_INDEFINITE ).show() } result = FileOperator.removeFiles(targetFile, removeFile) if (result) { - handler.post { + withContext(Dispatchers.Main) { Snackbar.make( - viewBinding.modList, - String.format( - requireContext().getString(R.string.recovery_prompt), - modClass.modName - ), - Snackbar.LENGTH_SHORT + viewBinding.modList, + String.format( + requireContext().getString(R.string.recovery_prompt), + modClass.modName + ), + Snackbar.LENGTH_SHORT ).show() if (index != null) { modAdapter.removeItem(index) + if (modAdapter.itemCount == 0) { + notFindMod() + } } } } else { - handler.post { + withContext(Dispatchers.Main) { Snackbar.make( - viewBinding.modList, - getString(R.string.cut_failed), - Snackbar.LENGTH_SHORT + viewBinding.modList, + getString(R.string.cut_failed), + Snackbar.LENGTH_SHORT ).show() } } } else { - handler.post { + withContext(Dispatchers.Main) { Snackbar.make( - viewBinding.modList, - String.format( - getString(R.string.del_moding_tip), - modClass.modName - ), - Snackbar.LENGTH_INDEFINITE + viewBinding.modList, + String.format( + getString(R.string.del_moding_tip), + modClass.modName + ), + Snackbar.LENGTH_INDEFINITE ).show() } FileOperator.delete_files(targetFile) - handler.post { + withContext(Dispatchers.Main) { Snackbar.make( - viewBinding.modList, - String.format( - getString(R.string.del_completed), - modClass.modName - ), - Snackbar.LENGTH_SHORT + viewBinding.modList, + String.format( + getString(R.string.del_completed), + modClass.modName + ), + Snackbar.LENGTH_SHORT ).show() if (index != null) { modAdapter.removeItem(index) + if (modAdapter.itemCount == 0) { + notFindMod() + } } } } @@ -175,53 +175,46 @@ class ModFragment : BaseFragment() { * 加载模组列表 */ fun loadModList() { - val scope = CoroutineScope(Job()) - val handler = Handler(Looper.getMainLooper()) - scope.launch { + lifecycleScope.launch(Dispatchers.IO) { val dataList = viewModel.loadMod() - handler.post { + withContext(Dispatchers.Main) { viewBinding.progressBar.isVisible = true viewBinding.modErrorIcon.isVisible = false viewBinding.modError.isVisible = false viewBinding.swipeRefreshLayout.isVisible = false } - if (dataList == null) { - handler.post { - viewBinding.modError.setText(R.string.not_find_mod) - viewBinding.modError.isVisible = true - viewBinding.modErrorIcon.isVisible = true - viewBinding.swipeRefreshLayout.isVisible = false - viewBinding.progressBar.isVisible = false + if (dataList.isNullOrEmpty()) { + withContext(Dispatchers.Main) { + notFindMod() } } else { - handler.post { + withContext(Dispatchers.Main) { viewBinding.swipeRefreshLayout.isVisible = true viewBinding.progressBar.isVisible = false viewBinding.modErrorIcon.isVisible = false viewBinding.modError.isVisible = false - if (isAdded) { - modAdapter = ModAdapter(requireContext(), dataList) - FastScrollerBuilder(viewBinding.modList).useMd2Style() - .setPopupTextProvider(modAdapter).build() - modAdapter.setItemEvent { i, modListItemBinding, viewHolder, modClass -> - modListItemBinding.root.setOnClickListener { - onClickItemWork(modListItemBinding, modClass) - } - modListItemBinding.root.setOnLongClickListener { - modAdapter.showDeleteItemDialog( - modClass.modName, - viewHolder.absoluteAdapterPosition, - onClickPositiveButton = { d, b -> - delFile(handler, modClass, viewHolder.absoluteAdapterPosition) - false - }) - false - } + modAdapter = ModAdapter(requireContext(), dataList) + FastScrollerBuilder(viewBinding.modList).useMd2Style() + .setPopupTextProvider(modAdapter).build() + modAdapter.setItemEvent { i, modListItemBinding, viewHolder, modClass -> + modListItemBinding.root.setOnClickListener { + onClickItemWork(modListItemBinding, modClass) + } + modListItemBinding.root.setOnLongClickListener { + modAdapter.showDeleteItemDialog( + modClass.modName, + viewHolder.absoluteAdapterPosition, + onClickPositiveButton = { d, b -> + delFile( + modClass, + viewHolder.absoluteAdapterPosition + ) + false + }) + false } - viewBinding.modList.adapter = modAdapter - } else { - DebugHelper.printLog("加载模组列表", "没有附加到活动", isError = true) } + viewBinding.modList.adapter = modAdapter } } } @@ -237,16 +230,14 @@ class ModFragment : BaseFragment() { fun onClickItemWork(viewBinding: ModListItemBinding, modClass: ModClass) { val context = requireContext() val modDialogBinding = - ModDialogBinding.inflate(LayoutInflater.from(context)) + ModDialogBinding.inflate(LayoutInflater.from(context)) val bottomSheetDialog = - BottomSheetDialog(context) - - + BottomSheetDialog(context) modDialogBinding.modNameView.text = viewBinding.modNameView.text modDialogBinding.modNameDescription.text = viewBinding.modIntroductionView.text val configurationManager = modClass.modConfigurationManager val configurationData: ModConfigurationData? = - configurationManager?.readData() + configurationManager?.readData() val works: MutableList = ArrayList() if (modClass.modFile.isDirectory) { if (GlobalMethod.isActive) { @@ -273,11 +264,11 @@ class ModFragment : BaseFragment() { } works.add(getString(R.string.share_mod)) val modActionAdapter = ModActionAdapter( - context, - works, - modClass.modFile.path, - this@ModFragment, - bottomSheetDialog + context, + works, + modClass.modFile.path, + this@ModFragment, + bottomSheetDialog ) if (configurationData != null) { modActionAdapter.setModConfigurationData(configurationData) @@ -287,13 +278,13 @@ class ModFragment : BaseFragment() { if (modClass.modIcon == null) { val drawable = context.getDrawable(R.drawable.image) modDialogBinding.modIcon.setImageDrawable( - GlobalMethod.tintDrawable( - drawable, ColorStateList.valueOf( - GlobalMethod.getColorPrimary( - requireContext() - ) - ) + GlobalMethod.tintDrawable( + drawable, ColorStateList.valueOf( + GlobalMethod.getColorPrimary( + requireContext() + ) ) + ) ) } else { Glide.with(requireContext()).load(modClass.modIcon).into(modDialogBinding.modIcon) @@ -301,17 +292,18 @@ class ModFragment : BaseFragment() { } else { val drawable = context.getDrawable(R.drawable.file) modDialogBinding.modIcon.setImageDrawable( - GlobalMethod.tintDrawable( - drawable, ColorStateList.valueOf( - GlobalMethod.getColorPrimary( - requireContext() - ) - ) + GlobalMethod.tintDrawable( + drawable, ColorStateList.valueOf( + GlobalMethod.getColorPrimary( + requireContext() + ) ) + ) ) } bottomSheetDialog.setContentView(modDialogBinding.root) - val bottomSheet = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet) + val bottomSheet = + bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet) if (bottomSheet != null) { val behavior = BottomSheetBehavior.from(bottomSheet) behavior.state = BottomSheetBehavior.STATE_EXPANDED // 默认展开 @@ -322,16 +314,16 @@ class ModFragment : BaseFragment() { bottomSheetDialog.show() } -// /** -// * 显示没有找到模组 -// */ -// fun showNotFindMod() { -// viewBinding.modError.setText(R.string.not_find_mod) -// viewBinding.modError.isVisible = true -// viewBinding.modErrorIcon.isVisible = true -// viewBinding.modList.isVisible = false -// viewBinding.progressBar.isVisible = false -// } + /** + * 显示没有找到模组 + */ + private fun notFindMod() { + viewBinding.modError.setText(R.string.not_find_mod) + viewBinding.modError.isVisible = true + viewBinding.modErrorIcon.isVisible = true + viewBinding.swipeRefreshLayout.isVisible = false + viewBinding.progressBar.isVisible = false + } override fun getViewBindingObject(layoutInflater: LayoutInflater): FragmentModBinding { return FragmentModBinding.inflate(layoutInflater) @@ -340,11 +332,11 @@ class ModFragment : BaseFragment() { override fun whenViewCreated(inflater: LayoutInflater, savedInstanceState: Bundle?) { viewBinding.modList.layoutManager = StableLinearLayoutManager(requireContext()) val divider = MaterialDividerItemDecoration( - requireContext(), - MaterialDividerItemDecoration.VERTICAL + requireContext(), + MaterialDividerItemDecoration.VERTICAL ) viewBinding.modList.addItemDecoration( - divider + divider ) viewBinding.swipeRefreshLayout.setOnRefreshListener { loadModList() diff --git a/app/src/main/java/com/coldmint/rust/pro/fragments/WarehouseFragment.kt b/app/src/main/java/com/coldmint/rust/pro/fragments/WarehouseFragment.kt index eff0eb0..12680a5 100644 --- a/app/src/main/java/com/coldmint/rust/pro/fragments/WarehouseFragment.kt +++ b/app/src/main/java/com/coldmint/rust/pro/fragments/WarehouseFragment.kt @@ -31,16 +31,13 @@ class WarehouseFragment : BaseFragment() { } }.attach() viewBinding.mainButton.setOnClickListener { - val intent = Intent(context, CreationWizardActivity::class.java) - intent.putExtra("type", "mod") - startActivity(intent) + startActivity(Intent(context, CreationWizardActivity::class.java)) } } } - override fun getViewBindingObject(layoutInflater: LayoutInflater): FragmentWarehouseBinding { - return FragmentWarehouseBinding.inflate(layoutInflater) - } + override fun getViewBindingObject(layoutInflater: LayoutInflater): FragmentWarehouseBinding = + FragmentWarehouseBinding.inflate(layoutInflater) override fun whenViewCreated(inflater: LayoutInflater, savedInstanceState: Bundle?) { viewBinding.pager.adapter = WarehouseAdapter(this) diff --git a/app/src/main/java/com/coldmint/rust/pro/ui/BottomSheet.kt b/app/src/main/java/com/coldmint/rust/pro/ui/BottomSheet.kt deleted file mode 100644 index 617d15e..0000000 --- a/app/src/main/java/com/coldmint/rust/pro/ui/BottomSheet.kt +++ /dev/null @@ -1,100 +0,0 @@ -package com.coldmint.rust.pro.ui - -import android.animation.Animator -import android.animation.AnimatorSet -import android.animation.ObjectAnimator -import android.annotation.SuppressLint -import android.content.Context -import android.util.AttributeSet -import android.view.animation.AccelerateDecelerateInterpolator -import androidx.core.animation.addListener -import androidx.interpolator.view.animation.FastOutSlowInInterpolator -import com.google.android.material.bottomsheet.BottomSheetDragHandleView -import android.view.MotionEvent as MotionEvent1 - -class BottomSheet(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : BottomSheetDragHandleView(context) { - - constructor(context: Context) : this(context, null) - constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) - - private var initialX = 0f - private var lastTouchX = 0f - private var deltaX = 0f - private val maxXOffset = 50f // 最大偏移量 - var isScaling = false - - - // 覆盖 onTouchEvent 方法以处理触摸事件 - @SuppressLint("ClickableViewAccessibility") - override fun onTouchEvent(event: MotionEvent1?): Boolean { - event?.let { - when (it.action) { - MotionEvent1.ACTION_DOWN -> { - // 触摸开始时的逻辑 - // 记录初始位置 - initialX = translationX - lastTouchX = event.rawX - // 触摸开始时放大 - - if (!isScaling) { - animate().scaleX(1.2f).scaleY(1.2f) - .setDuration(200) - .setInterpolator(FastOutSlowInInterpolator()) - .withLayer() - .start() - isScaling = true - - } - } - - MotionEvent1.ACTION_MOVE -> { - val dx = event.rawX - lastTouchX - val fl = initialX + dx - if (fl < maxXOffset && fl > -maxXOffset) { - translationX = fl - - } - } - - MotionEvent1.ACTION_UP, MotionEvent1.ACTION_CANCEL -> { - // 触摸结束时恢复大小和位置 - val animatorSet = AnimatorSet() - - // 恢复大小 - val scaleAnimator = ObjectAnimator.ofFloat(this, "scaleX", 1f) - scaleAnimator.duration = 200 - scaleAnimator.interpolator = AccelerateDecelerateInterpolator() - - val scaleYAnimator = ObjectAnimator.ofFloat(this, "scaleY", 1f) - scaleYAnimator.duration = 200 - scaleYAnimator.interpolator = AccelerateDecelerateInterpolator() - - // 恢复到原始位置 - val translationAnimator = ObjectAnimator.ofFloat(this, "translationX", 0f) - translationAnimator.duration = 200 - translationAnimator.interpolator = AccelerateDecelerateInterpolator() - - // 将所有动画添加到 AnimatorSet 中并启动 - animatorSet.playTogether(scaleAnimator, scaleYAnimator, translationAnimator) - animatorSet.start() - animatorSet.addListener(object : Animator.AnimatorListener { - override fun onAnimationStart(animation: Animator) {} - override fun onAnimationEnd(animation: Animator) { - isScaling = false - translationX = 0f - } - override fun onAnimationCancel(animation: Animator) {} - override fun onAnimationRepeat(animation: Animator) {} - }) - - } - - else -> { - // 其他事件处理 - } - } - } - // 返回 true 表示事件已经被消费,返回 false 表示事件没有被消费 - return true - } -} \ No newline at end of file diff --git a/app/src/main/res/layout/mod_dialog.xml b/app/src/main/res/layout/mod_dialog.xml index f9f1df0..f50c5b2 100644 --- a/app/src/main/res/layout/mod_dialog.xml +++ b/app/src/main/res/layout/mod_dialog.xml @@ -5,10 +5,9 @@ android:orientation="vertical" android:padding="8dp"> - + -