How to manage dividers in a PreferenceFragment?

后端 未结 10 1017
慢半拍i
慢半拍i 2020-12-01 12:29

I started dealing with preferences in a PreferenceFragment. Here\'s what I have:

\"my_preferences\"

相关标签:
10条回答
  • 2020-12-01 13:06

    I had this exact problem and wanted dividers between preference categories but not between the items themselves. I found that the accepted solution satisfied Question 1 by removing the dividers from preference items but did not fix question 2 and add the dividers between preference categories.

    Fix below. Basically override the onCreateAdapter method of your PreferenceFragmentCompat and give it a custom PreferenceGroupAdapter that has an overridden onBindViewHolder method that uses the position and whatever else you need to set above and below permissions for each view holder. A divider will be drawn when both viewholders allow a divider between them.

    Here is my fix

    public class SettingsFragment extends PreferenceFragmentCompat {
    
        @Override
        protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
            return new CustomPreferenceGroupAdapter(preferenceScreen);
        }
    
        static class CustomPreferenceGroupAdapter extends PreferenceGroupAdapter {
    
        @SuppressLint("RestrictedApi")
        public CustomPreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
            super(preferenceGroup);
        }
    
        @SuppressLint("RestrictedApi")
        @Override
        public void onBindViewHolder(PreferenceViewHolder holder, int position) {
            super.onBindViewHolder(holder, position);
            Preference currentPreference = getItem(position);
            //For a preference category we want the divider shown above.
            if(position != 0 && currentPreference instanceof PreferenceCategory) {
                holder.setDividerAllowedAbove(true);
                holder.setDividerAllowedBelow(false);
            } else {
                //For other dividers we do not want to show divider above 
                //but allow dividers below for CategoryPreference dividers.
                holder.setDividerAllowedAbove(false);
                holder.setDividerAllowedBelow(true);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-01 13:06

    New solution for new android API 24 and above (December 25th, 2017).

    I've found after try many ways on stackoverflow, but not work, or it just work but not work in nestest PreferenceScreen.

    Frist, you need to find listview from current displaying fragment, and remove the divider:

    private fun removeDividerInCurrentFragment() {
        this@YourPreferenceActivity.fragmentManager.findFragmentById(android.R.id.content)?.let {
            it.view?.findViewById<ListView?>(android.R.id.list)?.let {
                it.divider = null
                it.dividerHeight = 0
            }
        }
    }
    

    Second, to remove the divider when fragment commited, call method above (removeDividerInCurrentFragment) to remove listview's divider.

    To sure if you have nestest PreferenceScreen. Register listener when fragment changed in your PreferenceActivity by implement FragmentManager.OnBackStackChangedListener protocol:

    class YourPreferenceActivity : PreferenceActivity(), FragmentManager.OnBackStackChangedListener {
        override fun onBackStackChanged() {
            this@YourPreferenceActivity.removeDividerInCurrentFragment()
        }
    }
    

    Finally, register backstack changes listener by call fragmentManager.addOnBackStackChangedListener(this@ YourPreferenceActivity) in onCreate. And remove backstack changes listener by call fragmentManager.removeOnBackStackChangedListener in onDestroyed method.

    Good luck!

    0 讨论(0)
  • 2020-12-01 13:07

    if you use a PreferenceFragment ,you can use ListView.setDivider(null); if you use a PreferenceFragmentCompat ,you can use PreferenceFragmentCompat.setDivider(Drawable divider) or setDividerHeight(int height);

    0 讨论(0)
  • 2020-12-01 13:08

    (AndroidX only)

    Maksim Ivanov's answer got me most of the way there. But to remove dividers only for a specific Preference created in code, I had to do:

    val pref = object : Preference(activity) {
        override fun onBindViewHolder(holder: PreferenceViewHolder) {
            super.onBindViewHolder(holder)
            // By default, preferences created in code show dividers
            holder.setDividerAllowedAbove(false)
            holder.setDividerAllowedBelow(false)
        }
    }
    
    0 讨论(0)
提交回复
热议问题