मैंने इस मुद्दे के बारे में यहां रिपोर्ट की है (आप वहां पर मेरे वर्कअराउंड प्रोजेक्ट की जांच भी कर सकते हैं), लेकिन अभी के लिए, मैंने इसे हैक करने के लिए थोड़ा हैक-वाई पाया है, फिर भी इसे दूर करने का आसान तरीका:
इसके लिए PreferenceCategory
, मैंने इसके लेआउट्स की शुरुआत / बाईं पैडिंग को 0 पर सेट किया।
अन्य प्रकार की वरीयताओं के लिए, मैं उस icon_frame
मामले को छिपाने के लिए चुनता हूं जब उनके पास एक आइकन नहीं है।
यहाँ कोड है। बस इस वर्ग से विस्तार करें और बाकी स्वचालित है:
Kotlin
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 नमूना है, जो मैं बना लिया है यहाँ की जाँच करने के लिए):
यह कोड थोड़ा खतरनाक है, इसलिए सुनिश्चित करें कि लाइब्रेरी के प्रत्येक अपडेट पर, आप जांच लें कि यह ठीक काम करता है।
इसके अलावा, यह कुछ विशेष मामलों पर अच्छी तरह से काम नहीं कर सकता है, जैसे कि जब आप android:layout
वरीयता के लिए स्वयं को परिभाषित करते हैं, तो आपको इस मामले के लिए इसे संशोधित करना होगा।
एक बेहतर, अधिक आधिकारिक समाधान मिला:
प्रत्येक वरीयता के लिए, का उपयोग करें app:iconSpaceReserved="false"
। यह ठीक काम करना चाहिए, लेकिन किसी कारण से एक ज्ञात (ज्ञात) बग है कि यह वरीयता के लिए काम नहीं करता है। यह यहां बताया गया था , और निकट भविष्य में तय किया जाना चाहिए।
तो अब के लिए आप मेरे द्वारा लिखे गए वर्कअराउंड और इस ध्वज के मिश्रण संस्करण का उपयोग कर सकते हैं।
संपादित करें: अभी तक एक और समाधान मिला। यह एक प्राथमिकता के सभी खत्म हो जाएगा, और isIconSpaceReserved
प्रत्येक के लिए निर्धारित किया है। अफसोस की बात है, जैसा कि मैंने ऊपर लिखा है, यदि आप वरीयता-सूची का उपयोग करते हैं, तो यह इसे बर्बाद कर देता है, लेकिन यदि आप इसका उपयोग नहीं करते हैं तो यह ठीक काम करना चाहिए:
Kotlin
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);
}
}
}
EDIT: Google ने आखिरकार लाइब्रेरी ( यहां लिंक ) को निर्धारित करने के बाद, आप प्रत्येक वरीयता के लिए ध्वज सेट कर सकते हैं, या इस समाधान का उपयोग कर सकते हैं, जो आपके लिए यह सब करता है:
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)
}
}
}
बस इससे आगे बढ़ें, और आपके पास अपनी प्राथमिकताओं के लिए बेकार पैडिंग नहीं होगी। यहां नमूना परियोजना , जहां मैं उन टोटकों के बजाय, इससे बचने के लिए एक आधिकारिक तरीका रखने का अनुरोध करता हूं। कृपया इसे अभिनीत करने पर विचार करें।