【问题标题】:Make a normal layout look like a PreferenceScreen使普通布局看起来像 PreferenceScreen
【发布时间】:2015-03-30 17:58:38
【问题描述】:

PreferenceScreen 对我来说不够好,因为我必须将项目添加到 Spinner。这些项目需要来自数据列表。

我有一个自定义的 ArrayAdapter,它返回项目的名称,当我单击它时。它返回项目中包含的数据。

我想在 ListPreference 中使用相同的 ArrayAdapter(这是 PreferenceScreen 中的微调器),但 ListPreference 不允许我使用适配器。

所以,我想重新创建 PreferenceScreen 的外观(使用 PreferenceCategory 的)而不使用实际的 PreferenceScreen(和 PreferenceCategory 的)

图书馆可以做到这一点吗?我还没找到。

谢谢,

提姆

【问题讨论】:

  • Is this possible with a library? 嗯,有可能没有。但是你必须重新创建布局和底层逻辑,并以编程方式使用 SharedPreferences。
  • @DerGolem 没问题,但我正在寻找已经重新创建布局的人。或者图书馆
  • 我做到了。 没有任何库。启动:stackoverflow.com/a/6194194/2649012
  • @DerGolem 这很有趣,我刚刚添加了相同的代码。你能告诉我你是如何在布局中找到@+android:id/summary 和@+android:id/widget_frame 的吗?它在这里向我抛出错误
  • @DerGolem 你能发布一些代码吗?这对于稍后将访问此问题的所有访问者都非常有用。谢谢!

标签: android preferencescreen


【解决方案1】:

我尝试收集我的第一个方法 - 我希望我没有忘记包含一些部分(apart 颜色定义或 statelist 可绘制对象,这是您自己制作的一项微不足道的任务)

Customizing the standard Preferences

/res/xml/prefs.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >

    <!-- ... -->

    <PreferenceCategory android:title="@string/pref_vibrate_cat">
        <CheckBoxPreference
            android:persistent="true"
            android:key="vibrate"
            android:title="@string/pref_vibrate_title"
            android:summary="@string/pref_vibrate_summ"
            android:defaultValue="true"
            android:layout="@layout/prefs"
        />
    </PreferenceCategory>

    <!-- ... -->

    <!-- Just to show how to use a custom preference (you must have the corresponding java Class in your project) -->
    <PreferenceCategory android:title="@string/pref_tts_cat">
        <com.dergolem.abc.CLS_Prefs_Multi
            android:persistent="true"
            android:key="tts"
            android:title="@string/pref_tts_title"
            android:summary="@string/nothing"
            android:dialogTitle="@string/pref_tts_dlg"
            android:dialogIcon="@android:drawable/sym_action_chat"
            android:entries="@array/prefs_tts_titles"
            android:entryValues="@array/prefs_tts_values"
            android:defaultValue="@array/prefs_tts_defaults"
            android:layout="@layout/prefs"
            android:widgetLayout="@layout/arr_dn"
        />
    </PreferenceCategory>

    <!-- ... -->

</PreferenceScreen>

/res/layout/prefs.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for a visually child-like Preference in a PreferenceActivity. -->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:baselineAligned="false"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingStart="16dp"
    android:paddingEnd="?android:attr/scrollbarSize"
    >
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:minWidth="16dp"
        android:gravity="center"
        android:orientation="horizontal"
        >
        <ImageView
            android:id="@+android:id/icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
        />
    </LinearLayout>
    <RelativeLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_weight="1"
        >
        <TextView
            android:id="@+android:id/displayTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textStyle="bold"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
        />
        <TextView
            android:id="@+android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textStyle="bold"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
        />
        <TextView
            android:id="@+android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignStart="@android:id/title"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="?android:attr/textColorSecondary"
            android:shadowColor="@color/white"
            android:shadowDx="1"
            android:shadowDy="1"
            android:shadowRadius="1"
            android:maxLines="4"
        />
    </RelativeLayout>
    <!-- Preference should place its actual preference widget here. -->
    <LinearLayout
        android:id="@+android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:minWidth="48dp"
        android:gravity="center"
        android:orientation="vertical"
    />
</LinearLayout>

/src/ACT_Prefs

package com.dergolem.abc;

