6.7.0 - Alpha19 - 主页抽屉添加开关分隔线以增强视觉体验

This commit is contained in:
SuperMonster003
2026-02-12 17:52:57 +08:00
parent 0cd4435d2f
commit 5240084b00
6 changed files with 316 additions and 22 deletions

View File

@@ -151,7 +151,7 @@
"崩溃报告页面支持双指缩放调整字体大小并添加常用功能按钮", "崩溃报告页面支持双指缩放调整字体大小并添加常用功能按钮",
"应用启动器图标支持自适应图标特性 _[`issue #405`](http://issues.autojs6.com/405)_", "应用启动器图标支持自适应图标特性 _[`issue #405`](http://issues.autojs6.com/405)_",
"Rhino 引擎在泛型签名解析失败时回退为原始反射类型以增强低版本安卓系统的反射方法可用性", "Rhino 引擎在泛型签名解析失败时回退为原始反射类型以增强低版本安卓系统的反射方法可用性",
"主页抽屉开关类条目支持点击标题文字区域显示详情对话框并按需支持快捷跳转系统设置", "主页抽屉开关类条目添加分隔线, 支持点击标题文字区域显示详情对话框并按需支持快捷跳转系统设置",
"启动或重启 AutoJs6 时支持点击主页抽屉 \"客户端模式\" 标题文字区域中止正在尝试建立的连接", "启动或重启 AutoJs6 时支持点击主页抽屉 \"客户端模式\" 标题文字区域中止正在尝试建立的连接",
"客户端模式连接时支持使用 IPv6 地址及域名地址建立连接", "客户端模式连接时支持使用 IPv6 地址及域名地址建立连接",
"客户端模式连接时支持特殊用途 IPv4 地址 (回环/广播/多播/保留/...) 检测提示", "客户端模式连接时支持特殊用途 IPv4 地址 (回环/广播/多播/保留/...) 检测提示",

View File

