【Android】用Kotlin方式使用ActionMode

ActionMode


ActionMode模式为在页面产生一个悬浮的类似于ActionBar的控件,悬浮在ActionBar之上,可以在不占用页面空间的情况下增加功能入口。ActionMode有两种模式

  1. Primary Action :控件覆盖出现在上方ActionBar之上
  2. Floating Action:控件浮动出现在任意View的四周
Primary Action Floating Action

启动方式


通过Activity或者View的startActionMode方法启动,并接受两个参数:ActionMode.CallbackActionMode.Type

public ActionMode startActionMode(android.view.ActionMode.Callback callback, int type)

ActionMode.Callback定义了ActionMode的生命周期回调:

public interface Callback {
    
    
    // AcionMode创建
    boolean onCreateActionMode(ActionMode var1, Menu var2);

    // AcionMode状态变化时(无效、或者项目更新)
    boolean onPrepareActionMode(ActionMode var1, Menu var2);

    // AcionMode菜单项被选中时
    boolean onActionItemClicked(ActionMode var1, MenuItem var2);

    // AcionMode销毁
    void onDestroyActionMode(ActionMode var1);
}

ActionMode.Type定义了前面介绍的两种ActionMode类型

public abstract class ActionMode {
    
    
    public static final int TYPE_FLOATING = 1;
    public static final int TYPE_PRIMARY = 0;}

封装ActionModeController


我们封装ActionModeController类,简化ActionMode使用体验

class ActionModeController(
    // menu的resId
    @MenuRes private val resId: Int,
    // ActionMode 类型
    private val type: Int,
    // menu选择后回调
    private val onAction : (MenuItem) -> Unit
) {
    
    
    // 从Activiy启动
    fun startActionMode(activity: Activity) {
    
    
        activity.startActionMode(createActionModeCallback(), type)
    }

    // 从View启动
    fun startActionMode(view: View) {
    
    
        view.startActionMode(createActionModeCallback(), type)
    }

    private fun createActionModeCallback(): ActionMode.Callback {
    
    
        return object: ActionMode.Callback {
    
    
            override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
    
    
                mode.menuInflater.inflate(resId, menu)
                return true
            }

            override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
    
    
                return false
            }

            override fun onDestroyActionMode(mode: ActionMode) {
    
    
            }

            override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
    
    
                onAction.invoke(item)

                mode.finish()
                return true
            }
        }
    }
}

接下来实际看一下使用效果

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/first"
        android:title="@string/first"
        android:icon="@drawable/ic_done"
        />

    <item
        android:id="@+id/second"
        android:title="@string/second"
        android:icon="@drawable/ic_close"
        />
</menu>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    tools:context=".MainFragment"
    android:orientation="vertical">

        <Button
            android:id="@+id/primary_action_mode_activity_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="PRIMARY ACTION MODE (ACTIVITY)"/>

        <Button
            android:id="@+id/primary_action_mode_view_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="PRIMARY ACTION MODE (VIEW)"/>

        <Button
            android:id="@+id/floating_action_mode_activity_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="FLOATING ACTION MODE (ACTIVITY)"/>

        <Button
            android:id="@+id/floating_action_mode_view_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="FLOATING ACTION MODE (VIEW)"/>
</LinearLayout>

class MainFragment : Fragment(R.layout.fragment_main) {
    
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    
    
        super.onViewCreated(view, savedInstanceState)

		// Primary Action
        val primaryActionModeController = ActionModeController(R.menu.action_menus, ActionMode.TYPE_PRIMARY) {
    
    

            when (it.itemId) {
    
    
                R.id.first -> {
    
    
                    Toast.makeText(context, "FIRST", Toast.LENGTH_SHORT).show()
                }
                R.id.second -> {
    
    
                    Toast.makeText(context, "SECOND", Toast.LENGTH_SHORT).show()
                }
            }
        }

        // Floating Action 
        val floatingActionModeController = ActionModeController(R.menu.action_menus, ActionMode.TYPE_FLOATING) {
    
    
            when (it.itemId) {
    
    
                R.id.first -> {
    
    
                    Toast.makeText(context, "FIRST", Toast.LENGTH_SHORT).show()
                }
                R.id.second -> {
    
    
                    Toast.makeText(context, "SECOND", Toast.LENGTH_SHORT).show()
                }
            }
        }

        // Activity 启动 Primary Action
        primary_action_mode_activity_button.setOnClickListener {
    
    
            primaryActionModeController.startActionMode(requireActivity())
        }

        // View 启动 Primary Action
        primary_action_mode_view_button.setOnClickListener {
    
    
            primaryActionModeController.startActionMode(it)
        }

        // Activity 启动 Floating Action
        floating_action_mode_activity_button.setOnClickListener {
    
    
            floatingActionModeController.startActionMode(requireActivity())
        }

        // View 启动 Floating Action
        floating_action_mode_view_button.setOnClickListener {
    
    
            floatingActionModeController.startActionMode(it)
        }
    }
}

在这里插入图片描述


更加Kotlin范儿的封装


ActionModeController适合在Java或者Kotlin中使用,如果我们只面向Kotlin使用,可以在ActionModeController基础上,分装的更加Kotlin范儿:

fun Activity.startActionMode(@MenuRes resId: Int, type: Int, onAction: (MenuItem) -> Unit) =
    ActionModeController(resId, type, onAction).startActionMode(this)

通过扩展函数,完全隐去了对ActionModeController的定义和调用,非常简洁。

猜你喜欢

转载自blog.csdn.net/vitaviva/article/details/108936869