Tambahkan margin di atas item ListView teratas (dan di bawah yang terakhir) di Android

147

Ini adalah pertanyaan yang cukup bagus tentang tata letak item dalam ListView di Android.

Saya memiliki aktivitas dengan bilah judul di bagian atas dan ListView mengambil seluruh layar. Saya ingin ListView saya muncul dengan padding 10dp di kiri, kanan dan atas, tetapi ketika Anda menggulir ListView ke atas, saya ingin itu untuk menutup padding 10dp atas sebelum menghilang di bawah tepi pudar. Demikian pula, ketika Anda menggulir ke bawah, item daftar terakhir akan muncul dengan 10dp antara bagian bawah item daftar terakhir dan bagian bawah layar yang sebenarnya (jika Anda bertanya-tanya mengapa, itu karena ada gambar latar belakang yang cantik yang saya inginkan muncul di sekitar ListView).

Saya sudah mencoba menambahkan padding ke ListView itu sendiri, tetapi kemudian ketika Anda menggulir daftar itu menghilang di bawah tepi padding.

Saya dari latar belakang web dev, dan analoginya adalah menambahkan margin di atas item daftar pertama (dan di bawah item daftar terakhir).

Mick Byrne
sumber
tentukan hanya margin kiri & kanan ... coba tempel xml Anda di sini, jadi saya dapat melihat masalah edit: tunggu, maksud Anda .... Anda ingin bantalan atas dan bawah juga digulir?
Tek Yin
Saya tidak bisa menentukan margin kiri dan kanan - tidak ada 'margin' dalam tata letak Android, hanya padding. Tapi, ya, saya ingin bantalan atas dan bawah digulir - itu cara yang baik untuk menggambarkannya.
Mick Byrne
Saya sudah mencoba beberapa metode, dan masih gagal .. Saya punya beberapa trik untuk dilakukan, tetapi akan lebih sulit untuk melakukannya ... Anda meletakkan 2 objek kustom ke item daftar pada posisi pertama dan terakhir .. dan menggunakan adaptor khusus untuk mendeteksi item dan menggambarnya secara berbeda (tinggi sempit & transparan)
Tek Yin
Ya ... itulah yang saya pikirkan untuk mundur juga. Tetapi ada segala macam komplikasi dengan itu, karena saya kemudian perlu mengatur warna latar belakang dalam item daftar, bukan tampilan, yang berarti saya kemudian perlu secara manual meretas beberapa efek untuk ditampilkan ketika Anda mengetuk sesuatu. . Terima kasih atas bantuan Anda ...
Mick Byrne
Kabar baik .. Saya mendapatkan solusinya ... Anda dapat menggunakan addHeaderView (Lihat v) di ListActivity .. panggil saja getListView(). addHeaderView(capView)dan getListView(). addHeaderView(botView) pastikan itu dipanggil sebelum menginisialisasi isi daftar misalnya. setListAdapter (adaptor);
Tek Yin

Jawaban:

397

Kau menulis:

Saya sudah mencoba menambahkan padding ke ListView itu sendiri, tetapi kemudian ketika Anda menggulir daftar itu menghilang di bawah tepi padding.

Setel ListView's clipToPaddingatribut menjadi false. Ini akan memungkinkan padding di sekitar ListView dan menggulir ke ujung tata letak (dan tidak hanya ke tepi padding).

Sebuah contoh:

<ListView
    android:id="@+id/list_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:divider="@android:color/transparent"
    android:dividerHeight="10.0sp"
    android:padding="16dip"
    android:clipToPadding="false"/>

android:clipToPaddingadalah atribut XML dari ViewGroup, kelas dasar untuk layout dan tampilan wadah.

Panggilan metode terkait adalah:

public void setClipToPadding (boolean clipToPadding)
Gunnar Karlsson
sumber
4
Selain itu, ini dapat dibuat menjadi gaya atau tema melalui<item name="android:clipToPadding">false</item>
pjco
2
Oh, ini juga berlaku untuk ScrollView
pjco
4
Agak terlambat untuk diskusi, tetapi perhatikan bahwa pada perangkat yang lebih lama (saya melihatnya pada beberapa perangkat 2.3.x), tampilan daftar item didaur ulang terlalu cepat. Sementara fase menggambar tahu itu bisa menggambar di sana, fase tata letak tidak, sehingga mengira item sudah mati dari layar. Lihat stackoverflow.com/questions/15915226/… .
Jeffrey Klardie
@JeffreyKlardie Saya menemukan masalah ketika item didaur ulang terlalu cepat pada perangkat yang lebih lama dan bahkan membuat scrollbar mengubah ukurannya dengan cepat, yang terlihat sangat aneh. @ pjco Saya tidak yakin mengapa tetapi pengaturan clipToPaddingmelalui gaya tidak bekerja untuk saya, rasanya jika tidak diterapkan. Meskipun, jika saya mengaturnya langsung pada ListView itu berfungsi.
ForceMagic
5
Jangan lupa android:scrollbarStyle="outsideOverlay"juga bilah gulir melewati padding juga
jfcartier
19
View padding = new View(this);
padding.setHeight(20); // Can only specify in pixels unfortunately. No DIP :-(