/* ---------------------------------- Imports ------------------------------- */

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.widget.ListView;

public final class ACT_Prefs // NO_UCD (use default)
extends PreferenceActivity
implements OnSharedPreferenceChangeListener
{
    /* ------------------------------ Objects ------------------------------- */

    private Context ctx = null;

    /* ----------------------------- Overrides ------------------------------ */

    // Reload the Activity on rotation.
    @Override
    public final void onConfigurationChanged(final Configuration cfg)
    {
        super.onConfigurationChanged(cfg);
        reStart();
    }
    /*
    Load the Preference Activity if the API LEvel is less than 11 or else load
    the PreferenceFragment.
    Needed workaround, since unfortunately Google didn't include the
    PreferenceFragment in the support library
    */
    @Override
    public final void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        ctx = getApplicationContext();

        if (Build.VERSION.SDK_INT < 11)
        {
            createPreference_Activity();
        }
        else
        {
            createPreference_Fragment();
        }
    }
    @Override
    protected void onPause()
    {
        // Unregister OnSharedPreferenceChangeListener
        PreferenceManager.getDefaultSharedPreferences(ctx).
        unregisterOnSharedPreferenceChangeListener(this);

        // Call the base method
        super.onPause();
    }
    @Override
    protected void onResume()
    {
        // Register OnSharedPreferenceChangeListener
        PreferenceManager.getDefaultSharedPreferences(ctx).
        registerOnSharedPreferenceChangeListener(this);

        // Fire the base method
        super.onResume();
    }

    /* ------------------------------ Methods ------------------------------- */

    @SuppressWarnings("deprecation")
    private final void createPreference_Activity()
    {
        // Set the Activity layout
        addPreferencesFromResource(R.xml.prefs);

        // Get the PreferenceScreen ListView
        final ListView lvw = getListView();

        // Set the horizontal separator
        lvw.setDivider(getResources().getDrawable(R.drawable.list_divider));
        lvw.setDividerHeight((1));

        // Set the statelist selector
        lvw.setSelector(R.drawable.list_item_colors);

        // Remove the top and bottom fadings
        lvw.setVerticalFadingEdgeEnabled(false);
    }
    @SuppressLint("NewApi")
    private final void createPreference_Fragment()
    {
        // Create the fragment.
        getFragmentManager().beginTransaction().replace
            (android.R.id.content, new FRG_Prefs()).commit();
        getFragmentManager().executePendingTransactions();
    }
}

/src/FRG_Prefs

package com.dergolem.abc;

/* ---------------------------------- Imports ------------------------------- */

import android.annotation.SuppressLint;
import android.graphics.PixelFormat;
import android.preference.PreferenceFragment;
import android.view.View;
import android.widget.ListView;

@SuppressLint("NewApi")
public final class FRG_Prefs
extends PreferenceFragment
{
    /* ----------------------------- Overrides ------------------------------ */

    @Override
    public final void onResume()
    {
        super.onResume();
        addPreferencesFromResource(R.xml.prefs);

        init();
    }
    @Override
    public final void onStop()
    {
        super.onStop();
        // Kill the prefence screen, so that it won't be recreated DUPLICATE.
        // HORRIBLE, but it's the only way to avoid the PreferenceScreen copycat.
        getActivity().finish();
    }

    /* ------------------------------ Methods ------------------------------- */

    private final void init()
    {
        final View v = getView();

        v.setPadding(paddingSize, 0, paddingSize, 0);

        // Get the PreferenceScreen ListView
        final ListView lvw = (ListView) v.findViewById(android.R.id.list);

        // Set the horizontal separator
        lvw.setDivider(getResources().getDrawable(R.drawable.list_divider));
        lvw.setDividerHeight((1));

        // Set the state selector
        lvw.setSelector(R.drawable.list_item_colors);

        // Remove top and bottom fading
        lvw.setVerticalFadingEdgeEnabled(false);
    }
}

显示我的偏好:

startActivity(new Intent(ctx, ACT_Prefs.class));

ctx 定义为

Context ctx = getApplicationContext();

由于我经常使用它,所以我一劳永逸地定义它。

[编辑]

根据要求,我可以添加一个方法来制作Fake PreferenceScreen

