Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically changing android preference's widgetlayout resource

I created a preference entry inside preference screen, which looks like this:

<PreferenceScreen>
    <Preference
        android:title="title"
        android:key="key"
        android:widgetLayout="@layout/someview"/>
</PreferenceScreen>

Here I set a widgetlayout resource, which should be shown to the right of the preference item (like a checkbox for a checkbox preference). I can also set this resource in code of my PreferenceActivity.onCreate() like this:

Preference myPreference = findPreference("key");
myPreference.setWidgetLayoutResource(R.layout.someview);

Both approaches work fine, so I can see my resource to the right of the preference item. However, I cannot access this resource (someview) to alter its properties on runtime.

Neither manually setting resource id, inflating it from resource or findViewById seem to work - I have invalid resource/resource id not found exceptions. Seems like preference activity inflates the resource sometime later.

Has anybody run into the same problem? Any ideas about how to alter widgetlayout resource's properties on runtime?

Here is a similar question, but it was not answered

  • [android-developers] problem accessing widget in Preference widgetLayout
like image 576
kkgery Avatar asked Mar 24 '12 09:03

kkgery


People also ask

What is PreferenceFragmentCompat?

A PreferenceFragmentCompat is the entry point to using the Preference library. This Fragment displays a hierarchy of Preference objects to the user. It also handles persisting values to the device. To retrieve an instance of android.

How do I turn off preferences on Android?

findPreference("yourpref"). setEnabled(false);

What is preference screen?

This settings screen is used to manage the preferences of the users. For creating this settings screen android provides a feature to make a settings preferences screen.

Which of these methods can be used to view the user preferences in the context of overall Android framework?

getAll(): This method is used to retrieve all values from the preferences.


2 Answers

I seem to have the same problem, and I tried like this:

1) make a custom Preference and override onBindView():

public class ProgressBarPreference extends Preference {

    private ProgressBar mProgressBar;

    // constructors

    @Override
    protected void onBindView(View view) {
        super.onBindView(view);
        mProgressBar = (ProgressBar) view.findViewById(R.id.progressBar);
    }

    public ProgressBar getProgressBar() {
        return mProgressBar;
    }

}

2) add this preference to the screen xml:

<package.ProgressBarPreference
    android:key="key"
    android:summary="summary"
    android:title="title"
    android:widgetLayout="@layout/preference_widget_progressbar" />

preference_widget_progressbar.xml

<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/progressBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center" />

or call setWidgetLayoutResource().

3) get the ProgressBar when onPreferenceTreeClick():

if (preference instanceof ProgressBarPreference) {
    ProgressBar progressBar = ((ProgressBarPreference) preference).getProgressBar();
    // TODO something
}

However, over a year now!

like image 176
kuokuo Avatar answered Nov 15 '22 11:11

kuokuo


I have a partial workaround for joinAero's case. If the goal is to simply show or hide an indeterminate progress bar in the widget, the trick is to set and clear the widget layout resource in code.

1) Define the widget layout containing the ProgressBar. No need to assign an ID. preference_widget_progressbar.xml:

<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center" />

2) Don't specify the widget in settings.xml

<package.ProgressBarPreference
    android:key="key"
    android:summary="summary"
    android:title="title" />

3) When you want to show the progress bar, set the widget resource to preference_widget_progressbar. To clear it, set it to 0. The call to notifyChanged() is needed to update the screen.

public void showProgressBar(boolean isVisible) {
    // Show or hide the entire widget (which contains only a ProgressBar)
    setWidgetLayoutResource(isVisible ? R.layout.preference_widget_progressbar: 0);
    notifyChanged();    // Update screen
}

Getting a pointer to the actual ProgressBar is surprisingly hard, especially if the preference is in a library project. I had some success using getIdentifier() as per this post, but this approach actually hides the entire widget, whereas setting the visibility on the ProgressBar leaves a blank widget visible.

like image 31
ehartwell Avatar answered Nov 15 '22 11:11

ehartwell