Android: Only show divider in settings for headers

This commit is contained in:
Robin Kertels 2023-03-08 16:34:42 +01:00
parent f1e4b6a141
commit edde253724
No known key found for this signature in database
GPG Key ID: 3824904F14D40757
4 changed files with 123 additions and 10 deletions

View File

@ -22,8 +22,8 @@ class CheatItem {
}
companion object {
const val TYPE_CHEAT = 0
const val TYPE_HEADER = 1
const val TYPE_HEADER = 0
const val TYPE_CHEAT = 1
const val TYPE_ACTION = 2
}
}

View File

@ -13,11 +13,11 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.color.MaterialColors
import com.google.android.material.divider.MaterialDividerItemDecoration
import com.google.android.material.elevation.ElevationOverlayProvider
import org.dolphinemu.dolphinemu.R
import org.dolphinemu.dolphinemu.databinding.FragmentCheatListBinding
import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsDividerItemDecoration
class CheatListFragment : Fragment() {
private var _binding: FragmentCheatListBinding? = null
@ -39,8 +39,7 @@ class CheatListFragment : Fragment() {
binding.cheatList.adapter = CheatsAdapter(activity, viewModel)
binding.cheatList.layoutManager = LinearLayoutManager(activity)
val divider = MaterialDividerItemDecoration(requireActivity(), LinearLayoutManager.VERTICAL)
divider.isLastItemDecorated = false
val divider = SettingsDividerItemDecoration(requireActivity())
binding.cheatList.addItemDecoration(divider)
@ColorInt val color =

View File

@ -0,0 +1,118 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Partially based on: MaterialDividerItemDecoration
*
* Copyright (C) 2021 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 org.dolphinemu.dolphinemu.features.settings.ui
import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.graphics.drawable.ShapeDrawable
import android.view.View
import androidx.annotation.Px
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
import org.dolphinemu.dolphinemu.R
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
import kotlin.math.max
import kotlin.math.roundToInt
class SettingsDividerItemDecoration(context: Context) : ItemDecoration() {
private var dividerDrawable: Drawable
@Px
private var dividerThickness: Int
private val tempRect = Rect()
init {
val attrs = context.obtainStyledAttributes(intArrayOf(R.attr.colorSurfaceVariant))
val dividerColor =
attrs.getColor(0, ContextCompat.getColor(context, R.color.dolphin_surfaceVariant))
attrs.recycle()
val shape = ShapeDrawable()
dividerThickness = max(context.resources.displayMetrics.density.roundToInt(), 1)
dividerDrawable = DrawableCompat.wrap(shape)
DrawableCompat.setTint(dividerDrawable, dividerColor)
}
private fun isNextViewAHeader(view: View, parent: RecyclerView): Boolean {
val index = parent.indexOfChild(view)
if (index == parent.childCount - 1) {
return false
}
val nextChild = parent.getChildAt(index + 1)
val viewHolder = parent.getChildViewHolder(nextChild)
// CheatsItem.TYPE_HEADER == SettingsItem.TYPE_HEADER
return viewHolder.itemViewType == SettingsItem.TYPE_HEADER
}
override fun onDraw(
canvas: Canvas, parent: RecyclerView, state: RecyclerView.State
) {
if (parent.layoutManager == null) {
return
}
canvas.save()
val left: Int
val right: Int
if (parent.clipToPadding) {
left = parent.paddingLeft
right = parent.width - parent.paddingRight
canvas.clipRect(
left, parent.paddingTop, right, parent.height - parent.paddingBottom
)
} else {
left = 0
right = parent.width
}
val dividerCount = parent.childCount - 1
for (i in 0 until dividerCount) {
val child = parent.getChildAt(i)
if (!isNextViewAHeader(child, parent)) {
continue
}
parent.getDecoratedBoundsWithMargins(child, tempRect)
// Take into consideration any translationY added to the view.
val bottom = tempRect.bottom + child.translationY.roundToInt()
val top = bottom - dividerDrawable.intrinsicHeight - dividerThickness
dividerDrawable.setBounds(left, top, right, bottom)
dividerDrawable.draw(canvas)
}
canvas.restore()
}
override fun getItemOffsets(
outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State
) {
if (!isNextViewAHeader(view, parent)) {
return
}
outRect.bottom = dividerDrawable.intrinsicHeight + dividerThickness
}
}

View File

@ -17,8 +17,6 @@ import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.divider.MaterialDividerItemDecoration;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.databinding.FragmentSettingsBinding;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
@ -146,9 +144,7 @@ public final class SettingsFragment extends Fragment implements SettingsFragment
recyclerView.setAdapter(mAdapter);
recyclerView.setLayoutManager(manager);
MaterialDividerItemDecoration divider =
new MaterialDividerItemDecoration(requireActivity(), LinearLayoutManager.VERTICAL);
divider.setLastItemDecorated(false);
SettingsDividerItemDecoration divider = new SettingsDividerItemDecoration(requireActivity());
recyclerView.addItemDecoration(divider);
setInsets();