Як додати кнопку до 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.