Android: How to Maximize Preferencefragment Width (Or Get Rid of Margin)

Android: How to maximize PreferenceFragment width (or get rid of margin)?

Finally, I found the solution to this.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
if(v != null) {
ListView lv = (ListView) v.findViewById(android.R.id.list);
lv.setPadding(10, 10, 10, 10);
}
return v;
}

You can set padding by using: setPadding();

Android: How to adjust Margin/Padding in Preference?

You could customize you checkbox like this:
MyPreference.xml

<CheckBoxPreference android:key="testcheckbox" 
android:title="Checkbox Title"
android:summary="Checkbox Summary..."
android:layout="@layout/custom_checkbox_preference_layout">
</CheckBoxPreference>

and custom_checkbox_preference_layout.xml

<?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:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingLeft="16dip"
android:paddingRight="?android:attr/scrollbarSize">

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="0dp"
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"
/>
</LinearLayout>

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">

<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: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_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
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:gravity="center"
android:orientation="vertical" />

</LinearLayout>

the point is android:minWidth="0dp".

Adjust margin/padding in the 'PreferenceScreen' in Android

Unfortunately, I don't think that you are going to find a better answer than you have already discovered in Android: How to maximize PreferenceFragment width (or get rid of margin)?. I will explain why and give you an alternative which you may consider to be worse than the one presented in the answer you reference.

Underneath the preference screen is a layout for each item which we will identify. These are the preference library dependencies that we will use:

implementation 'com.android.support:preference-v7:27.1.1'
implementation 'com.android.support:preference-v14:27.1.1'

The preferenceTheme attribute of the theme defines how the preferences will look.

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
<!-- Theme for the preferences -->
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>

Going up the parent chain (ctrl-B) from PreferenceThemeOverlay.v14.Material we see

<style name="PreferenceThemeOverlay.v14.Material">
...
<item name="preferenceStyle">@style/Preference.Material</item>
...
</style>

Preference.Material is defined as:

<style name="Preference.Material">
<item name="android:layout">@layout/preference_material</item>
</style>

The layout for the preference is preference_material.xml. Here is the source.

The following section of this layout interests us:

...
<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>
...

As you can see, the top and bottom padding for the RelativeLayout is hard-coded. Since a style attribute is not used, there is no way to override the padding. Because of this hard-coding, you have two choices:

  1. Use the "really bad workaround" outlined in the answer you found which involves Java code to modify the padding, or,

  2. Use your own layout by defining android:layout="@layout/custom_preference" in the XML for your preferences. You can copy the Android layout and make your modifications.

Each method has drawbacks, so pick the one you think you can best deal with.


The following are key components of a small app that demonstrates substitution of the preference layout.

MainActivity.java
This activity rolls in the preference fragment for convenience.

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
Simply defines a home for the preference fragment.

<?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
Some modification have been made to accommodate usage of this file mainly updated ?attr/somthing to ?android:attr/something.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Layout for a Preference in a PreferenceActivity. The
Preference is able to place a specific widget for its particular
type in the "widget_frame" layout. -->

<!-- Modified from the original to accommodate usage as a local layout file. -->
<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>
<!-- 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:gravity="end|center_vertical"
android:orientation="vertical"
android:paddingStart="16dp" />
</LinearLayout>

Gradle file

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'
}

Preference Activity white margin on large screens

addPreferencesFromResource method is deprecated in API 11 and higher. Try to use a PreferenceFragment and override onCreateView like this:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
if(v != null) {
ListView lv = (ListView) v.findViewById(android.R.id.list);
lv.setPadding(10, 10, 10, 10);
}
return v;
}

This code is taken from this response:
Android: How to maximize PreferenceFragment width (or get rid of margin)?

PreferenceFragmentCompat adds margin to preference items

If you are using AndroidX, you can use Preference.setIconSpaceReserved(boolean iconSpaceReserved) method.

So, you will have:

item_Confirmation.setIconSpaceReserved(false);

You can also check this answer.



Related Topics



Leave a reply



Submit