From 5ced42125c1eb47b37858aa34d24cdf2dd404cda Mon Sep 17 00:00:00 2001 From: Mygod Date: Mon, 15 Jan 2018 21:03:52 -0800 Subject: [PATCH] Implement ActionMode for CustomRulesFragment --- .../shadowsocks/acl/CustomRulesFragment.kt | 90 ++++++++++++------- .../main/res/drawable/ic_action_delete.xml | 3 +- .../res/drawable/ic_service_connected.xml | 4 +- .../res/drawable/ic_service_connecting.xml | 4 +- .../main/res/drawable/ic_service_stopped.xml | 4 +- .../main/res/drawable/ic_service_stopping.xml | 4 +- .../src/main/res/menu/custom_rules_menu.xml | 35 -------- .../main/res/menu/custom_rules_selection.xml | 33 +++++++ .../main/res/drawable/ic_navigation_close.xml | 3 +- plugin/src/main/res/values/styles.xml | 3 +- 10 files changed, 100 insertions(+), 83 deletions(-) create mode 100644 mobile/src/main/res/menu/custom_rules_selection.xml rename {mobile => plugin}/src/main/res/drawable/ic_navigation_close.xml (80%) diff --git a/mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt b/mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt index 64c511ce..c4dd8101 100644 --- a/mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt +++ b/mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt @@ -20,21 +20,21 @@ package com.github.shadowsocks.acl +import android.annotation.TargetApi import android.content.ClipData import android.content.ClipboardManager import android.content.Context +import android.os.Build import android.os.Bundle import android.support.design.widget.Snackbar +import android.support.v4.content.ContextCompat import android.support.v7.app.AlertDialog import android.support.v7.widget.DefaultItemAnimator import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.support.v7.widget.Toolbar import android.support.v7.widget.helper.ItemTouchHelper -import android.view.LayoutInflater -import android.view.MenuItem -import android.view.View -import android.view.ViewGroup +import android.view.* import android.widget.EditText import android.widget.Spinner import android.widget.TextView @@ -48,12 +48,13 @@ import com.github.shadowsocks.ToolbarFragment import com.github.shadowsocks.bg.BaseService import com.github.shadowsocks.utils.Subnet import com.github.shadowsocks.utils.asIterable +import com.github.shadowsocks.utils.resolveResourceId import com.github.shadowsocks.widget.UndoSnackbarManager import java.net.IDN import java.net.URL import java.util.* -class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { +class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener, ActionMode.Callback { companion object { private const val TEMPLATE_REGEX_DOMAIN = "(^|\\.)%s$" @@ -288,13 +289,12 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { private val selectedItems = HashSet() private val adapter by lazy { AclRulesAdapter() } private lateinit var list: RecyclerView - private var selectionItem: MenuItem? = null + private var mode: ActionMode? = null private lateinit var undoManager: UndoSnackbarManager private val clipboard by lazy { activity!!.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager } private fun onSelectedItemsUpdated() { - val selectionItem = selectionItem - if (selectionItem != null) selectionItem.isVisible = selectedItems.isNotEmpty() + if (selectedItems.isEmpty()) mode?.finish() else if (mode == null) mode = toolbar.startActionMode(this) } private fun createAclRuleDialog(item: Any = ""): Triple { @@ -345,9 +345,6 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { toolbar.setTitle(R.string.custom_rules) toolbar.inflateMenu(R.menu.custom_rules_menu) toolbar.setOnMenuItemClickListener(this) - val selectionItem = toolbar.menu.findItem(R.id.selection) - selectionItem.isVisible = selectedItems.isNotEmpty() - this.selectionItem = selectionItem list = view.findViewById(R.id.list) list.layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false) list.itemAnimator = DefaultItemAnimator() @@ -365,10 +362,9 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { } override fun onBackPressed(): Boolean { - return if (selectedItems.isNotEmpty()) { - selectedItems.clear() - onSelectedItemsUpdated() - adapter.notifyDataSetChanged() + val mode = mode + return if (mode != null) { + mode.finish() true } else super.onBackPressed() } @@ -395,24 +391,6 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { } override fun onMenuItemClick(item: MenuItem): Boolean = when (item.itemId) { - R.id.action_select_all -> { - adapter.selectAll() - true - } - R.id.action_cut -> { - copySelected() - adapter.removeSelected() - true - } - R.id.action_copy -> { - copySelected() - true - } - R.id.action_delete -> { - adapter.removeSelected() - true - } - R.id.action_manual_settings -> { val (templateSelector, editText, dialog) = createAclRuleDialog() dialog.setPositiveButton(android.R.string.ok, { _, _ -> @@ -444,4 +422,50 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { undoManager.flush() super.onDetach() } + + override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { + val activity = activity!! + val window = activity.window + // In the end material_grey_100 is used for background, see AppCompatDrawableManager (very complicated) + if (Build.VERSION.SDK_INT >= 23) { + window.statusBarColor = ContextCompat.getColor(activity, R.color.material_grey_300) + window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR + } else window.statusBarColor = ContextCompat.getColor(activity, R.color.material_grey_600) + activity.menuInflater.inflate(R.menu.custom_rules_selection, menu) + toolbar.touchscreenBlocksFocus = true + return true + } + override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean = false + override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean = when (item.itemId) { + R.id.action_select_all -> { + adapter.selectAll() + true + } + R.id.action_cut -> { + copySelected() + adapter.removeSelected() + true + } + R.id.action_copy -> { + copySelected() + true + } + R.id.action_delete -> { + adapter.removeSelected() + true + } + else -> false + } + override fun onDestroyActionMode(mode: ActionMode) { + val activity = activity!! + val window = activity.window + window.statusBarColor = ContextCompat.getColor(activity, + activity.theme.resolveResourceId(android.R.attr.statusBarColor)) + window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE + toolbar.touchscreenBlocksFocus = false + selectedItems.clear() + onSelectedItemsUpdated() + adapter.notifyDataSetChanged() + this.mode = null + } } diff --git a/mobile/src/main/res/drawable/ic_action_delete.xml b/mobile/src/main/res/drawable/ic_action_delete.xml index 89c372c3..0e9d1eb3 100644 --- a/mobile/src/main/res/drawable/ic_action_delete.xml +++ b/mobile/src/main/res/drawable/ic_action_delete.xml @@ -2,7 +2,8 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24.0" - android:viewportHeight="24.0"> + android:viewportHeight="24.0" + android:tint="?attr/colorControlNormal"> diff --git a/mobile/src/main/res/drawable/ic_service_connected.xml b/mobile/src/main/res/drawable/ic_service_connected.xml index f5ce5d49..18c89607 100644 --- a/mobile/src/main/res/drawable/ic_service_connected.xml +++ b/mobile/src/main/res/drawable/ic_service_connected.xml @@ -2,9 +2,7 @@ + android:drawable="@drawable/ic_service_busy"> + android:drawable="@drawable/ic_service_idle"> + android:drawable="@drawable/ic_service_idle"> + android:drawable="@drawable/ic_service_busy"> - - - - - - - - + + + + + + diff --git a/mobile/src/main/res/drawable/ic_navigation_close.xml b/plugin/src/main/res/drawable/ic_navigation_close.xml similarity index 80% rename from mobile/src/main/res/drawable/ic_navigation_close.xml rename to plugin/src/main/res/drawable/ic_navigation_close.xml index d11cc5c9..7caff12f 100644 --- a/mobile/src/main/res/drawable/ic_navigation_close.xml +++ b/plugin/src/main/res/drawable/ic_navigation_close.xml @@ -2,7 +2,8 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24.0" - android:viewportHeight="24.0"> + android:viewportHeight="24.0" + android:tint="?attr/colorControlNormal"> diff --git a/plugin/src/main/res/values/styles.xml b/plugin/src/main/res/values/styles.xml index 30a2ae47..e540a020 100644 --- a/plugin/src/main/res/values/styles.xml +++ b/plugin/src/main/res/values/styles.xml @@ -1,13 +1,14 @@