【讨论】:

  • 我需要将我想在我的 PreferenceScreen 中显示的视图放在 layout/prefs.xml 中吗?
  • 不,在 /res/xml/prefs.xml 中,就像 CheckBoxPreference 一样。 /res/layout/prefs.xml 是这些偏好视图的模板。
  • 如何将 Spinner 添加到设置布局中?
  • 我还使用了一些非标准首选项。例如Multiselection ListViews(非标准的较低API级别),DatePickers,TimePickers,带图标的ListViews,...
  • 谢谢!我会看一下并将上面的代码保存为sn-p,以便在下一个项目中需要时使用它!
【解决方案2】:

上面的答案很难实现,所以我设计了自己的版本。

布局xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical">

<include layout="@layout/toolbar"/> <!-- This is a custom toolbar (or actionbar), and not necessary -->

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_below="@+id/toolbar"
        android:paddingRight="?android:attr/scrollbarSize">

        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_below="@layout/toolbar"
            android:id="@+id/scrollView" >
            <LinearLayout
                android:orientation="vertical"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:text="@string/category_battery"
                    android:id="@+id/category_misc"
                    android:layout_marginLeft="@dimen/activity_settings_header_margin" />

                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="2dp"
                    android:id="@+id/divider"
                    android:layout_marginLeft="@dimen/activity_settings_margin"
                    android:layout_below="@+id/category_misc"
                    android:contentDescription="divider"
                    android:scaleType="matrix"
                    android:background="@android:drawable/divider_horizontal_bright"
                    android:src="@android:drawable/divider_horizontal_bright" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical"
                    android:padding="@dimen/activity_settings_margin">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/textView"/>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/textView"/>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/textView"/>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/textView"/>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/textView"/>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/textView"/>

                </LinearLayout>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/category_calibration"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:id="@+id/category_subjects"
                    android:layout_marginLeft="@dimen/activity_settings_header_margin"
                    android:layout_below="@+id/batteryChargeState" />

                <ImageView
                    android:layout_width="fill_parent"
                    android:layout_height="2dp"
                    android:id="@+id/divider2"
                    android:layout_marginLeft="@dimen/activity_settings_margin"
                    android:layout_below="@+id/category_subjects"
                    android:contentDescription="divider"
                    android:scaleType="matrix"
                    android:background="@android:drawable/divider_horizontal_bright"
                    android:src="@android:drawable/divider_horizontal_bright" />



                <LinearLayout android:layout_width="match_parent"
                    android:layout_below="@+id/category_subjects"
                    android:layout_centerVertical="true"
                    android:layout_height="match_parent"
                    android:padding="@dimen/activity_settings_margin"
                    android:orientation="vertical"
                    android:id="@+id/nextLayout">


                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:id="@+id/textView"/>


                </LinearLayout>

            </LinearLayout>

        </ScrollView>
    </RelativeLayout>


</RelativeLayout>

工具栏 xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"/>

尺寸 xml:

<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>

    <dimen name="activity_settings_margin">24dp</dimen>
    <dimen name="activity_settings_header_margin">18dp</dimen>
</resources>

颜色 xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="orange">#FDA432</color>
    <color name="orange_dark">#ffd17731</color>

</resources>

只需使用您的方式来存储首选项。我创建了一个包含私钥的自定义首选项类,因此我无法在此处发布代码而不破坏它。

使用这样的自定义布局的优点是您可以添加自己的工具栏,并将此行作为第一个 RelativeLayout 的第一个元素。

要使用自定义工具栏,请在 onCreate() 中使用这段代码

    @Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                mTitle = mDrawerTitle = getTitle(); // This is for the title when you use a drawer

                mToolbar = (Toolbar) findViewById(R.id.toolbar); // This finds the toolbar you've specified using the <include> in the xml

                setSupportActionBar(mToolbar); // This sets the toolbar to be used

                mToolbar.setBackgroundColor(getResources().getColor(R.color.orange)); // This sets the color of the toolbar

                if (Build.VERSION.SDK_INT >= 21) {
                    getWindow().setStatusBarColor(getResources().getColor(R.color.orange_dark)); // This sets the color of the navigation bar to a darker orange as used for the toolbar, only when this is supported!
                }

                mToolbar.setNavigationIcon(R.mipmap.ic_launcher); // This makes the icon clickable, to open and close a drawer if you have one
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多