【问题标题】:Switch in multiple custom preference layouts切换多个自定义首选项布局
【发布时间】:2013-11-07 11:08:24
【问题描述】:

我有一个设置活动 HomeActivity,它在启动时加载。启动模式设置为singleTask,由于某些要求,在HomeActivity的布局中有一个带有图标、标题和开关的元素。这个想法是您应该能够使用开关启用/禁用呼叫。如果您单击该行(在开关外),您将进入一个新活动 CallPreferences,您可以在其中设置呼叫特定设置。在 CallPreferences 的操作栏中,还应该存在一个开关,用户可以再次启用/禁用呼叫。两个活动的开关都应该反映“现实”。也就是说,当开关改变时,该值被存储到共享首选项中。然后,两个开关都从共享首选项 onCreate 中读取,以将其值设置为 on 或 off。

在 HomeActivity 的 xml 中,我有一个如下所示的首选项屏幕:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:foo="http://schemas.android.com/apk/lib/com.xxx.yy" >

    <com.xxx.yy.preferences.IconSwitchPreference
        foo:icon="@drawable/call_icn"        
        android:title="@string/call"
        android:key="callIconSwitchPreference" >
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="com.xxx.yy.preferences.CallPreferences"
            android:targetPackage="om.xxx.yy" />
    </com.xxx.yy.preferences.IconSwitchPreference>

</PreferenceScreen>

IconSwitchPreference 是我的自定义首选项布局,包含线性布局、标题文本视图、图像视图和开关:

<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for a Preference in a PreferenceActivity. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingRight="?android:attr/scrollbarSize">

   <Switch
        android:id="@+id/menu_switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:onClick="onMenuSwitchClicked" />

</LinearLayout>

以及运行代码的类:

public class IconSwitchPreference extends IconPreference {

public IconSwitchPreference(Context context) {
    this(context, null);
}

public IconSwitchPreference(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public IconSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setLayoutResource(R.layout.preference_icon_switch);        
        if (attrs != null) {
            int iconResId = attrs.getAttributeResourceValue(XMLNS, "icon", 0);
            mIcon = context.getResources().getDrawable(iconResId);            
            mFilter = attrs.getAttributeValue(XMLNS, "filter");
            mUrl = attrs.getAttributeValue(XMLNS, "url");
        }
    }   
}

在 CallPreferences 中,我以编程方式创建开关并将其添加到操作栏:

private void createActionBarSwitch() {
    ActionBar actionBar = getActionBar();
    Switch actionBarSwitch = new Switch(this);

    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
            ActionBar.DISPLAY_SHOW_CUSTOM);
    actionBar.setCustomView(actionBarSwitch, new ActionBar.LayoutParams(
            ActionBar.LayoutParams.WRAP_CONTENT,
            ActionBar.LayoutParams.WRAP_CONTENT, Gravity.CENTER_VERTICAL
                    | Gravity.RIGHT));

    actionBarSwitch.setChecked(isSwitchOn());
}

这行得通,我可以将开关设置为存储的值,然后更新开关以反映该值。

但在 HomeActivity 中,开关没有更新以反映该值。

以下操作不起作用

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    LayoutInflater inflater = getLayoutInflater();
    View view = inflater.inflate(R.layout.preference_icon_switch, null);
    TextView tv = (TextView)view.findViewById(android.R.id.title);
    tv.setText("Test");
    Switch menuSwitch = (Switch)view.findViewById(R.id.menu_switch);
    menuSwitch.setChecked(sharedPrefs.isCallhandlingEnabled());
}

文本视图也没有更改为测试,也没有启用开关(默认值为false)。

以下是有效的:

final IconSwitchPreference ic = (IconSwitchPreference) findPreference("callIconSwitchPreference");
ic.setTitle("Test");

标题设置为“测试”。唯一的问题是我没有对开关的任何引用,所以我可以更新它的值。是否可以更新 IconSwitchPreference.java 以在其使用的 xml 中提取和存储对开关的引用?

我尝试了许多解决方案和代码示例;但他们都有一些不起作用的东西。另一种解决方案是使用标准 SwitchPreference,但在单击开关本身以更改其状态(不进入新活动)和单击行以进入活动(不更改开关)之间没有区别值)。

【问题讨论】:

    标签: android xml android-layout


    【解决方案1】:

    通过将以下标记添加到 HomeActivity xml 解决了该问题:

    foo:switchPref="@string/call_enabled_pref_key"

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:foo="http://schemas.android.com/apk/lib/com.xxx.yy" >
    
        <com.xxx.yy.preferences.IconSwitchPreference
            foo:icon="@drawable/call_icn"        
            android:title="@string/call"
            android:key="callIconSwitchPreference"
            foo:switchPref="@string/call_enabled_pref_key" >
            <intent
                android:action="android.intent.action.VIEW"
                android:targetClass="com.xxx.yy.preferences.CallPreferences"
                android:targetPackage="om.xxx.yy" />
        </com.xxx.yy.preferences.IconSwitchPreference>
    
    </PreferenceScreen>
    

    然后在 IconSwitchPreference.java 中提取 res id:

    mSwitchPrefResId = attrs.getAttributeResourceValue(XMLNS, "switchPref", 0);

    public IconSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            setLayoutResource(R.layout.preference_icon_switch);        
            if (attrs != null) {
                int iconResId = attrs.getAttributeResourceValue(XMLNS, "icon", 0);
                mIcon = context.getResources().getDrawable(iconResId);            
                mFilter = attrs.getAttributeValue(XMLNS, "filter");
                mUrl = attrs.getAttributeValue(XMLNS, "url");
                mSwitchPrefResId = attrs.getAttributeResourceValue(XMLNS, "switchPref", 0);
            }
        }   
    }
    

    onBindView 在同一个类 (IconSwitchPreference.java) 我得到了对 Switch 的引用:

    @Override
    public void onBindView(View view) {
        super.onBindView(view);
        mSwitch = (Switch) view.findViewById(R.id.menu_switch);
        updateSwitch();
    }
    

    然后我使用 mSwitchPrefResId 来获取共享首选项(以了解开关是否启用)并将 mSwitch 设置为相应的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      • 2015-02-26
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多