Bagaimana cara menambahkan tombol ke PreferenceScreen

106

Adakah cara untuk menambahkan tombol ke bagian bawah layar preferensi dan membuatnya berfungsi dengan benar saat menggulir?

vlaku
sumber
2
Sudahkah Anda melihat cara membuat preferensi khusus?
Prashast
2
Untuk pengunjung di masa mendatang, saat solusi Max berfungsi, ada solusi alternatif: stackoverflow.com/a/7251575/802469
Reed

Jawaban:

249

Ada solusi lain untuk menyesuaikan tampilan preferensi.

Rancang tata letak XML normal dengan tombol atau apa pun yang ingin Anda tambahkan ke preferensi standar. Sertakan a ListViewdalam tata letak Anda dan berikan ID tersebut @android:id/list.

Katakanlah kita memanggil file layout res/layout/main.xml. Ini bisa terlihat seperti ini:

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

Di Anda PreferenceActivity, tambahkan dua baris ini ke Anda onCreate:

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

Dalam ListViewtata letak Anda kemudian akan diganti dengan preferensi yang ditentukan dengan cara biasa res/xml/preferences.xml.

Max
sumber
10
Tidak berfungsi ketika tombol ditempatkan di bawah tampilan daftar. Tidak berfungsi saat aktivitas preferensi menggunakan tema dialog.
Greg Ennis
11
Dokumentasi terbaru tentang penggunaan PreferenceActivity di developer.android.com/reference/android/preference/… menyebutkan bahwa untuk semua pengembangan baru PreferenceFragment adalah cara yang lebih disukai untuk diterapkan. Tampaknya solusi yang diberikan tidak akan berfungsi dalam skenario seperti itu.
Pankaj
4
Itu masih tidak bergulir dengan daftar.
Sudarshan Bhat
7
Saya sedikit bingung dengan berapa banyak suara yang dimiliki jawaban ini karena tidak benar-benar menjawab pertanyaan asli. Itu tidak menggulir dengan daftar, dan tidak berfungsi ketika tombol ditempatkan di bagian bawah tampilan, seperti yang disebutkan dalam komentar di atas.
howettl
1
@howettl hanya mengubah fill_parent ke wrap_content di ListView layout_height
Martin Ch
56

Saya tahu ini agak terlambat, tetapi saya baru saja menemukan solusi yang saya suka lebih baik daripada solusi Max yang dipuji.

Anda cukup menambahkan footer (atau jika Anda ingin tombol berada di atas, sebuah header) ke ListView PreferenceActivity seperti ini:

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));
    }
}

Saya harap ini membantu seseorang.

jpihl
sumber
2
Setidaknya ini terasa lebih baik sebagai solusi Max karena tidak bergantung pada id elemen. Mari kita lihat bagaimana perilakunya di versi Android yang akan datang ...
Daniel F
@Tokopedia jangan menyeberangi jembatan sampai Anda mendapatkannya;)
jpihl
1
Saya tidak bisa mendapatkan ListViewdengan PreferenceFragment :(
Michał K
1
Tidak, ini tidak akan berfungsi seperti itu (karena PreferenceFragmentmemiliki daftarnya sendiri), tetapi saya menyelesaikannya hanya dengan membuat Preferencedan menetapkan Intentdi atasnya. Tidak perlu membuat tombol (setidaknya dalam kasus saya)
Michał K
1
Tidak berfungsi dengan PreferenceFragmentCompat, karena getListView sebenarnya akan mengembalikan RecyclerView
Mauker
11

Contoh di bawah ini akan membuat tombol di bagian bawah halaman (jika ada yang masih tertarik).

Dalam kasus LinearLayout Anda juga bisa menerapkan bobot; ini diperlukan karena Listview disetel ke * fill_parent *. Saya biasanya melakukan ini dengan menambahkan * android: layout_weight *:

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

Penjelasan di bawah ini tidak mungkin 100% tetapi akan membantu Anda memahami ...

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

Bisa juga dibilang, karena Button tidak memiliki bobot; tombol dirender pada ketinggian 0dp.

Sekarang dengan menambahkan layout_weigths, tombol akan menampilkan tampilan

+-- 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
| +--
+--
Ronnie
sumber
Maaf melewatkan kiriman @stealthcopter
Ronnie
7

Sebenarnya ada solusinya. Ini kodenya, semoga bermanfaat bagi siapa saja. Sepertinya 3 opsi dan 2 tombol di bagian bawah layar, terlepas dari resolusi layar (ditargetkan 240 sebagai terendah)

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; 
    } 
}
vlaku
sumber
2

