我正在尝试实现的是下面图像的基本和精确的复制品(我已经平方的偏好)。按下首选项左侧的任何内容都应该打开一个对话框。按下togglebutton将禁用/启用我在此首选项中设置的任何内容。
我一直在努力工作几个小时,而且我空手而归。如何在PreferenceActivity中实现它?
编辑:似乎人们误解了我的问题。我弄清楚如何使用PreferenceActivity解决我的问题非常重要。不是活动。我不在乎我是需要用XML还是以编程方式来做。请不要向我提供我不能在类似内容中使用的答案。
编辑2:增加了赏金 - 我真的需要一个答案
答案 0 :(得分:17)
天哪,我喜欢你的想法: - )
这与@ MH的答案相同,但更简洁。
我使用ToggleButton
进行了测试,而不是Switch
。
package android.dumdum;
import android.content.Context;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ToggleButton;
public class TogglePreference extends Preference {
public TogglePreference(Context context) {
super(context);
}
public TogglePreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TogglePreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public View getView(View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = new LinearLayout(getContext());
((LinearLayout) convertView)
.setOrientation(LinearLayout.HORIZONTAL);
TextView txtInfo = new TextView(getContext());
txtInfo.setText("Test");
((LinearLayout) convertView).addView(txtInfo,
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1));
ToggleButton btn = new ToggleButton(getContext());
((LinearLayout) convertView).addView(btn);
}
return convertView;
}
}
preferences.xml
:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Test custom preferences" >
<android.dumdum.EncryptorEditTextPreference />
<android.dumdum.TogglePreference />
</PreferenceCategory>
</PreferenceScreen>
EncryptorEditTextPreference
与您的问题无关,但它使用相同的技术(扩展EditTextPreference
)。
答案 1 :(得分:9)
前言只是一个注意事项:这将是一个很长的答案,但我的目的是为您提供一个易于理解的答案,您可以直接复制并粘贴以开始使用。
这实际上并不难实现。您最好的出发点是在ICS上查找SwichPreference
的实现。你会发现它非常简单,大多数工作都是由一个TwoStatePreference
超类完成的,而这个超类也只是可用的ICS。幸运的是,你几乎可以复制粘贴(在这个答案中一直看到)该类并构建你自己的TogglePreference
(为了清楚起见,我们称之为),使用{{ 1}}实施指南。
通过这样做你会得到什么,如下所示。我为每种方法添加了一些解释,以便我可以限制我的写作。
<强> TogglePreference.java 强>
SwitchPreference
此示例的布局文件只是一个package mh.so.pref;
import mh.so.R;
import android.content.Context;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ToggleButton;
/**
* A {@link Preference} that provides a two-state toggleable option.
* <p>
* This preference will store a boolean into the SharedPreferences.
*/
public class TogglePreference extends TwoStatePreference {
private final Listener mListener = new Listener();
private ExternalListener mExternalListener;
/**
* Construct a new TogglePreference with the given style options.
*
* @param context The Context that will style this preference
* @param attrs Style attributes that differ from the default
* @param defStyle Theme attribute defining the default style options
*/
public TogglePreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Construct a new TogglePreference with the given style options.
*
* @param context The Context that will style this preference
* @param attrs Style attributes that differ from the default
*/
public TogglePreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* Construct a new TogglePreference with default style options.
*
* @param context The Context that will style this preference
*/
public TogglePreference(Context context) {
this(context, null);
}
/** Inflates a custom layout for this preference, taking advantage of views with ids that are already
* being used in the Preference base class.
*/
@Override protected View onCreateView(ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(R.layout.toggle_preference_layout, parent, false);
}
/** Since the Preference base class handles the icon and summary (or summaryOn and summaryOff in TwoStatePreference)
* we only need to handle the ToggleButton here. Simply get it from the previously created layout, set the data
* against it and hook up a listener to handle user interaction with the button.
*/
@Override protected void onBindView(View view) {
super.onBindView(view);
ToggleButton toggleButton = (ToggleButton) view.findViewById(R.id.toggle_togglebutton);
toggleButton.setChecked(isChecked());
toggleButton.setOnCheckedChangeListener(mListener);
}
/** This gets called when the preference (as a whole) is selected by the user. The TwoStatePreference
* implementation changes the actual state of this preference, which we don't want, since we're handling
* preference clicks with our 'external' listener. Hence, don't call super.onClick(), but the onPreferenceClick
* of our listener. */
@Override protected void onClick() {
if (mExternalListener != null) mExternalListener.onPreferenceClick();
}
/** Simple interface that defines an external listener that can be notified when the preference has been
* been clicked. This may be useful e.g. to navigate to a new activity from your PreferenceActivity, or
* display a dialog. */
public static interface ExternalListener {
void onPreferenceClick();
}
/** Sets an external listener for this preference*/
public void setExternalListener(ExternalListener listener) {
mExternalListener = listener;
}
/** Listener to update the boolean flag that gets stored into the Shared Preferences */
private class Listener implements CompoundButton.OnCheckedChangeListener {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!callChangeListener(isChecked)) {
// Listener didn't like it, change it back.
// CompoundButton will make sure we don't recurse.
buttonView.setChecked(!isChecked);
return;
}
TogglePreference.this.setChecked(isChecked);
}
}
}
,其中包含三个元素,其中最有趣的一个是LinearLayout
。 ToggleButton
和ImageView
通过在Android命名空间中使用适当的ID来利用TextView
基类已经完成的工作。这样,我们不必担心这些。请注意,我非常确定在Honeycomb之前没有添加图标选项,因此您可能只想将其作为自定义属性添加到Preference
并手动设置它以便它始终存在。如果你需要更具体的指针来解决这个问题,请点击我的评论。
无论如何,显然你可以在任何范围内修改布局,并根据自己的喜好应用样式。例如,要让TogglePreference
模仿ToggleButton
,您可以将背景更改为其他Switch
和/或更改或完全删除开/关文本。
<强> toggle_preference_layout.xml 强>
StateListDrawable
然后,您可以像<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight" >
<ImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:focusable="false"
android:focusableInTouchMode="false" />
<TextView
android:id="@android:id/summary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:focusable="false"
android:focusableInTouchMode="false"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ToggleButton
android:id="@+id/toggle_togglebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:focusable="false"
android:focusableInTouchMode="false" />
</LinearLayout>
中的任何其他TogglePreference
一样使用Preference
。通过连接监听器,您可以在用户选择首选项时执行任何操作,同时单击实际PreferenceActivity
将切换ToggleButton
中的布尔值。
<强> DemoPreferenceActivity.java 强>
SharedPreferences
Prefs.xml仅仅是上述package mh.so.pref;
import mh.so.R;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.widget.Toast;
public class DemoPreferenceActivity extends PreferenceActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
TogglePreference toggle = (TogglePreference) findPreference("toggle_preference");
toggle.setExternalListener(new TogglePreference.ExternalListener() {
@Override public void onPreferenceClick() {
Toast.makeText(DemoPreferenceActivity.this, "You clicked the preference without changing its value", Toast.LENGTH_LONG).show();
}
});
}
}
的单一定义。您可以在Android的命名空间中提供所有常用属性。或者,您也可以声明一些自定义属性,以利用TogglePreference
的内置功能来处理TwoStatePreference
和summaryOn
文本。
<强>的prefs.xml 强>
summaryOff
最后,来自ICS的反向移植的TwoStatePreference类。它与原始版本几乎没有任何不同,您可以找到源overhere。
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Toggle preferences" >
<mh.so.pref.TogglePreference xmlns:app="http://schemas.android.com/apk/res/mh.so"
android:key="toggle_preference"
android:summary="Summary"
android:icon="@drawable/icon" />
</PreferenceCategory>
</PreferenceScreen>
答案 2 :(得分:0)
不确定这是否是切换按钮,但如果是,你可以在.xml上说android:textOn或android:textoff。如果它在java部分,它可能就像setTextOnNot肯定,如果这是一个切换按钮,但如果它是你可以只说android:textOn或android:textoff on .xml。如果它在java部分,它可能就像toggleButton.setChecked。
答案 3 :(得分:0)
我不确定你遇到了什么问题,我只是创建了一个虚拟视图,就像你所指的那样,我没有看到任何问题
<TableRow
android:id="@+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Switch
android:id="@+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="Switch" />
</TableRow>
答案 4 :(得分:0)
您可以在pref xml文件中使用此xml代码
<PreferenceCategory>
<EditTextPreference
android:key="myEditText"
android:title="Hi"
android:inputType="Mine"></EditTextPreference>
</PreferenceCategory>
您可以使用复选框来改为使用此代码togglebutton:
<CheckBoxPreference
android:key="testmode"
android:title="@string/test_mode"></CheckBoxPreference>
如果您不想使用复选框,可以使用以下代码:
答案 5 :(得分:0)
只需使用SwitchPreference
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<SwitchPreference
android:key="test"
android:title="This is test toggle switch" />
</PreferenceScreen>
看起来像这样(只是我的应用程序中的一个示例,不用担心其他prefs)