From dad52724db29e34e21d487d6d489fde7d58e8e24 Mon Sep 17 00:00:00 2001 From: Viktor De Pasquale Date: Sat, 2 Nov 2019 18:12:22 +0100 Subject: [PATCH] Updated hide fragment with more robust filtering UI --- .../magisk/redesign/hide/HideFragment.kt | 17 +- .../magisk/redesign/hide/HideViewModel.kt | 46 ++++-- .../magisk/utils/DataBindingAdapters.kt | 19 +++ app/src/main/res/drawable/ic_filter.xml | 12 ++ app/src/main/res/drawable/ic_search_md2.xml | 18 +++ app/src/main/res/drawable/ic_up_md2.xml | 10 ++ app/src/main/res/layout/fragment_hide_md2.xml | 149 ++++++++++++++++-- app/src/main/res/menu/menu_hide_md2.xml | 9 -- app/src/main/res/values/strings_md2.xml | 2 + 9 files changed, 242 insertions(+), 40 deletions(-) create mode 100644 app/src/main/res/drawable/ic_filter.xml create mode 100644 app/src/main/res/drawable/ic_search_md2.xml create mode 100644 app/src/main/res/drawable/ic_up_md2.xml delete mode 100644 app/src/main/res/menu/menu_hide_md2.xml diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideFragment.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideFragment.kt index 9ddf7452f..a42f2e9b4 100644 --- a/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideFragment.kt @@ -2,9 +2,8 @@ package com.topjohnwu.magisk.redesign.hide import android.content.Context import android.graphics.Insets -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem +import android.os.Bundle +import android.view.View import com.topjohnwu.magisk.R import com.topjohnwu.magisk.databinding.FragmentHideMd2Binding import com.topjohnwu.magisk.redesign.compat.CompatFragment @@ -20,16 +19,14 @@ class HideFragment : CompatFragment() { override fun onAttach(context: Context) { super.onAttach(context) activity.setTitle(R.string.magiskhide) - setHasOptionsMenu(true) } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.menu_hide_md2, menu) - menu.findItem(R.id.action_show_system)?.isChecked = viewModel.isShowSystem - } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return viewModel.menuItemPressed(item) + binding.hideActionScrollUp.setOnClickListener { + binding.hideScrollContainer.fullScroll(View.FOCUS_UP) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideViewModel.kt index 15927cf7d..260d34313 100644 --- a/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideViewModel.kt @@ -1,12 +1,14 @@ package com.topjohnwu.magisk.redesign.hide import android.content.pm.ApplicationInfo -import android.view.MenuItem +import android.os.Handler +import android.os.Looper +import androidx.databinding.Bindable import com.topjohnwu.magisk.BR -import com.topjohnwu.magisk.R import com.topjohnwu.magisk.data.repository.MagiskRepository import com.topjohnwu.magisk.databinding.ComparableRvItem import com.topjohnwu.magisk.extensions.subscribeK +import com.topjohnwu.magisk.extensions.toggle import com.topjohnwu.magisk.model.entity.HideAppInfo import com.topjohnwu.magisk.model.entity.HideTarget import com.topjohnwu.magisk.model.entity.ProcessHideApp @@ -19,18 +21,31 @@ import com.topjohnwu.magisk.utils.DiffObservableList import com.topjohnwu.magisk.utils.FilterableDiffObservableList import com.topjohnwu.magisk.utils.KObservableField import com.topjohnwu.magisk.utils.currentLocale +import io.reactivex.Single +import io.reactivex.android.schedulers.AndroidSchedulers class HideViewModel( private val magiskRepo: MagiskRepository ) : CompatViewModel() { + private val queryHandler = Handler(Looper.getMainLooper()) + private val queryRunnable = Runnable { query() } + var isShowSystem = false + @Bindable get set(value) { field = value + notifyPropertyChanged(BR.showSystem) query() } - val query = KObservableField("") + var query = "" + @Bindable get + set(value) { + field = value + notifyPropertyChanged(BR.query) + submitQuery() + } val items = filterableListOf() val itemBinding = itemBindingOf { it.bindExtra(BR.viewModel, this) @@ -39,6 +54,8 @@ class HideViewModel( it.bindExtra(BR.viewModel, this) } + val isFilterExpanded = KObservableField(false) + override fun refresh() = magiskRepo.fetchApps() .map { it to magiskRepo.fetchHideTargets().blockingGet() } .map { pair -> pair.first.map { mergeAppTargets(it, pair.second) } } @@ -70,8 +87,13 @@ class HideViewModel( // --- + private fun submitQuery() { + queryHandler.removeCallbacks(queryRunnable) + queryHandler.postDelayed(queryRunnable, 1000) + } + private fun query( - query: String = this.query.value, + query: String = this.query, showSystem: Boolean = isShowSystem ) = items.filter { fun filterSystem(): Boolean { @@ -90,18 +112,22 @@ class HideViewModel( // --- - fun menuItemPressed(menuItem: MenuItem) = when (menuItem.itemId) { - R.id.action_show_system -> isShowSystem = (!menuItem.isChecked) - .also { menuItem.isChecked = it } - else -> null - }?.let { true } ?: false - fun toggleItem(item: HideProcessItem) = magiskRepo .toggleHide(item.isHidden.value, item.item.packageName, item.item.name) // might wanna reorder the list to display the item at the top .subscribeK() .add() + fun toggle(item: KObservableField) = item.toggle() + + fun resetQuery() { + query = "" + } + + fun hideFilter() { + isFilterExpanded.value = false + } + } inline fun > filterableListOf( diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt b/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt index 7e8a4dee2..3eaec43fa 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt +++ b/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt @@ -15,6 +15,7 @@ import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.Toolbar import androidx.core.animation.doOnEnd import androidx.core.view.* +import androidx.core.widget.NestedScrollView import androidx.databinding.BindingAdapter import androidx.databinding.InverseBindingAdapter import androidx.databinding.InverseBindingListener @@ -26,6 +27,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.viewpager.widget.ViewPager import com.google.android.material.button.MaterialButton import com.google.android.material.card.MaterialCardView +import com.google.android.material.chip.Chip import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.navigation.NavigationView import com.google.android.material.textfield.TextInputLayout @@ -410,4 +412,21 @@ fun Toolbar.setOnMenuClickListener(listener: Toolbar.OnMenuItemClickListener) { @BindingAdapter("tooltipText") fun View.setTooltipTextCompat(text: String) { ViewCompat.setTooltipText(this, text) +} + +@BindingAdapter("onCloseClicked") +fun Chip.setOnCloseClickedListenerBinding(listener: View.OnClickListener) { + setOnCloseIconClickListener(listener) +} + +@BindingAdapter("onScrollStateChanged") +fun NestedScrollView.setOnScrollStateChangeListener(listener: Runnable) { + setOnScrollChangeListener { _: NestedScrollView?, _: Int, _: Int, _: Int, _: Int -> + if (!handler.hasCallbacks(listener)) { + listener.run() + } else { + handler.removeCallbacksAndMessages(null) + } + handler.postDelayed(listener, 1000) + } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_filter.xml b/app/src/main/res/drawable/ic_filter.xml new file mode 100644 index 000000000..f327b4a79 --- /dev/null +++ b/app/src/main/res/drawable/ic_filter.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_search_md2.xml b/app/src/main/res/drawable/ic_search_md2.xml new file mode 100644 index 000000000..626a6c3ce --- /dev/null +++ b/app/src/main/res/drawable/ic_search_md2.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_up_md2.xml b/app/src/main/res/drawable/ic_up_md2.xml new file mode 100644 index 000000000..60b1ea4b8 --- /dev/null +++ b/app/src/main/res/drawable/ic_up_md2.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_hide_md2.xml b/app/src/main/res/layout/fragment_hide_md2.xml index e9619e9c6..7084e8adf 100644 --- a/app/src/main/res/layout/fragment_hide_md2.xml +++ b/app/src/main/res/layout/fragment_hide_md2.xml @@ -17,22 +17,137 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + tools:paddingTop="40dp"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_hide_md2.xml b/app/src/main/res/menu/menu_hide_md2.xml deleted file mode 100644 index 9514ec2bc..000000000 --- a/app/src/main/res/menu/menu_hide_md2.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/values/strings_md2.xml b/app/src/main/res/values/strings_md2.xml index 71c9a28fd..d08aa471a 100644 --- a/app/src/main/res/values/strings_md2.xml +++ b/app/src/main/res/values/strings_md2.xml @@ -79,4 +79,6 @@ Toggles “toast” notifications Revoke + Filter by name + \ No newline at end of file