Anda hanya perlu menggunakan PreferenceFragment di dalam General Activity dan menambahkan tombol ke dalam layout aktivitas.

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

masukkan deskripsi gambar di sini

Albert
sumber
Saya mengikuti saran ini, dan itu memang menampilkan tombol di bagian bawah tampilan, tetapi itu ditumpangkan di atas daftar preferensi dan tidak dapat diklik (yaitu mengklik tombol hanya mengaktifkan item preferensi di bawahnya).
iaindownie
Tombol onClickListener tidak diaktifkan menggunakan solusi ini
rdehuyss
@rdehuyss karena Anda perlu menambahkan onClickListener ke buttonSave:)
Albert
1

Ini akan menjadi seperti apa kodenya dalam aktivitas di contoh ronny. Maksud saya adalah meletakkan menu di sisi bawah layar.

/** 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
}
pengguna507410
sumber
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>

Saya mereferensikan @Ronnie, menggunakan RelativeLayout dan menyetel ketinggian untuk layout_height listview, lalu menyetel tombol layout_alignParentBottom = "true", Ini dapat membuat tombol di bagian bawah PreferenceScreen; lalu gunakan cara @Max. itu bekerja untuk kebutuhan saya.

Mejonzhan
sumber
Ini adalah solusi yang bagus, tetapi Anda lupa menyetel tampilan daftar di atas tombol. saat ini, item listview mungkin berada di belakang tombol, yang tidak disarankan karena jika ini adalah item terakhir, item tersebut tidak akan pernah terlihat dan karenanya dapat diklik.
Pengembang android
oh iya kamu benar saya lupa case ini karena listview saya cuma 5 item makasih.
Mejonzhan
perbarui jawaban Anda, sehingga orang lain tidak akan memiliki perilaku ini.
Pengembang android
Saya rasa Anda juga lupa beberapa atribut dan tag akhir relativeLayout.
Pengembang android
Nyatanya, menyetel listview_height yang benar bisa menyelesaikan masalah yang Anda katakan.
Mejonzhan
1

Dimungkinkan juga untuk menambahkan tombol Tindakan ke bilah tindakan untuk pendekatan standar 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>
redevill
sumber
0

Tampilan kustom di Preference Activity ini akan membantu menambahkan tampilan kustom di PreferenceActivity di Android.

Buat main.xml, pandangan hanya diperlukan adalah ListView, dengan 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>

Buat 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");
        }
}
Ankit Singh
sumber
0

Berikut ini adalah solusi sederhana untuk menambahkan tombol yang dapat diklik ke layar preferensi Anda. Ini dipermudah karena preferensi sudah mencadangkan ruang di android: widgetLayout dan tombolnya dapat mengirimkan klik dengan android: onClick.

Pertama buat button.xml dengan konten

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

Sekarang di preferensi.xml Anda, tambahkan preferensi

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

PreferenceActivity Anda sekarang hanya harus berisi anggota 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");
}
}
ppareit
sumber
0

Preferensi.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) {
                ...
            }
    }

}
Dmitry
sumber
0

Saya menemukan semua jawaban di atas tidak dapat digunakan karena tata letak apa pun yang saya buat untuk 'membungkus' PreferenceScreenwadah di dalam tata letak khusus (kemudian menambahkan tombol di bawah ListView) tidak benar-benar berfungsi.

Mereka hanya melapisi tata letak kustom di atas daftar preferensi (mengambang), dan mengklik (misalnya) tombol kustom baru hanya akan memanggil preferensi di bawah tombol.

Namun, saya menemukan solusi ini yang berfungsi baik untuk menambahkan tombol di bawah wadah daftar preferensi, saat menggunakan PreferenceFragment.

iaindownie
sumber