android:如何使设置导航像本机设置应用程序

如何为Android本机设置应用程序进行SwitchReference的设置导航?

当你点击WiFi区域(不在交换机上)时,它将导航到一个新屏幕:

点击WiFi

我的应用程序只将开关从ON更改为OFF,反之亦然,即使我没有点击开关。

我正在使用PreferenceFragment和xml作为屏幕。 我的偏好是遵循Android PreferenceFragment文档中的示例。 我在ICS 4.0 API 14上开发我的应用程序。

有人知道怎么做吗?

编辑:

我的XML看起来像这样:

       

通过查看股票设置应用程序的来源,您可以find他们是如何做到的。

基本上,他们使用自定义ArrayAdapter(就像使用ListView一样)来显示带有Switch按钮的行。 对于第二个屏幕,他们只使用ActionBar中提供的CustomView。

我写了一篇文章,其中包含示例代码,以说明如何在项目中执行此操作。 但请注意,这只能在API级别14或更高级别中推卸,因此如果您定位较旧的设备,请保留旧的样式首选项屏幕。

我在这里看到两个问题:1。如何在开关区域外听取偏好点击? 2.如何在操作栏中放置开关?

我会回答问题1:

我创建了一个新的SwitchPreference类并覆盖了onClick方法,什么都不做。 这可以防止在开关外部单击时更​​改设置。

 public class SwitchPreference extends android.preference.SwitchPreference { @Override protected void onClick() { } } 

用法(xml):

  

用法(java):

 SwitchPreference switchPreference = (SwitchPreference) findPreference("whatever"); switchPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { DialogUtils.showToast(Preferences.this, "Clicked outside switch"); return true; } }); switchPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { DialogUtils.showToast(Preferences.this, "Clicked inside switch and setting changed"); return true; } }); 

我尝试了这个,并且有点挣扎。 我以为我会分享我的经验。

起初我尝试了XGouchet的答案,因为它获得了最多的选票。 解决方案相当复杂,并且需要使用优先级标头 ,这些标头非常酷但不适合我正在做的事情。 我决定让我做的最简单的事情是将我的preferenceFragment包装在一个常规片段中,然后用常规视图伪造切换器首选项。 我挖出了Android源代码的偏好,并提出了这个问题

                    

顶部的FrameLayout像这样获得一个首选项片段

  getChildFragmentManager() .beginTransaction() .replace(R.id.fragment_container, new SettingsPreferencesFragment(), "SettingsPreferencesFragment") .commit(); 

然后我可以像在任何常规视图中那样分配我的点击监听器。 SettingsPreferencesFragment只是完全标准的首选片段。

这个解决方案似乎很不错,但后来我发现平板电脑上出现了奇怪的布局问题。 我意识到我无法在所有设备上看到这个解决方案,我需要使用真正的switchPreference而不是假的。

==============解决方案2 ===============

AlikElzin-kilaka的解决方案很简单,但是当我尝试时却没有用。 我第二次尝试确保我没有做错。 我一直在玩,想出了一些似乎有用的东西。 他有一个很好的观点

这里有2个问题:1。如何在开关区域外听取偏好点击? 2.如何在操作栏中放置开关?

真的只有问题(1)值得回答,因为问题2已在这里和其他地方得到解答

我意识到在首选项中访问视图的唯一方法是创建子类并覆盖onBind 。 所以我想出了这个子类的SwitchPreference,它为整个视图创建了交换机的单独点击处理程序。 它仍然是一个黑客。

 public class MySwitchPreference extends SwitchPreference { public MySwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public MySwitchPreference(Context context, AttributeSet attrs) { super(context, attrs); getView(null,null); } public MySwitchPreference(Context context) { super(context); } public interface SwitchClickListener{ public void onSwitchClicked(boolean checked); public void onPreferenceClicked(); } private SwitchClickListener listener = null; public void setSwitchClickListener(SwitchClickListener listener){ this.listener = listener; } public Switch findSwitchWidget(View view){ if (view instanceof Switch){ return (Switch)view; } if (view instanceof ViewGroup){ ViewGroup viewGroup = (ViewGroup)view; for (int i = 0; i < viewGroup.getChildCount();i++){ View child = viewGroup.getChildAt(i); if (child instanceof ViewGroup){ Switch result = findSwitchWidget(child); if (result!=null) return result; } if (child instanceof Switch){ return (Switch)child; } } } return null; } protected void onBindView (View view){ super.onBindView(view); final Switch switchView = findSwitchWidget(view); if (switchView!=null){ switchView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (listener!=null) listener.onSwitchClicked(switchView.isChecked()); } }); switchView.setFocusable(true); switchView.setEnabled(true); } view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (listener!=null) listener.onPreferenceClicked(); } }); } } 

它使用递归函数findSwitchWidget来遍历树,直到findSwitch。 我宁愿写这样的代码:

 Switch switchView = view.findViewById(android.R.id.switchView); 

但似乎没有办法达到我所知道的内部id值。 无论如何,一旦我们有了实际的开关,我们就可以为它和容器视图分配监听器。 交换机首选项不会自动更新,因此必须自行保存首选项。

 MySwitchPreference switchPreference = (MySwitchPreference) findPreference("whatever"); switchPreference.setSwitchClickListener(new MySwitchPreference.SwitchClickListener() { @Override public void onSwitchClicked(boolean checked) { //Save the preference value here } @Override public void onPreferenceClicked() { //Launch the new preference screen or activity here } }); 

希望这第二个黑客不会再回来咬我了。

任何人都看到这种方法有任何潜在的缺陷吗?

我还在github上添加了稍微改进的代码版本https://gist.github.com/marchold/45e22839eb94aa14dfb5