10

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?

loganj
  • 215
  • 2
  • 7
  • Did you ever find a solution to this? I've just hit it too. – Graham Borland Jun 29 '11 at 14:35
  • Not really. I stuck with [my subclass](https://github.com/loganj/foursquared/blob/master/main/src/com/joelapenna/foursquared/preferences/ProgressCheckBoxPreference.java) of `CheckBoxPreference`. – loganj Jul 17 '11 at 16:52

2 Answers2

12
  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/)

greensuisse
  • 1,727
  • 16
  • 18
0

android:widgetLayout is the right part of the preference. In the CheckBoxPreference, the widgetLayout is the checkbox. If you take a base Preference and put a ViewSwitcher in the widgetLayout, it should work

fedj
  • 3,452
  • 1
  • 22
  • 21
  • Sure, but then I miss out on the stuff CheckBoxPreference does, like summaries and accessibility. – loganj Sep 01 '10 at 13:53