通过android:widgetLayout自定义CheckBoxPreference

10
我有一个偏好设置(Preference),可以启用同步适配器,并且在切换时需要一段时间才能完成其工作。因此,当用户单击该偏好设置时,我会开启一个 AsyncTask 来执行工作。在此期间,我禁用该偏好设置,并用一个不确定的 ProgressBar 替换复选框。通过使用 CheckBoxPreference 的子类来覆盖 ProgressBar,我已经使用了一个 hack 来实现所有这些功能。Yuck。 android:widgetLayout 属性似乎正是为这个设计的。我应该能够使用 android:widgetLayout 属性指定默认 CheckBox 的替代品。该替代品将实现 Checkable 并使用 ViewSwitcher 在 CheckBox 和 ProgressBar 之间适当地切换。
唯一的问题是,CheckBoxPreference 在其 onBindView() 方法中似乎忽略了 android:widgetLayout 可能被使用的可能性。它明确地这样做:
View checkboxView = view.findViewById(com.android.internal.R.id.checkbox);

这实际上使得通过android:widgetLayout交换自定义的Checkable并让其正常工作成为不可能。

这是否是CheckBoxPreference中的疏忽/错误,还是我误解了android:widgetLayout?是否有更干净的预期方法来做我试图做的事情?


你最终找到解决办法了吗?我也遇到了这个问题。 - Graham Borland
不是真的。我坚持使用我的子类CheckBoxPreference - loganj
2个回答

12
  1. 首先,我同意你的观点,Android应该重构这行代码view.findViewById(com.android.internal.R.id.checkbox);,改为“调用受保护的方法”,可以被子类重写。

  2. 幸运的是,我们仍能通过以下方式绕过重写:

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

在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>

需要注意的是,复选框的可聚焦属性必须设置为false(我猜CheckBoxPreference的默认布局也做了相同的事情),以便列表适配器接收事件而不是复选框本身。我猜你之前尝试失败的原因可能是你没有设置可聚焦状态。

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


太棒了!它可以工作了。感谢提醒将它们设置为“false”。 - Sdghasemi

0

android:widgetLayout是Preference的右侧部分。在CheckBoxPreference中,widgetLayout是复选框。 如果您将基本Preference放入widgetLayout中的ViewSwitcher中,则应该可以正常工作。


当然可以,但我会错过 CheckBoxPreference 的摘要和辅助功能等功能。 - loganj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接