Skip to content

Commit

Permalink
[skip ci] Better recyclerview
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr-TSNG committed Aug 10, 2022
1 parent 4784c44 commit 4077641
Show file tree
Hide file tree
Showing 23 changed files with 310 additions and 215 deletions.
2 changes: 1 addition & 1 deletion app/src/main/java/icu/nullptr/hidemyapplist/MyApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class MyApp : Application() {
val globalScope = CoroutineScope(Dispatchers.Default)
val appIconLoader by lazy {
val iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size)
AppIconLoader(iconSize, true, this)
AppIconLoader(iconSize, false, this)
}

@SuppressLint("SdCardPath")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,8 @@ object ConfigManager {
}
saveConfig()
}

fun isUsingHide(packageName: String): Boolean {
return config.scope.containsKey(packageName)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package icu.nullptr.hidemyapplist.ui.adapter

import android.view.ViewGroup
import icu.nullptr.hidemyapplist.service.ConfigManager
import icu.nullptr.hidemyapplist.ui.view.AppItemView

class AppManageAdapter : AppSelectAdapter() {

inner class ViewHolder(view: AppItemView) : AppSelectAdapter.ViewHolder(view) {
override fun bind(packageName: String) {
(itemView as AppItemView).let {
it.load(packageName)
it.showEnabled = ConfigManager.isUsingHide(packageName)
}
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = AppItemView(parent.context, false)
view.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
return ViewHolder(view)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package icu.nullptr.hidemyapplist.ui.adapter

import android.view.ViewGroup
import icu.nullptr.hidemyapplist.service.ConfigManager
import icu.nullptr.hidemyapplist.ui.view.AppItemView

class AppScopeAdapter(
filterOnlyEnabled: Boolean,
private val checked: MutableSet<String>
) : AppSelectAdapter(if (filterOnlyEnabled) ConfigManager::isUsingHide else null) {

private inline var String.isChecked
get() = checked.contains(this)
set(value) {
if (value) checked.add(this) else checked.remove(this)
}

inner class ViewHolder(view: AppItemView) : AppSelectAdapter.ViewHolder(view) {
init {
view.setOnClickListener {
val packageName = filteredList[absoluteAdapterPosition]
packageName.isChecked = !packageName.isChecked
view.isChecked = packageName.isChecked
}
}

override fun bind(packageName: String) {
(itemView as AppItemView).let {
it.load(packageName)
it.isChecked = packageName.isChecked
}
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = AppItemView(parent.context, true)
view.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
return ViewHolder(view)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package icu.nullptr.hidemyapplist.ui.adapter

import android.widget.Filter
import android.widget.Filterable
import androidx.recyclerview.widget.RecyclerView
import icu.nullptr.hidemyapplist.service.PrefManager
import icu.nullptr.hidemyapplist.ui.view.AppItemView
import icu.nullptr.hidemyapplist.util.PackageHelper
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking

abstract class AppSelectAdapter(
private val firstFilter: ((String) -> Boolean)? = null
) : RecyclerView.Adapter<AppSelectAdapter.ViewHolder>(), Filterable {

abstract class ViewHolder(view: AppItemView) : RecyclerView.ViewHolder(view) {
abstract fun bind(packageName: String)
}

private inner class AppFilter : Filter() {
override fun performFiltering(constraint: CharSequence): FilterResults {
return runBlocking {
val constraintLowered = constraint.toString().lowercase()
val filteredList = PackageHelper.appList.first().filter {
if (firstFilter?.invoke(it) == false) return@filter false
if (!PrefManager.filter_showSystem && PackageHelper.isSystem(it)) return@filter false
val label = PackageHelper.loadAppLabel(it)
val packageInfo = PackageHelper.loadPackageInfo(it)
label.lowercase().contains(constraintLowered) || packageInfo.packageName.lowercase().contains(constraintLowered)
}

FilterResults().also { it.values = filteredList }
}
}

@Suppress("UNCHECKED_CAST", "NotifyDataSetChanged")
override fun publishResults(constraint: CharSequence, results: FilterResults) {
filteredList = results.values as List<String>
notifyDataSetChanged()
}
}

private val mFilter = AppFilter()

protected var filteredList: List<String> = listOf()

override fun getItemCount() = filteredList.size

override fun getItemId(position: Int) = filteredList[position].hashCode().toLong()

override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(filteredList[position])

override fun getFilter(): Filter = mFilter
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
package icu.nullptr.hidemyapplist.ui.fragment

import androidx.fragment.app.Fragment
import com.tsng.hidemyapplist.R
import android.os.Bundle
import androidx.fragment.app.viewModels
import com.google.android.material.transition.MaterialSharedAxis
import icu.nullptr.hidemyapplist.service.ConfigManager
import icu.nullptr.hidemyapplist.ui.adapter.AppManageAdapter
import icu.nullptr.hidemyapplist.ui.viewmodel.AppSelectViewModel

class AppManageFragment : Fragment(R.layout.fragment_app_manage) {
class AppManageFragment : AppSelectFragment() {

override val viewModel by viewModels<AppSelectViewModel> {
AppSelectViewModel.Factory(
firstComparator = Comparator.comparing(ConfigManager::isUsingHide).reversed(),
adapter = AppManageAdapter()
)
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import android.view.MenuItem
import android.view.View
import androidx.activity.addCallback
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import by.kirich1409.viewbindingdelegate.viewBinding
import com.tsng.hidemyapplist.R
Expand All @@ -20,20 +17,12 @@ import icu.nullptr.hidemyapplist.ui.viewmodel.AppSelectViewModel
import icu.nullptr.hidemyapplist.util.PackageHelper
import kotlinx.coroutines.launch

class AppSelectFragment : Fragment(R.layout.fragment_app_select) {
abstract class AppSelectFragment : Fragment(R.layout.fragment_app_select) {

private val binding by viewBinding<FragmentAppSelectBinding>()
private val args by navArgs<AppSelectFragmentArgs>()
private val viewModel by viewModels<AppSelectViewModel> {
AppSelectViewModel.Factory(args)
}
protected abstract val viewModel: AppSelectViewModel

private fun onBack() {
if (viewModel.isMultiSelect) {
setFragmentResult("app_select", Bundle().apply {
putStringArrayList("checked", ArrayList(viewModel.checked))
})
}
protected open fun onBack() {
navController.navigateUp()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.view.View
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.FragmentNavigatorExtras
import by.kirich1409.viewbindingdelegate.viewBinding
import com.google.android.gms.ads.AdRequest
import com.google.android.material.transition.MaterialElevationScale
import com.tsng.hidemyapplist.BuildConfig
import com.tsng.hidemyapplist.R
Expand All @@ -26,14 +27,13 @@ class HomeFragment : Fragment(R.layout.fragment_home) {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setupToolbar(binding.toolbar, getString(R.string.app_name))
// binding.adBanner.loadAd(AdRequest.Builder().build())
binding.adBanner.loadAd(AdRequest.Builder().build())
binding.templateManage.setOnClickListener {
val extras = FragmentNavigatorExtras(binding.manageCard to "transition_manage")
navController.navigate(R.id.nav_template_manage, null, null, extras)
}
binding.appManage.setOnClickListener {
val extras = FragmentNavigatorExtras(binding.manageCard as View to "transition_manage")
navController.navigate(R.id.nav_app_manage, null, null, extras)
navController.navigate(R.id.nav_app_manage)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package icu.nullptr.hidemyapplist.ui.fragment

import android.os.Bundle
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.navArgs
import icu.nullptr.hidemyapplist.ui.adapter.AppScopeAdapter
import icu.nullptr.hidemyapplist.ui.util.navController
import icu.nullptr.hidemyapplist.ui.viewmodel.AppSelectViewModel

class ScopeFragment : AppSelectFragment() {

private lateinit var checked: MutableSet<String>

override val viewModel by viewModels<AppSelectViewModel> {
val args by navArgs<ScopeFragmentArgs>()
checked = args.checked.toMutableSet()
AppSelectViewModel.Factory(
firstComparator = Comparator.comparing { !checked.contains(it) },
adapter = AppScopeAdapter(args.filterOnlyEnabled, checked)
)
}

override fun onBack() {
setFragmentResult("app_select", Bundle().apply {
putStringArrayList("checked", ArrayList(checked))
})
navController.navigateUp()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.*
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.navArgs
import by.kirich1409.viewbindingdelegate.viewBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.transition.MaterialContainerTransform
Expand All @@ -23,7 +24,10 @@ import kotlinx.coroutines.launch
class TemplateSettingsFragment : Fragment(R.layout.fragment_template_settings) {

private val binding by viewBinding<FragmentTemplateSettingsBinding>()
private val viewModel by viewModels<TemplateSettingsViewModel>()
private val args by navArgs<TemplateSettingsFragmentArgs>()
private val viewModel by viewModels<TemplateSettingsViewModel>() {
TemplateSettingsViewModel.Factory(args)
}

private fun onBack() {
viewModel.name = viewModel.name?.trim()
Expand All @@ -49,15 +53,6 @@ class TemplateSettingsFragment : Fragment(R.layout.fragment_template_settings) {
drawingViewId = R.id.nav_host_fragment
scrimColor = Color.TRANSPARENT
}

val args = TemplateSettingsFragmentArgs.fromBundle(requireArguments())
args.name?.let {
viewModel.name = it
viewModel.originalName = it
viewModel.appliedAppList.value = ConfigManager.getTemplateAppliedAppList(it)
viewModel.targetAppList.value = ConfigManager.getTemplateTargetAppList(it)
}
viewModel.isWhiteList = args.isWhiteList
}

override fun onGetLayoutInflater(savedInstanceState: Bundle?): LayoutInflater {
Expand Down Expand Up @@ -87,8 +82,7 @@ class TemplateSettingsFragment : Fragment(R.layout.fragment_template_settings) {
viewModel.targetAppList.value = bundle.getStringArrayList("checked")!!
clearFragmentResultListener("app_select")
}
val selectArgs = AppSelectFragmentArgs(
isMultiSelect = true,
val selectArgs = ScopeFragmentArgs(
filterOnlyEnabled = false,
checked = viewModel.targetAppList.value.toTypedArray()
)
Expand All @@ -99,8 +93,7 @@ class TemplateSettingsFragment : Fragment(R.layout.fragment_template_settings) {
viewModel.appliedAppList.value = bundle.getStringArrayList("checked")!!
clearFragmentResultListener("app_select")
}
val selectArgs = AppSelectFragmentArgs(
isMultiSelect = true,
val selectArgs = ScopeFragmentArgs(
filterOnlyEnabled = true,
checked = viewModel.appliedAppList.value.toTypedArray()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import android.widget.LinearLayout
import by.kirich1409.viewbindingdelegate.CreateMethod
import by.kirich1409.viewbindingdelegate.viewBinding
import com.tsng.hidemyapplist.databinding.AppItemViewBinding
import icu.nullptr.hidemyapplist.hmaApp
import icu.nullptr.hidemyapplist.util.PackageHelper

class AppItemView @JvmOverloads constructor(
Expand Down Expand Up @@ -37,6 +36,6 @@ class AppItemView @JvmOverloads constructor(
fun load(packageName: String) {
binding.packageName.text = packageName
binding.label.text = PackageHelper.loadAppLabel(packageName)
binding.icon.setImageBitmap(hmaApp.appIconLoader.loadIcon(PackageHelper.loadPackageInfo(packageName).applicationInfo))
binding.icon.setImageBitmap(PackageHelper.loadAppIcon(packageName))
}
}
Loading

0 comments on commit 4077641

Please sign in to comment.