Як додати кнопку до PreferenceScreen


106

Чи є спосіб додати кнопку до нижнього екрана налаштувань і змусити їх працювати правильно під час прокрутки?


2
Ви подивилися на створення спеціальних уподобань?
— Прашаст

2
Для майбутніх відвідувачів, поки рішення Макса працює, є альтернативне рішення: stackoverflow.com/a/7251575/802469
— Рід

Відповіді:


249

Існує ще одне рішення для налаштування зовнішнього вигляду уподобань.

Створіть звичайний макет XML за допомогою кнопок або будь-чого, що ви хочете додати до стандартних налаштувань. Включіть ListViewу свій макет і вкажіть його ідентифікатор @android:id/list.

Скажімо, ми називаємо файл макета res/layout/main.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="match_parent"
              android:orientation="vertical">
    <Button android:text="This is a button on top of all preferences."
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    <ListView android:id="@android:id/list"
              android:layout_width="match_parent"
              android:layout_height="wrap_content" />
</LinearLayout>

У ваших PreferenceActivity, додайте ці два рядки в onCreate:

addPreferencesFromResource(R.xml.preferences);
setContentView(R.layout.main);

Потім ListViewу вашому макеті буде замінено налаштування, визначені звичайним способом res/xml/preferences.xml.


10
Не працює, якщо кнопка розміщена під переглядом списку. Не працює, коли в налаштуваннях використовується тема діалогу.
— Грег Енніс

11
В останній документації щодо використання PreferenceActivity на developer.android.com/reference/android/preference/… згадується, що для всіх нових розробок PreferenceFragment є кращим способом реалізації. Здається, що дане рішення не працюватиме за таким сценарієм.
— Панкай

4
Він все ще не прокручується зі списком.
— Sudarshan Bhat

7
Мене трохи бентежить, скільки голосів має ця відповідь, оскільки вона насправді не відповідає на початкове запитання. Він не прокручується зі списком і не працює, коли кнопка розміщена в нижній частині вікна, як зазначено в коментарях вище.
— howettl

1
@howettl просто змініть fill_parent на wrap_content у ListView layout_height
— Martin Ch

56

Я знаю, що це трохи пізно, але я просто знайшов рішення, яке мені подобається краще, ніж похвальне рішення Макса.

Ви можете просто додати колонтитул (або якщо вам подобається, що кнопка знаходиться вгорі, заголовок) до списку PreferenceActivity's ListView так:

public class MyActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        ListView v = getListView();
        v.addFooterView(new Button(this));
    }
}

Я сподіваюся, що це комусь допоможе.


2
Принаймні, це краще, ніж рішення Макса, оскільки воно не покладається на ідентифікатор елемента. Подивимося, як він поводиться у майбутніх версіях Android ...
— Daniel F

@DanielF. не переступайте через міст, поки не дістанетесь до нього;)
— jpihl