ListView myListView = (ListView) findViewById(R.id.my_list_view);

myListView.addHeaderView(padding);
myListView.addFooterView(padding);

myListView.setAdapter(myAdapter);

ListView di atas akan memiliki header dan footer padding 20 piksel.

Jake Wilson
sumber
4
Terima kasih atas jawabannya! Bagus sekali !! Jika Anda ingin memberi ketinggian pada dp, hal itu dapat dilakukan dengan menggunakan DisplayMetrics: float mDensity = getResources().getDisplayMetrics().density; int height = (int) (50 * mDensity + 0.5f); padding.setHeight(height);
Tony Ceralva
3
Atau lebih baik lagi, dapatkan dimens dalam dp di tingkat Java menggunakan getResources (). GetDimensionPixelOffset (R.dimen.some_value);
greg7gkb
1
Benar-benar kagum pada berapa banyak hal Android yang saya pelajari di StackOverflow terhadap yang saya pelajari di situs pengembang
TrueCoke
1
Atau bahkan lebih baik(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
Eugen Pechanec
1
Tidak ada metode "setHeight ()" untuk Lihat di API 23. Sebaliknya kita dapat menggunakan "setMinimumHeight ()".
KWA
10

Tambahkan ke jawaban @ Jakobud ...

ListView saya sudah memanfaatkan android:divider/android:dividerHeightproperti untuk membuat celah transparan antara item listView. Hal ini memungkinkan saya untuk hanya menambahkan android:headerDividersEnableddan android:footerDividersEnabledproperti dan mengatur pandangan Header dan Footer untuk new View(Activity.this).

Penyederhanaan sedikit untuk kasus di mana Anda sudah memiliki pengaturan pembagi di listView.

greg7gkb
sumber
1
Saya akan menyarankan siapa pun jika memungkinkan untuk menggunakan pembagi, bukan dalam margin dan bantalan item. Jawaban bagus
dzsonni
2

Solusi saya menggunakan a ListFragment, berdasarkan solusi oleh @ Jakobud dan @ greg7gkb.

ListView listView = getListView();
listView.setDivider(null);
listView.setDividerHeight(getResources().getDimensionPixelSize(R.dimen.divider_height));
listView.setHeaderDividersEnabled(true);
listView.setFooterDividersEnabled(true);
View padding = new View(getActivity());
listView.addHeaderView(padding);
listView.addFooterView(padding);
hleinone
sumber
1

@Gunnar Karlsson jawaban baik, tetapi memiliki masalah pandangan sel yang didaur ulang sebelum waktunya ketika benar-benar di belakang padding, tetapi belum sepenuhnya dari layar. Pengaturan clipToPadding = false bertanggung jawab untuk ini dan mungkin atau mungkin tidak diperbaiki di versi android masa depan. ( Saat menggunakan clipToPadding di ListView, item-item tersebut didaur ulang sebelum waktunya )

Saya punya solusi sederhana yang bagus tanpa efek samping:

  1. Tambahkan Tata Letak luar (Linear atau Relatif) ke cell_design.xml Anda
  2. Pada Layout luar ini tambahkan padding (yaitu 10dip) untuk membuat "margin" di seluruh sel. (NB hanya padding yang berfungsi, bukan margin pada layout luar)
  3. Pada set ListView android:dividerHeight="-10dip", kebalikan dari apa yang ada di sekitar sel

Dibandingkan dengan jawaban yang lain, tidak perlu mengatur warna pembagi. Padding di sel paling atas dan bawah akan hadir, dan pembagi negatif akan mencegah pembagi tinggi ganda di antaranya.

James
sumber
"tanpa efek samping" itu tidak sepenuhnya benar. Menambahkan lapisan lain dalam hierarki tampilan Anda, terutama dalam item tampilan daftar, berarti menurunkan kinerja.
Teovald