我在这里报告了这个问题(你也可以在那里查看我的解决方法项目),但现在,我发现了一些 hack-y,但很容易克服这个问题的方法:
这是代码。只需从此类扩展,其余的都是自动的:
科特林
abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
override fun onCreateAdapter(preferenceScreen: PreferenceScreen?): RecyclerView.Adapter<*> {
return object : PreferenceGroupAdapter(preferenceScreen) {
override fun onBindViewHolder(holder: PreferenceViewHolder, position: Int) {
super.onBindViewHolder(holder, position)
val preference = getItem(position)
if (preference is PreferenceCategory)
setZeroPaddingToLayoutChildren(holder.itemView)
else
holder.itemView.findViewById<View?>(R.id.icon_frame)?.visibility = if (preference.icon == null) View.GONE else View.VISIBLE
}
}
}
private fun setZeroPaddingToLayoutChildren(view: View) {
if (view !is ViewGroup)
return
val childCount = view.childCount
for (i in 0 until childCount) {
setZeroPaddingToLayoutChildren(view.getChildAt(i))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
view.setPaddingRelative(0, view.paddingTop, view.paddingEnd, view.paddingBottom)
else
view.setPadding(0, view.paddingTop, view.paddingRight, view.paddingBottom)
}
}
}
爪哇
public abstract class BasePreferenceFragmentCompat extends PreferenceFragmentCompat {
@Override
protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
return new PreferenceGroupAdapter(preferenceScreen) {
@SuppressLint("RestrictedApi")
@Override
public void onBindViewHolder(PreferenceViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
Preference preference = getItem(position);
if (preference instanceof PreferenceCategory)
setZeroPaddingToLayoutChildren(holder.itemView);
else {
View iconFrame = holder.itemView.findViewById(R.id.icon_frame);
if (iconFrame != null) {
iconFrame.setVisibility(preference.getIcon() == null ? View.GONE : View.VISIBLE);
}
}
}
};
}
private void setZeroPaddingToLayoutChildren(View view) {
if (!(view instanceof ViewGroup))
return;
ViewGroup viewGroup = (ViewGroup) view;
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
setZeroPaddingToLayoutChildren(viewGroup.getChildAt(i));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
viewGroup.setPaddingRelative(0, viewGroup.getPaddingTop(), viewGroup.getPaddingEnd(), viewGroup.getPaddingBottom());
else
viewGroup.setPadding(0, viewGroup.getPaddingTop(), viewGroup.getPaddingRight(), viewGroup.getPaddingBottom());
}
}
}
结果(可以在此 Google 示例中找到 XML 示例,我在此处创建了该示例以进行检查):
此代码有点危险,因此请确保在每次更新库时检查它是否正常工作。
此外,它在某些特殊情况下可能效果不佳,例如当您为首android:layout
选项定义自己的时,因此您必须为此进行修改。
得到了更好、更官方的解决方案:
对于每个首选项,使用app:iconSpaceReserved="false"
. 这应该可以正常工作,但由于某种原因,存在一个(已知)错误,它不适用于 PreferenceCategory。此处已报告,应在不久的将来修复。
所以现在你可以使用我写的解决方法和这个标志的混合版本。
编辑:找到另一个解决方案。这将克服所有偏好,并isIconSpaceReserved
为每个偏好设置。可悲的是,正如我在上面所写的,如果您使用 PreferenceCategory,它会破坏它,但如果您不使用它应该可以正常工作:
科特林
abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
override fun setPreferenceScreen(preferenceScreen: PreferenceScreen?) {
super.setPreferenceScreen(preferenceScreen)
if (preferenceScreen != null) {
val count = preferenceScreen.preferenceCount
for (i in 0 until count)
preferenceScreen.getPreference(i)!!.isIconSpaceReserved = false
}
}
爪哇
public class BasePreferenceFragment extends PreferenceFragmentCompat {
@Override
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
super.setPreferenceScreen(preferenceScreen);
if (preferenceScreen != null) {
int count = preferenceScreen.getPreferenceCount();
for (int i = 0; i < count; i++)
preferenceScreen.getPreference(i).setIconSpaceReserved(false);
}
}
}
编辑:在谷歌最终修复库(链接在这里)之后,您可以为每个偏好设置标志,或者使用这个解决方案,为您完成它:
abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
private fun setAllPreferencesToAvoidHavingExtraSpace(preference: Preference) {
preference.isIconSpaceReserved = false
if (preference is PreferenceGroup)
for (i in 0 until preference.preferenceCount)
setAllPreferencesToAvoidHavingExtraSpace(preference.getPreference(i))
}
override fun setPreferenceScreen(preferenceScreen: PreferenceScreen?) {
if (preferenceScreen != null)
setAllPreferencesToAvoidHavingExtraSpace(preferenceScreen)
super.setPreferenceScreen(preferenceScreen)
}
override fun onCreateAdapter(preferenceScreen: PreferenceScreen?): RecyclerView.Adapter<*> =
object : PreferenceGroupAdapter(preferenceScreen) {
@SuppressLint("RestrictedApi")
override fun onPreferenceHierarchyChange(preference: Preference?) {
if (preference != null)
setAllPreferencesToAvoidHavingExtraSpace(preference)
super.onPreferenceHierarchyChange(preference)
}
}
}
只需从它扩展,您就不会根据自己的喜好使用无用的填充。这里的示例项目,我还要求有一个官方的方法来避免它,而不是那些技巧。请考虑主演。