androidandroid-fragmentspreference

Custom Preference - Button not clickable


I'm working on a settings screen and I'm using Android's Preference API to build the interface. One of the preference will be a button - and I've done it by adding a custom layout to the preference. It works - the button is displayed as I want it but the problem is that when setting OnPreferenceClickListener nothing happens. It's not triggered.

I've tried adding beforeDescendants on the button layout root but no luck. Also tried to add focusable false to the button but still no luck.

Can anyone please share some tips on how I can make the preference button respond? Thanks!


Solution

  • onPreferenceClick is triggered when the Prefererence has been clicked not when you click the button. If you want to catch the button click you need to set a OnClickListener on the button itself. The problem is to retrieve the inflated button since the Preference class doesn't have a findViewById method or anything similar. Here's how I'd do it:

    1. Create a custom Preference class and override the onCreateView
    2. In the onCreateView method you grab the inflated layout from the super class and find the Button
    3. Add an OnClickListener to the button
    4. Use your custom Preference class in your preference layout file

    public class CustomPreference extends Preference  {
    
        public CustomPreference(Context context) {
            super(context);
        }
    
        public CustomPreference(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomPreference(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected View onCreateView(ViewGroup parent) {
            View preferenceView = super.onCreateView(parent);
    
            setOnClickListener(preferenceView);
    
            return preferenceView;
        }
    
        private void setOnClickListener(View preferenceView) {
            if (preferenceView != null && preferenceView instanceof ViewGroup) {
                ViewGroup widgetFrameView = ((ViewGroup)preferenceView.findViewById(android.R.id.widget_frame));
                if (widgetFrameView != null) {
                    // find the button
                    Button theButton = null;
                    int count = widgetFrameView.getChildCount();
                    for (int i = 0; i < count; i++) {
                        View view = widgetFrameView.getChildAt(i);
                        if (view instanceof Button) {
                            theButton = (Button)view;
                            break;
                        }
                    }
    
                    if (theButton != null) {
                        // set the OnClickListener
                        theButton.setOnClickListener(new OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                // do whatever you want to do
                            }
                        });
                    }
                }
            }
        }
    }
    

    This replaces the Preference in your xml file:

    <yourpackage.CustomPreference
        android:key="your_id"
        android:title="@string/your_title"
        android:summary="@string/your_summary"/>