很不幸,我认为你不可能找到比你已经在Android: How to maximize PreferenceFragment width (or get rid of margin)?中发现的答案更好了。我会解释原因,并给你提供一个备选方案,尽管你可能会认为这个方案比你参考答案中提出的更糟糕。
我们将识别每个项目下面的布局,这些是我们将使用的首选项库依赖项:
implementation 'com.android.support:preference-v7:27.1.1'
implementation 'com.android.support:preference-v14:27.1.1'
主题的
preferenceTheme
属性定义了首选项的外观。
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
<!-- Theme for the preferences -->
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
从
PreferenceThemeOverlay.v14.Material
向上遍历父级链(ctrl-B),我们可以看到
<style name="PreferenceThemeOverlay.v14.Material">
...
<item name="preferenceStyle">@style/Preference.Material</item>
...
</style>
Preference.Material
的定义如下:
<style name="Preference.Material">
<item name="android:layout">@layout/preference_material</item>
</style>
偏好设置的布局是
preference_material.xml
。以下是
源代码。
该布局的以下部分引起了我们的兴趣:
...
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?attr/textAppearanceListItem"
android:ellipsize="marquee" />
<TextView android:id="@+id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_alignStart="@id/title"
android:textAppearance="?attr/textAppearanceListItemSecondary"
android:textColor="?attr/textColorSecondary"
android:maxLines="10"
android:ellipsize="end" />
</RelativeLayout>
...
如您所见,
RelativeLayout
的顶部和底部填充是硬编码的。由于没有使用样式属性,因此无法覆盖填充。由于这种硬编码,您有两个选择:
使用您找到的答案中概述的"真正糟糕的解决方法",它涉及使用Java代码修改填充,或者
通过在首选项的XML中定义 android:layout="@layout/custom_preference"
来使用自己的布局。您可以复制 Android 布局并进行修改。
每种方法都有缺点,请选择您认为最能处理的方法。
以下是演示替换首选项布局的小应用程序的关键组件。
MainActivity.java这个活动为方便起见滚动首选项片段。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
Fragment preferenceFragment = new PrefsFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.prefContainer, preferenceFragment);
ft.commit();
}
}
public static class PrefsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.app_preferences);
}
}
}
app_preference.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.preference.Preference
android:key="preference"
android:layout="@layout/custom_pref_layout"
android:summary="Doesn't really do anything."
android:title="Preference Title" />
<android.support.v7.preference.EditTextPreference
android:defaultValue="Default EditTextPreference value"
android:dialogMessage="EditTextPreference Dialog Message"
android:inputType="number"
android:key="editTextPreference"
android:layout="@layout/custom_pref_layout"
android:summary="EditTextPreference Summary"
android:title="EditTextPreference Title" />
<android.support.v7.preference.SwitchPreferenceCompat
android:defaultValue="true"
android:key="switchPreference"
android:layout="@layout/custom_pref_layout"
android:summary="SwitchPreference Summary"
android:title="SwitchPreference Title" />
<android.support.v7.preference.CheckBoxPreference
android:defaultValue="true"
android:key="checkBoxPreference"
android:layout="@layout/custom_pref_layout"
android:summary="CheckBoxPreference Summary"
android:title="CheckBoxPreference Title" />
<android.support.v7.preference.ListPreference
android:defaultValue="180"
android:entries="@array/pref_sync_frequency_titles"
android:entryValues="@array/pref_sync_frequency_values"
android:key="list_preference"
android:layout="@layout/custom_pref_layout"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="List Preference Title" />
</android.support.v7.preference.PreferenceScreen>
activity_main.xml
简单定义了首选项片段的主页面。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/prefContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.preferencecustomlayout.MainActivity" />
custom_pref_layout.xml
已进行一些修改以适应该文件的使用,主要更新了?attr/somthing
为?android:attr/something
。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator"
android:clipToPadding="false"
android:gravity="center_vertical"
android:minHeight="?attr/listPreferredItemHeightSmall"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingStart="?android:attr/listPreferredItemPaddingStart">
<LinearLayout
android:id="@+id/icon_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="-4dp"
android:gravity="start|center_vertical"
android:minWidth="60dp"
android:orientation="horizontal"
android:paddingBottom="4dp"
android:paddingEnd="12dp"
android:paddingTop="4dp">
<com.android.internal.widget.PreferenceImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="48dp"
android:maxWidth="48dp" />
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingBottom="16dp"
android:paddingTop="16dp">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?attr/textAppearanceListItem" />
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@android:id/title"
android:layout_below="@android:id/title"
android:ellipsize="end"
android:maxLines="10"
android:textAppearance="?attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary" />
</RelativeLayout>
<LinearLayout
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="end|center_vertical"
android:orientation="vertical"
android:paddingStart="16dp" />
</LinearLayout>
Gradle文件
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "com.example.preferencecustomlayout"
minSdkVersion 18
targetSdkVersion 27
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:preference-v7:27.1.1'
implementation 'com.android.support:preference-v14:27.1.1'
}