1
Я не можу отримати програму ListViewPreferenceFragment :(
— Michał K

1
Ні, це не працюватиме так (тому що PreferenceFragmentмає свій список), але я вирішив це, просто створивши Preferenceі встановивши Intentна нього. Не потрібно було створювати кнопку (принаймні в моєму випадку)
— Michał K

1
Не працює з PreferenceFragmentCompat, оскільки getListView фактично поверне RecyclerView
— Mauker

11

Цей приклад нижче відобразить кнопку внизу сторінки (якщо хтось все ще зацікавлений).

У випадку LinearLayout ви також можете застосувати ваги; це потрібно, оскільки для перегляду списку встановлено значення * fill_parent *. Зазвичай я це роблю, додаючи * android: layout_weight * 's:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical">
    <ListView android:id="@android:id/list"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent" android:layout_weight="10"/>
    <Button android:text="This is a button on top of all preferences."
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:layout_weight="1"/>
</LinearLayout>

Наведене нижче пояснення не може бути 100%, але це допоможе вам зрозуміти ...

+-- View Port (linear layout)
| +-- List View (this is where the preferences will go)
| |
| |
| +--
+--
  +--
  | Button (which was pushed out of view by the fillparent of ListView
  +--

Ви також можете сказати, тому що кнопка не має ваги; кнопка відображається на висоті 0dp.

Тепер, коли додано layout_weigths, це дозволить відобразити кнопку перегляду

+-- View Port (linear layout)
| +-- List View (this is where the preferences will go)
| |
| |
| +--
| +--
| | Button (which was pushed out of view by the fillparent of ListView
| +--
+--

Вибачте, пропустив пост @stealthcopter
— Ронні

7

Власне, рішення є. Ось код, я сподіваюся, це буде корисно для будь-кого. Схоже, 3 варіанти та 2 кнопки в нижній частині екрана, незалежно від роздільної здатності екрана (було націлено на 240 як найнижчий)

package com.myapplication.gui;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.view.Display;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import com.myproject.general.HeightListView;

import com.myapplication.R;

public class FilterActivity extends PreferenceActivity {

    private LinearLayout rootView; 
    private LinearLayout buttonView; 
    private Button buttonDone;
    private Button buttonRevert;
    private ListView preferenceView; 
    private LinearLayout gradientView;
    private ScrollView scrollRoot;

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

        Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
        int height = display.getHeight();
        int width = height > 240 ? display.getWidth() : display.getWidth() - 4;

        scrollRoot = new ScrollView(this);
        scrollRoot.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

        rootView = new LinearLayout(this); 
        rootView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
        rootView.setOrientation(LinearLayout.VERTICAL);

        buttonView = new LinearLayout(this); 
        buttonView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        buttonView.setOrientation(LinearLayout.HORIZONTAL);
        buttonView.setGravity(Gravity.BOTTOM);

        gradientView = new LinearLayout(this);
        gradientView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        gradientView.setOrientation(LinearLayout.HORIZONTAL);
        gradientView.setBackgroundResource(R.drawable.gradient);
        gradientView.setPadding(0, 5, 0, 0);
        gradientView.setBackgroundResource(R.drawable.gradient);

        buttonDone = new Button(this); 
        buttonDone.setText(R.string.filterButton_Done); 
        buttonDone.setLayoutParams(new LayoutParams(width/2, LayoutParams.WRAP_CONTENT));
        gradientView.addView(buttonDone);

        buttonRevert = new Button(this); 
        buttonRevert.setText(R.string.filterButton_Revert);
        buttonRevert.setLayoutParams(new LayoutParams(width/2, LayoutParams.WRAP_CONTENT));
        gradientView.addView(buttonRevert);

        buttonView.addView(gradientView);

        preferenceView = new HeightListView(this); 
        preferenceView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); 
        preferenceView.setId(android.R.id.list); 

        PreferenceScreen screen = createPreferenceHierarchy(); 
        screen.bind(preferenceView); 
        preferenceView.setAdapter(screen.getRootAdapter()); 
        rootView.addView(preferenceView);
        rootView.addView(buttonView);

        if (height > 240) {
            this.setContentView(rootView);
        }
        else {
            scrollRoot.addView(rootView);
            this.setContentView(scrollRoot);
        }

        setPreferenceScreen(screen); 
    } 

    private PreferenceScreen createPreferenceHierarchy() {        
        PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);

        PreferenceScreen pref1 = getPreferenceManager().createPreferenceScreen(this);
        pref1.setKey("pref1");
        pref1.setTitle("Title");
        pref1.setSummary("Summary");
        root.addPreference(pref1); 

        PreferenceScreen pref2 = getPreferenceManager().createPreferenceScreen(this);
        pref2.setKey("pref2");
        pref2.setTitle("Title");
        pref2.setSummary("Summary");
        root.addPreference(pref2); 

        PreferenceScreen pref3 = getPreferenceManager().createPreferenceScreen(this);
        pref3.setKey("pref3");
        pref3.setTitle("Title");
        pref3.setSummary("Summary");
        root.addPreference(pref3); 

        return root; 
    } 
}

2

Вам просто потрібно використовувати PreferenceFragment всередині загальної діяльності та додати кнопку до макета діяльності.

public class SettingActivity extends Activity {

    UserProfileViewModel userProfileViewModel = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_setting);
        getFragmentManager().beginTransaction()
                .replace(R.id.content, new SettingsFragment())
                .commit();

    }

    private class SettingsFragment extends PreferenceFragment {
        public SettingsFragment() {
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // Load the preferences from an XML resource
            addPreferencesFromResource(R.xml.pref_main);

        }
    }
}

SettingActivity.java

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/buttonSave"/>

    <Button
        android:id="@+id/buttonSave"
        android:text="Save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />
</RelativeLayout>

activity_setting

введіть тут опис зображення


Я дотримувався цієї пропозиції, і вона відображає кнопку в нижній частині вікна, але вона накладається зверху на список налаштувань і її не можна натискати (тобто натискання кнопки активує лише пункт переваги внизу).
— iaindownie

Кнопка onClickListener не запускається за допомогою цього рішення
— rdehuyss

@rdehuyss це тому, що вам потрібно додати onClickListener до buttonSave:)
— Альберт

1

