Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customizing CheckBoxPreference via android:widgetLayout

I have a Preference that enables a sync adapter, and takes a while to actually do its work when toggled. Consequently, when the user clicks the Preference, I spin off an AsyncTask to do the work. In the meantime, I disable the Preference and replace the check box with an indeterminate ProgressBar. I have all of this working via a hack involving a subclass of CheckBoxPreference that overlays the ProgressBar on top of the CheckBox. Yuck.

The android:widgetLayout attribute seems like it's designed exactly for this. I should be able to use android:widgetLayout to specify a replacement for the default CheckBox. Said replacement would implement Checkable and use a ViewSwitcher to switch appropriately between a CheckBox and a ProgressBar.

The only problem is that CheckBoxPreference, in its onBindView() method, seems to ignore the possibility that android:widgetLayout may be used. It explicitly does this:

View checkboxView = view.findViewById(com.android.internal.R.id.checkbox);

This effectively makes it impossible to swap in a custom Checkable via android:widgetLayout and have it actually work.

Is this an oversight/bug in CheckBoxPreference, or have I misunderstood android:widgetLayout? Is there a cleaner intended way to do what I'm trying to do?

like image 677
loganj Avatar asked Sep 01 '10 12:09

loganj


1 Answers

  1. First, I agree with you that Android should refactor the piece of code view.findViewById(com.android.internal.R.id.checkbox); to "calling a protected method" which can be overrided by subclass.

  2. Luckily, we are still able to override work around as follows: The idea is simple: declare a checkbox which has id is android default id @android:id/checkbox

<CheckBoxPreference
android:key="autostart"
android:widgetLayout="@layout/customlayout" />

and in customlayout.xml:

<SwitchView>
...
<CheckBox>

android:id="@android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="mycheck"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
</CheckBox>

It's really important to note that focusable attributes of checkbox must be set to false (I guess the default layout of CheckBoxPreference does the same thing) so that list apdater receives event rather than the checkbox itself. I guess you didn't success in your try just because you didn't set the focusable state.

greensuisse
(https://sites.google.com/site/greensuisse/)

like image 176
greensuisse Avatar answered Oct 03 '22 05:10

greensuisse