@@ -6,6 +6,7 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
@@ -726,7 +727,6 @@ open class DrawerFragment : Fragment() {
drawerStatsDisposables.add(historyDisposable) drawerStatsDisposables.add(historyDisposable)
} }
private fun configureDrawerWidth() { private fun configureDrawerWidth() {
val screenWidthDp = resources.configuration.screenWidthDp val screenWidthDp = resources.configuration.screenWidthDp
val targetWidthPx = 288f.coerceIn( val targetWidthPx = 288f.coerceIn(
@@ -741,6 +741,40 @@ open class DrawerFragment : Fragment() {
binding.pluginCenter.setOnClickListener { PluginCenterActivity.startActivity(it.context) } binding.pluginCenter.setOnClickListener { PluginCenterActivity.startActivity(it.context) }
binding.restart.setOnClickListener { restart(mActivity, mActivity::beforeExit) } binding.restart.setOnClickListener { restart(mActivity, mActivity::beforeExit) }
binding.exit.setOnClickListener { exit(mActivity, mActivity::beforeExit) } binding.exit.setOnClickListener { exit(mActivity, mActivity::beforeExit) }
// Consume touches on drawer blank area to prevent "press state" leaking to RecyclerView items.
// zh-CN: 消费抽屉空白区域触摸, 防止按压状态影响 RecyclerView item 的 ripple/pressed 表现.
binding.drawerMenuContainer.setOnTouchListener { v, ev ->
val rv = binding.drawerMenu
val buttonsRow = binding.settings.parent as? View
fun hitTest(target: View?): Boolean {
if (target == null) return false
val loc = IntArray(2)
target.getLocationOnScreen(loc)
val left = loc[0]
val top = loc[1]
val right = left + target.width
val bottom = top + target.height
val x = ev.rawX.toInt()
val y = ev.rawY.toInt()
return x in left until right && y in top until bottom
}
val onRecycler = hitTest(rv)
val onButtons = hitTest(buttonsRow)
if (onRecycler || onButtons) {
false
} else {
// Keep container from staying pressed.
// zh-CN: 避免容器保持 pressed 状态.
if (ev.actionMasked == MotionEvent.ACTION_DOWN) {
v.isPressed = false
}
true
}
}
} }
override fun onResume() { override fun onResume() {

View File

@@ -7,6 +7,7 @@ import androidx.core.view.isVisible
import me.zhanghai.android.materialprogressbar.MaterialProgressBar import me.zhanghai.android.materialprogressbar.MaterialProgressBar
import org.autojs.autojs.ui.widget.BindableViewHolder import org.autojs.autojs.ui.widget.BindableViewHolder
import org.autojs.autojs.ui.widget.PrefSwitch import org.autojs.autojs.ui.widget.PrefSwitch
import org.autojs.autojs.util.ViewUtils.installFullRowRippleForwarder
import org.autojs.autojs6.databinding.DrawerMenuItemBinding import org.autojs.autojs6.databinding.DrawerMenuItemBinding
/** /**
@@ -17,6 +18,7 @@ import org.autojs.autojs6.databinding.DrawerMenuItemBinding
class DrawerMenuItemViewHolder(itemView: View) : BindableViewHolder<DrawerMenuItem?>(itemView) { class DrawerMenuItemViewHolder(itemView: View) : BindableViewHolder<DrawerMenuItem?>(itemView) {
private val mSwitchCompat: PrefSwitch private val mSwitchCompat: PrefSwitch
private val mSwitchDivider: View
private val mProgressBar: MaterialProgressBar private val mProgressBar: MaterialProgressBar
private val mIcon: ImageView private val mIcon: ImageView
private val mTitle: TextView private val mTitle: TextView
@@ -30,6 +32,7 @@ class DrawerMenuItemViewHolder(itemView: View) : BindableViewHolder<DrawerMenuIt
init { init {
val binding = DrawerMenuItemBinding.bind(itemView) val binding = DrawerMenuItemBinding.bind(itemView)
mSwitchCompat = binding.sw mSwitchCompat = binding.sw
mSwitchDivider = binding.switchDivider
mProgressBar = binding.progressBar mProgressBar = binding.progressBar
mIcon = binding.icon mIcon = binding.icon
mTitle = binding.title mTitle = binding.title
@@ -38,6 +41,13 @@ class DrawerMenuItemViewHolder(itemView: View) : BindableViewHolder<DrawerMenuIt
onClick() onClick()
} }
val iconContainer = binding.iconContainer
val titleContainer = binding.titleContainer
// Install full-row ripple forwarding once.
// zh-CN: 安装整行 Ripple 转发, 通常只需安装一次.
installFullRowRippleForwarder(itemView, iconContainer, titleContainer)
val toggleAction = { val toggleAction = {
if (mSwitchCompat.isVisible) { if (mSwitchCompat.isVisible) {
mSwitchCompat.toggle() mSwitchCompat.toggle()
@@ -46,11 +56,11 @@ class DrawerMenuItemViewHolder(itemView: View) : BindableViewHolder<DrawerMenuIt
} }
} }
binding.iconContainer.setOnClickListener { iconContainer.setOnClickListener {
toggleAction() toggleAction()
} }
binding.iconContainer.setOnLongClickListener { iconContainer.setOnLongClickListener {
when (val menuItem = mDrawerMenuItem) { when (val menuItem = mDrawerMenuItem) {
is DrawerMenuToggleableItem -> { is DrawerMenuToggleableItem -> {
menuItem.launchManagerIfPossible() menuItem.launchManagerIfPossible()
@@ -59,7 +69,7 @@ class DrawerMenuItemViewHolder(itemView: View) : BindableViewHolder<DrawerMenuIt
} }
} }
binding.titleContainer.setOnClickListener { titleContainer.setOnClickListener {
when (val menuItem = mDrawerMenuItem) { when (val menuItem = mDrawerMenuItem) {
is DrawerMenuToggleableItem -> { is DrawerMenuToggleableItem -> {
menuItem.onTitleContainerClick() menuItem.onTitleContainerClick()
@@ -68,7 +78,7 @@ class DrawerMenuItemViewHolder(itemView: View) : BindableViewHolder<DrawerMenuIt
} }
} }
binding.titleContainer.setOnLongClickListener { titleContainer.setOnLongClickListener {
when (val menuItem = mDrawerMenuItem) { when (val menuItem = mDrawerMenuItem) {
is DrawerMenuToggleableItem -> { is DrawerMenuToggleableItem -> {
menuItem.launchManagerIfPossible() menuItem.launchManagerIfPossible()
@@ -98,9 +108,11 @@ class DrawerMenuItemViewHolder(itemView: View) : BindableViewHolder<DrawerMenuIt
private fun setSwitch(item: DrawerMenuItem) { private fun setSwitch(item: DrawerMenuItem) {
if (!item.isSwitchEnabled) { if (!item.isSwitchEnabled) {
mSwitchCompat.visibility = View.GONE mSwitchCompat.visibility = View.GONE
mSwitchDivider.visibility = View.GONE
return return
} }
mSwitchCompat.visibility = View.VISIBLE mSwitchCompat.visibility = View.VISIBLE
mSwitchDivider.visibility = View.VISIBLE
val prefKey = item.prefKey val prefKey = item.prefKey
if (prefKey == DrawerMenuItem.DEFAULT_PREFERENCE_KEY) { if (prefKey == DrawerMenuItem.DEFAULT_PREFERENCE_KEY) {
mSwitchCompat.setChecked(item.isChecked, false) mSwitchCompat.setChecked(item.isChecked, false)

View File

@@ -32,8 +32,10 @@ import android.util.DisplayMetrics
import android.util.TypedValue import android.util.TypedValue
import android.view.Gravity import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MotionEvent
import android.view.ScaleGestureDetector import android.view.ScaleGestureDetector
import android.view.View import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
@@ -72,6 +74,7 @@ import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.theme.ThemeColorManager import org.autojs.autojs.theme.ThemeColorManager
import org.autojs.autojs.util.StringUtils.key import org.autojs.autojs.util.StringUtils.key
import org.autojs.autojs6.R import org.autojs.autojs6.R
import kotlin.math.abs
import kotlin.math.floor import kotlin.math.floor
import kotlin.math.min import kotlin.math.min
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -388,7 +391,7 @@ object ViewUtils {
* - 以 Type.navigationBars() 为主来源. * - 以 Type.navigationBars() 为主来源.
* - ignoreVisibility=true 时使用 "忽略可见性" 的 insets, 即使系统栏被隐藏也尽量返回稳定厚度. * - ignoreVisibility=true 时使用 "忽略可见性" 的 insets, 即使系统栏被隐藏也尽量返回稳定厚度.
* - ignoreVisibility=false 时使用 "可见" 的 insets, 反映当前可见状态. * - ignoreVisibility=false 时使用 "可见" 的 insets, 反映当前可见状态.
* 2. computed(显示差值法), 可选. * 2. computed (显示差值法), 可选.
* - 仅在 withComputed=true 且 pre-Android R 或 window==null 时启用. * - 仅在 withComputed=true 且 pre-Android R 或 window==null 时启用.
* - 通过 real metrics 与 usable metrics 的差值计算系统 UI insets, 再推导导航栏厚度. * - 通过 real metrics 与 usable metrics 的差值计算系统 UI insets, 再推导导航栏厚度.
* 3. 内部 dimen, 可选. * 3. 内部 dimen, 可选.
@@ -846,6 +849,7 @@ object ViewUtils {
// zh-CN: // zh-CN:
// 如果 view 未 attach 时调用 requestApplyInsets() 会被丢弃. // 如果 view 未 attach 时调用 requestApplyInsets() 会被丢弃.
// 需要等 attach 后再请求一次, 才能稳定触发 insets 分发. // 需要等 attach 后再请求一次, 才能稳定触发 insets 分发.
@Suppress("DEPRECATION")
private fun View.requestApplyInsetsWhenAttached() { private fun View.requestApplyInsetsWhenAttached() {
if (ViewCompat.isAttachedToWindow(this)) { if (ViewCompat.isAttachedToWindow(this)) {
ViewCompat.requestApplyInsets(this) ViewCompat.requestApplyInsets(this)
@@ -1405,6 +1409,239 @@ object ViewUtils {
} }
} }
/**
* Install a ripple forwarder that makes full-row background react to touches on specific children,
* while preserving RecyclerView-like delayed pressed behavior.
* zh-CN:
* 安装 Ripple 转发器, 让整行背景响应指定子视图的触摸,
* 同时尽量模拟 RecyclerView 的延迟 pressed 行为.
*/
fun installFullRowRippleForwarder(
parent: View,
vararg touchSources: View,
pressDelayMillis: Int = ViewConfiguration.getTapTimeout(),
) {
// Ensure the parent can show stateful background/foreground.
// zh-CN: 确保父视图可以显示带状态的 background/foreground.
parent.isClickable = true
parent.isFocusable = true
val vc = ViewConfiguration.get(parent.context)
// Movement threshold to decide "scrolling" vs "tapping".
// zh-CN: 用于区分 "滚动" 与 "点击" 的移动阈值.
val touchSlop = vc.scaledTouchSlop
// Duration used by framework to show a short pressed state for quick taps.
// zh-CN: 系统用于 "快速点击" 时短暂显示 pressed 的持续时间.
val pressedStateDuration = ViewConfiguration.getPressedStateDuration()
// Reusable objects to avoid allocations in hot paths.
// zh-CN: 复用对象, 避免高频路径分配.
val parentLoc = IntArray(2)
val childHitRect = Rect()
touchSources.forEach { child ->
child.setOnTouchListener(object : View.OnTouchListener {
// Track one gesture stream.
// zh-CN: 跟踪一次手势流.
private var activePointerId: Int = MotionEvent.INVALID_POINTER_ID
// Down positions in raw (screen) coordinates.
// zh-CN: DOWN 时的 raw (屏幕) 坐标.
private var downRawX: Float = 0f
private var downRawY: Float = 0f
// Last known raw coordinates for hotspot update.
// zh-CN: 用于更新 hotspot 的最近 raw 坐标.
private var lastRawX: Float = 0f
private var lastRawY: Float = 0f
// Whether we have applied parent pressed state.
// zh-CN: 是否已应用父视图 pressed 状态.
private var pressedApplied: Boolean = false
// Whether we are still waiting to apply pressed (pre-pressed).
// zh-CN: 是否仍处于等待 pressed 的 pre-pressed 状态.
private var prePressed: Boolean = false
// Runnable to apply pressed after delay.
// zh-CN: 延迟触发 pressed 的 Runnable.
private val applyPressedRunnable = Runnable {
if (!prePressed) {
return@Runnable
}
if (!isInsideViewWithSlop(child, lastRawX, lastRawY, touchSlop, childHitRect)) {
prePressed = false
return@Runnable
}
applyPressedNow()
}
override fun onTouch(v: View, event: MotionEvent): Boolean {
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
activePointerId = event.getPointerId(0)
downRawX = event.rawX
downRawY = event.rawY
lastRawX = event.rawX
lastRawY = event.rawY
pressedApplied = false
prePressed = true
// Delay pressed to mimic scrolling container behavior.
// zh-CN: 延迟 pressed, 模拟可滚动容器的行为.
parent.removeCallbacks(applyPressedRunnable)
parent.postDelayed(applyPressedRunnable, pressDelayMillis.toLong())
}
MotionEvent.ACTION_MOVE -> {
val idx = event.findPointerIndex(activePointerId)
if (idx < 0) {
return false
}
lastRawX = event.rawX
lastRawY = event.rawY
// If moved too much, treat as scroll and cancel.
// zh-CN: 如果移动过大, 视为滚动并取消.
val movedTooMuch =
abs(lastRawX - downRawX) > touchSlop || abs(lastRawY - downRawY) > touchSlop
if (movedTooMuch) {
cancelPressed()
return false
}
// If pressed is already applied, keep hotspot in sync.
// zh-CN: 若 pressed 已应用, 持续同步 hotspot.
if (pressedApplied) {
updateHotspot(lastRawX, lastRawY)
}
}
MotionEvent.ACTION_UP -> {
val idx = event.findPointerIndex(activePointerId)
if (idx < 0) {
cancelPressed()
return false
}
lastRawX = event.rawX
lastRawY = event.rawY
// If we never applied pressed (quick tap), apply briefly then clear.
// zh-CN: 如果尚未应用 pressed (快速点击), 短暂应用后清除.
if (prePressed && !pressedApplied) {
parent.removeCallbacks(applyPressedRunnable)
if (isInsideViewWithSlop(child, lastRawX, lastRawY, touchSlop, childHitRect)) {
applyPressedNow()
parent.postDelayed(
{ parent.isPressed = false },
pressedStateDuration.toLong(),
)
} else {
cancelPressed()
}
} else {
// Normal end of gesture.
// zh-CN: 正常结束手势.
parent.removeCallbacks(applyPressedRunnable)
// Defer clearing pressed state until after this UP is dispatched to the child view.
// zh-CN: 将清除 pressed 的时机延后到本次 UP 分发给子视图之后.
parent.post {
parent.isPressed = false
}
prePressed = false
pressedApplied = false
}
activePointerId = MotionEvent.INVALID_POINTER_ID
}
MotionEvent.ACTION_CANCEL -> {
cancelPressed()
activePointerId = MotionEvent.INVALID_POINTER_ID
}
}
// Do not consume, so child's click/long-click keep working.
// zh-CN: 不消费事件, 保持子视图 click/long-click 正常工作.
return false
}
/**
* Apply pressed immediately and update hotspot.
* zh-CN: 立即应用 pressed, 并更新 hotspot.
*/
private fun applyPressedNow() {
pressedApplied = true
prePressed = false
parent.isPressed = true
updateHotspot(lastRawX, lastRawY)
}
/**
* Cancel any pending pressed state and clear current pressed state.
* zh-CN: 取消所有待触发的 pressed, 并清除当前 pressed 状态.
*/
private fun cancelPressed() {
parent.removeCallbacks(applyPressedRunnable)
parent.isPressed = false
prePressed = false
pressedApplied = false
}
/**
* Update parent's ripple hotspot based on raw coordinates.
* zh-CN: 基于 raw 坐标更新父视图的 Ripple hotspot.
*/
private fun updateHotspot(rawX: Float, rawY: Float) {
parent.getLocationOnScreen(parentLoc)
val hx = rawX - parentLoc[0]
val hy = rawY - parentLoc[1]
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
parent.drawableHotspotChanged(hx, hy)
parent.background?.setHotspot(hx, hy)
parent.foreground?.setHotspot(hx, hy)
}
}
})
}
}
/**
* Check whether a raw (screen) coordinate is inside the view bounds with slop tolerance.
* zh-CN: 判断 raw (屏幕) 坐标是否在视图边界内, 并允许一定 slop 容差.
*/
private fun isInsideViewWithSlop(
view: View,
rawX: Float,
rawY: Float,
slop: Int,
outRect: Rect,
): Boolean {
val loc = IntArray(2)
view.getLocationOnScreen(loc)
val xInView = rawX - loc[0]
val yInView = rawY - loc[1]
outRect.set(
-slop,
-slop,
view.width + slop,
view.height + slop,
)
return outRect.contains(xInView.toInt(), yInView.toInt())
}
enum class MODE(val key: String) { enum class MODE(val key: String) {
DAY(key(R.string.key_night_mode_always_off)), DAY(key(R.string.key_night_mode_always_off)),

View File

@@ -5,8 +5,10 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="43dp"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:minHeight="43dp"
android:orientation="horizontal"> android:orientation="horizontal">
<FrameLayout <FrameLayout
@@ -32,7 +34,6 @@
android:layout_height="15dp" android:layout_height="15dp"
android:backgroundTint="@color/drawer_menu_group_text_color" android:backgroundTint="@color/drawer_menu_group_text_color"
android:visibility="gone" /> android:visibility="gone" />
</FrameLayout> </FrameLayout>
<LinearLayout <LinearLayout
@@ -41,7 +42,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:minHeight="43dp" android:minHeight="43dp"
android:layout_toEndOf="@+id/icon_container" android:layout_toEndOf="@+id/icon_container"
android:layout_toStartOf="@id/sw" android:layout_toStartOf="@id/switch_divider"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginEnd="5dp" android:layout_marginEnd="5dp"
android:gravity="center_vertical" android:gravity="center_vertical"
@@ -66,9 +67,20 @@
android:visibility="gone" android:visibility="gone"
tools:visibility="gone" tools:visibility="gone"
tools:text="@string/text_sample_string" /> tools:text="@string/text_sample_string" />
</LinearLayout> </LinearLayout>
<View
android:id="@+id/switch_divider"
android:layout_width="1dp"
android:layout_height="24dp"
android:layout_toStartOf="@id/sw"
android:layout_marginStart="2dp"
android:layout_marginEnd="6dp"
android:layout_centerVertical="true"
android:background="@color/day_night_alpha_20"
android:visibility="gone"
tools:visibility="visible" />
<org.autojs.autojs.ui.widget.PrefSwitch <org.autojs.autojs.ui.widget.PrefSwitch
android:id="@+id/sw" android:id="@+id/sw"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -79,5 +91,4 @@
android:visibility="gone" android:visibility="gone"
tools:checked="true" tools:checked="true"
tools:visibility="visible" /> tools:visibility="visible" />
</RelativeLayout> </RelativeLayout>

View File

@@ -18,7 +18,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1" android:layout_weight="1"
android:paddingBottom="4dp"/> android:paddingBottom="4dp" />
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -29,16 +29,16 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginVertical="2dp" android:paddingVertical="2dp"
android:baselineAligned="false"> android:baselineAligned="false">
<LinearLayout <LinearLayout
android:id="@+id/settings" android:id="@+id/settings"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
android:layout_gravity="center|bottom" android:gravity="center|bottom"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView
@@ -65,10 +65,10 @@
<LinearLayout <LinearLayout
android:id="@+id/plugin_center" android:id="@+id/plugin_center"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
android:layout_gravity="center|bottom" android:gravity="center|bottom"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView
@@ -95,10 +95,10 @@
<LinearLayout <LinearLayout
android:id="@+id/restart" android:id="@+id/restart"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
android:layout_gravity="center|bottom" android:gravity="center|bottom"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView
@@ -125,10 +125,10 @@
<LinearLayout <LinearLayout
android:id="@+id/exit" android:id="@+id/exit"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
android:layout_gravity="center|bottom" android:gravity="center|bottom"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView