You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android开发:如何让PreferenceCategory在屏幕剩余区域居中显示?

解决PreferenceCategory在剩余屏幕区域居中的问题

我明白你的需求:前面的PreferenceCategory(P1-P3)会占据部分屏幕空间,你希望P4和P5能在剩下的区域里同时实现水平、垂直居中显示。因为PreferenceCategory本身没有直接的gravity属性,咱们可以通过以下几种方式实现:

方法1:自定义PreferenceCategory布局(标题居中)

如果只是想让P4、P5的标题居中显示,这是最简单的实现方式:

  1. res/layout目录下创建preference_category_centered.xml布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">

    <!-- 复用系统标题样式,保证和其他Category风格一致 -->
    <TextView
        android:id="@android:id/title"
        style="?android:attr/listSeparatorTextViewStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="?android:attr/textColorPrimary" />

</LinearLayout>
  1. 在你的PreferenceScreen XML中,给P4、P5指定这个自定义布局:
<PreferenceCategory
    app:title="ABC"
    app:key="P4"
    app:layout="@layout/preference_category_centered" />

<PreferenceCategory
    app:title="ABC"
    app:key="P5"
    app:layout="@layout/preference_category_centered" />

这个方法能让每个Category的标题水平居中,但它们还是会按列表顺序垂直排列,不会整体在剩余屏幕区域垂直居中。

方法2:自定义CenteredPreferenceCategory(整体Item居中)

如果想让P4、P5的整个Item在列表中居中(包括垂直方向),可以自定义PreferenceCategory类,重写布局参数:

  1. 创建CenteredPreferenceCategory.kt(Java实现逻辑一致):
import android.content.Context
import android.view.Gravity
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceViewHolder

class CenteredPreferenceCategory(context: Context, attrs: AttributeSet) : PreferenceCategory(context, attrs) {

    override fun onBindViewHolder(holder: PreferenceViewHolder) {
        super.onBindViewHolder(holder)
        // 设置Item的布局参数,让它在RecyclerView中居中
        val layoutParams = holder.itemView.layoutParams as RecyclerView.LayoutParams
        layoutParams.gravity = Gravity.CENTER
        layoutParams.width = RecyclerView.LayoutParams.MATCH_PARENT
        holder.itemView.layoutParams = layoutParams
        
        // 同时让标题也居中(可选)
        holder.itemView.findViewById<android.widget.TextView>(android.R.id.title)?.gravity = Gravity.CENTER
    }
}
  1. 在XML中使用这个自定义类:
<com.yourpackage.CenteredPreferenceCategory
    app:title="ABC"
    app:key="P4" />

<com.yourpackage.CenteredPreferenceCategory
    app:title="ABC"
    app:key="P5" />

这个方法会让每个Category Item在RecyclerView的可用空间里居中,如果前面的P1-P3已经占据了大部分屏幕,P4、P5会挤在下方剩余空间里实现居中效果。

方法3:混合布局实现整体居中(推荐)

如果需要P4、P5整体在屏幕剩余区域垂直+水平居中(不是单个Item各自居中),可以通过自定义PreferenceFragment的布局,将偏好列表和居中容器分开:

  1. 创建res/layout/fragment_preference_custom.xml布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- 用来放置P1-P3的偏好列表,高度自适应内容 -->
    <LinearLayout
        android:id="@+id/preference_top_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

    <!-- 占据剩余屏幕高度,用来居中放置P4-P5 -->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/centered_bottom_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center">

    </androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>
  1. 在你的PreferenceFragmentCompat中重写onCreateView,手动构建偏好布局:
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.preference.PreferenceGroupAdapter

class SettingsFragment : PreferenceFragmentCompat() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // 加载自定义布局
        val rootView = inflater.inflate(R.layout.fragment_preference_custom, container, false)
        val topContainer = rootView.findViewById<ViewGroup>(R.id.preference_top_container)
        val bottomCenteredContainer = rootView.findViewById<ViewGroup>(R.id.centered_bottom_container)

        // 构建顶部的偏好列表(P1-P3)
        val preferenceScreen = PreferenceManager.getDefaultSharedPreferences(requireContext()).let {
            preferenceManager.createPreferenceScreen(requireContext()).apply {
                // 添加P1
                addPreference(PreferenceCategory(requireContext()).apply {
                    title = "ABC"
                    key = "P1"
                })
                // 添加P2并添加子偏好
                val p2 = PreferenceCategory(requireContext()).apply {
                    title = "ABC"
                    key = "P2"
                }
                // 这里添加你通过addPreference()加入的子偏好
                // p2.addPreference(yourPreference)
                addPreference(p2)
                // 添加P3并添加子偏好
                val p3 = PreferenceCategory(requireContext()).apply {
                    title = "ABC"
                    key = "P3"
                }
                // p3.addPreference(yourPreference)
                addPreference(p3)
            }
        }

        // 将顶部偏好列表添加到容器
        val topRecyclerView = RecyclerView(requireContext()).apply {
            adapter = PreferenceGroupAdapter(preferenceScreen)
            layoutManager = LinearLayoutManager(requireContext())
        }
        topContainer.addView(topRecyclerView)

        // 构建并添加P4、P5到居中容器
        val p4 = PreferenceCategory(requireContext()).apply {
            title = "ABC"
            key = "P4"
        }
        val p5 = PreferenceCategory(requireContext()).apply {
            title = "ABC"
            key = "P5"
        }

        // 将PreferenceCategory转为View并添加到居中容器
        bottomCenteredContainer.addView(p4.onCreateView(bottomCenteredContainer, inflater))
        bottomCenteredContainer.addView(p5.onCreateView(bottomCenteredContainer, inflater))

        return rootView
    }

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        // 这里不需要再加载XML,因为我们手动构建了布局
    }
}

这种方式能完美实现你的需求:P1-P3在顶部自适应高度,P4-P5整体在剩余屏幕区域同时实现垂直+水平居中显示。


内容的提问来源于stack exchange,提问作者Vivek Mangal

火山引擎 最新活动