diff options
| author | 2022-12-19 09:02:11 -0800 | |
|---|---|---|
| committer | 2022-12-19 09:38:24 -0800 | |
| commit | 68163c09ae1bfd8ebeaabfd21b78650b2ede00df (patch) | |
| tree | 279d6db5a019c2492e0a5d9ea58ea4be096319ac /java/src | |
| parent | dc36b45b534e9f438de69238c8b762b7ff5c8d89 (diff) | |
A base scrollable action row implementation
A base implementation of the new scrollable action row; the view is
added to the codebase but not used.
Bug: 262278109
Test: Tested with some debug code injections (base functionality, a11y,
unit tests).
Change-Id: Ic109440ce9609e73b72fc86c2cd455c42a421103
Diffstat (limited to 'java/src')
| -rw-r--r-- | java/src/com/android/intentresolver/widget/ScrollableActionRow.kt | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/java/src/com/android/intentresolver/widget/ScrollableActionRow.kt b/java/src/com/android/intentresolver/widget/ScrollableActionRow.kt new file mode 100644 index 00000000..f3a34985 --- /dev/null +++ b/java/src/com/android/intentresolver/widget/ScrollableActionRow.kt @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.widget + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.android.intentresolver.R + +class ScrollableActionRow : RecyclerView, ActionRow { + constructor(context: Context) : this(context, null) + constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) + constructor( + context: Context, attrs: AttributeSet?, defStyleAttr: Int + ) : super(context, attrs, defStyleAttr) { + layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) + adapter = Adapter(context) + } + + private val actionsAdapter get() = adapter as Adapter + + override fun setActions(actions: List<ActionRow.Action>) { + actionsAdapter.setActions(actions) + } + + override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { + super.onLayout(changed, l, t, r, b) + setOverScrollMode( + if (areAllChildrenVisible) View.OVER_SCROLL_NEVER else View.OVER_SCROLL_ALWAYS + ) + } + + private val areAllChildrenVisible: Boolean + get() { + val count = getChildCount() + if (count == 0) return true + val first = getChildAt(0) + val last = getChildAt(count - 1) + return getChildAdapterPosition(first) == 0 + && getChildAdapterPosition(last) == actionsAdapter.itemCount - 1 + && isFullyVisible(first) + && isFullyVisible(last) + } + + private fun isFullyVisible(view: View): Boolean = + view.left >= paddingLeft && view.right <= width - paddingRight + + private class Adapter(private val context: Context) : RecyclerView.Adapter<ViewHolder>() { + private val iconSize: Int = + context.resources.getDimensionPixelSize(R.dimen.chooser_action_view_icon_size) + private val itemLayout = R.layout.chooser_action_view + private var actions: List<ActionRow.Action> = emptyList() + + override fun onCreateViewHolder(parent: ViewGroup, type: Int): ViewHolder = + ViewHolder( + LayoutInflater.from(context).inflate(itemLayout, null) as TextView, + iconSize + ) + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(actions[position]) + } + + override fun getItemCount() = actions.size + + override fun onViewRecycled(holder: ViewHolder) { + holder.unbind() + } + + override fun onFailedToRecycleView(holder: ViewHolder): Boolean { + holder.unbind() + return super.onFailedToRecycleView(holder) + } + + fun setActions(actions: List<ActionRow.Action>) { + this.actions = ArrayList(actions) + notifyDataSetChanged() + } + } + + private class ViewHolder( + private val view: TextView, private val iconSize: Int + ) : RecyclerView.ViewHolder(view) { + + fun bind(action: ActionRow.Action) { + if (action.icon != null) { + action.icon.setBounds(0, 0, iconSize, iconSize) + view.setCompoundDrawablesRelative(null, action.icon, null, null) + } + view.text = action.label ?: "" + view.setOnClickListener { + action.onClicked.run() + } + view.id = action.id + } + + fun unbind() { + view.setOnClickListener(null) + } + } +} |