Так би виглядав код у діяльності на прикладі роні. Моя мета полягала в тому, щоб розмістити меню в нижній частині екрана.

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.prefs);
    addPreferencesFromResource(R.xml.prefs);

   /* LayoutInflater CX = getLayoutInflater();
    CX.inflate(R.layout.main,null);*/
    // TODO Auto-generated method stub
}

1
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="@dimens/listview_height" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="This is a button on top of all preferences." />
</RelativeLayout>

Я посилаюся на @Ronnie, використовую RelativeLayout і встановлюю висоту для layout_height of listview, а потім встановлюю layout_alignParentBottom = "true", кнопка може відображати кнопку внизу PreferenceScreen; потім скористайтеся способом @Max. це працює для моїх потреб.


Це приємне рішення, але ви забули встановити перегляд списку над кнопкою. В даний час елементи перегляду списку можуть бути за кнопкою, що не рекомендується, оскільки якщо це останній елемент, він ніколи не буде видно і, отже, натискати.
— андроїд розробник

о, так, ви маєте рацію, я забув цей випадок, тому що мій списокпереглянув лише 5 пунктів, дякую.
— Меджонжан

оновіть свою відповідь, щоб інші не мали такої поведінки.
— андроїд розробник

Я думаю, ви також забули деякі атрибути та кінцевий тег RelaLayout.
— андроїд розробник

Насправді, встановлення потрібного listview_height може вирішити проблему, про яку ви сказали.
— Меджонжан

1

Також можна додати кнопки Дії на панель дій для стандартного підходу для Android.

public class PrefActivity extends PreferenceActivity{

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu items for use in the action bar
      MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.preference_header_menu, menu);
      return super.onCreateOptionsMenu(menu);
  }

}


    <?xml version="1.0" encoding="utf-8"?>
       <menu xmlns:android="http://schemas.android.com/apk/res/android">
       <item android:id="@+id/action_add"
           android:icon="@drawable/ic_menu_add_dark"
           android:title="@string/menu_action_add_title"
           android:showAsAction="always"  />

   </menu>

0

Спеціальний вигляд у налаштуваннях "Налаштування", це допоможе додати користувацький вигляд у PreferenceActivity в Android.

Створіть main.xml, єдиний необхідний перегляд - це ListView, з id : android:id="@android:id/list".

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:weightSum="1">
        <ListView 
            android:id="@android:id/list" 
            android:layout_weight="1"
            android:layout_width="fill_parent"
                android:layout_height="0dp">
        </ListView>
        <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Створіть CustomPreferenceActivity.java

public class CustomPreferenceActivity extends PreferenceActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                addPreferencesFromResource(R.xml.settings);

                //setup any other views that you have
                TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("View Added");
        }
}

0

Далі наведено просте рішення, щоб додати кнопку, що можна натискати, на екран налаштувань. Це стає простим, оскільки налаштування вже резервують простір в android: widgetLayout і кнопка можуть передавати кліки за допомогою android: onClick.

Спочатку створіть button.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="match_parent">
<Button
    android:text="BUTTON"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/button"
    android:onClick="onButtonClick"/>
</LinearLayout>

Тепер у свої preferences.xml додайте налаштування

<Preference
    android:key="button"
    android:title="Title"
    android:summary="Summary"
    android:widgetLayout="@layout/button" />

Тепер ваша функція PreferenceActivity має містити лише onButtonClick

public class MainActivity extends PreferenceActivity {

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

    addPreferencesFromResource(R.xml.main_preferences);


}

public void onButtonClick(View v) {
    Log.d("Button", "Yeah, button was clicked");
}
}

0

preferences.xml:

    <Preference
        android:key="clearAllData"
        android:title="@string/settings_clear_all_data">
    </Preference>

SettingsFragment.java:

public class SettingsFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);

        Preference clearAllData = (Preference) findPreference("clearAllData");

        // setup buttons
        final Context context = getActivity();
        clearAllData.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {

            @Override
            public boolean onPreferenceClick(Preference preference) {
                ...
            }
    }

}

0

Я виявив, що всі перераховані вище відповіді непридатні для використання, оскільки будь-які макети, створені для "загортання" PreferenceScreenконтейнера всередині спеціальних макетів (потім додавання кнопки внизу ListView), насправді не спрацювали.

Вони лише накладають користувальницький макет у верхній частині списку налаштувань (плаваючий), а натискання (наприклад) нової спеціальної кнопки лише викликає налаштування під кнопкою.

Однак я знайшов це рішення, яке працює як додавання кнопки під контейнером списку налаштувань під час використання PreferenceFragment.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.