Tetapkan margin dalam LinearLayout secara terprogram


266

Saya mencoba menggunakan Java ( bukan XML ) untuk membuat LinearLayout dengan tombol yang mengisi layar, dan memiliki margin. Berikut adalah kode yang berfungsi tanpa margin:

LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
for (int r = 0; r < 6; ++r) {
    Button btn = new Button(this);
    btn.setText("A");

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); // Verbose!
    lp.weight = 1.0f; // This is critical. Doesn't work without it.
    buttonsView.addView(btn, lp);
}

ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
setContentView(buttonsView, lp);

Jadi itu berfungsi dengan baik, tapi bagaimana Anda memberi Anda margin tombol sehingga ada ruang di antara mereka? Saya mencoba menggunakan LinearLayout.MarginLayoutParams, tetapi itu tidak memiliki weightanggota sehingga tidak baik. Dan itu tidak berfungsi jika Anda memasukkannya lpdalam konstruktornya juga.

Apakah ini tidak mungkin? Karena sudah pasti terlihat, dan itu bukan tugas tata letak Android pertama yang hanya dapat Anda lakukan dalam XML.


1
developer.android.com/reference/android/view/… , int, int, int) Alih-alih layoutParams.setMargins (30, 20, 30, 0); Anda meletakkan layoutParams.setMargins (30dp, 20dp, 30dp, 0dp);
DarthestVader

3
setMargins mengambil int sebagai argumen .. Anda hanya dapat memberikan "dp" menggunakan atribusi xml
jyavenard

Jawaban:


496

Berikut adalah sedikit kode untuk mencapainya:

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
     LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

layoutParams.setMargins(30, 20, 30, 0);

Button okButton=new Button(this);
okButton.setText("some text");
ll.addView(okButton, layoutParams);

6
terima kasih untuk contoh kode to-the-point - jauh lebih bermanfaat daripada sekadar deskripsi
Seseorang di suatu tempat

25
Sepertinya margin margin diatur dalam piksel. Adakah cara untuk mengaturnya dalam dps?
Artem Russakovskii

30
@ArtemRussakovskii Seperti kebanyakan fungsi di Android, mereka mengambil piksel. Saya menyarankan fungsi utilitas global yang mengubah dips ke px. Inilah yang telah saya lakukan di semua aplikasi saya. API Android menyebalkan.
mxcl

7
@ MaxHowell Itulah yang akhirnya saya lakukan. Sungguh luar biasa bahwa hal-hal dasar seperti itu kadang-kadang hilang.
Artem Russakovskii

5
@ArtemRussakovskii - gunakan TypedValue.applyDimension (...) untuk mengonversi DIP ke PX. Lihat stackoverflow.com/questions/2238883/…
Gautam

64

Jadi itu berfungsi dengan baik, tapi bagaimana Anda memberi Anda margin tombol sehingga ada ruang di antara mereka?

Anda menelepon setMargins()pada LinearLayout.LayoutParamsobjek.

Saya mencoba menggunakan LinearLayout.MarginLayoutParams, tetapi itu tidak memiliki anggota berat sehingga tidak baik.

LinearLayout.LayoutParamsadalah subkelas dari LinearLayout.MarginLayoutParams, sebagaimana ditunjukkan dalam dokumentasi .

Apakah ini tidak mungkin?

Tidak.

itu bukan tugas tata letak Android pertama yang hanya dapat Anda lakukan dalam XML

Anda dipersilakan untuk memberikan bukti klaim ini.

Secara pribadi, saya tidak mengetahui apa pun yang hanya dapat dicapai melalui XML dan tidak melalui metode Java di SDK. Bahkan, menurut definisi, semuanya harus bisa dilakukan melalui Java (walaupun tidak harus melalui metode SDK-reachable), karena XML bukan kode yang dapat dieksekusi. Tetapi, jika Anda mengetahui sesuatu, tunjukkan, karena itu adalah bug di SDK yang harus diperbaiki suatu hari nanti.


2
Ha, oke saya mengerti sekarang. Semakin sedikit tersesat dalam tata letak sistem yang agak rumit. Saya tidak berpikir ada pula untuk mengatur layout_widgth / tinggi saat runtime.
Timmmm

2
Dan tidak ada cara untuk mengatur gaya: stackoverflow.com/questions/2016249/...
Timmmm

1
Saya belum punya masalah dengan pengaturan lebar dan tinggi saat runtime via LayoutPararms. Saya suka gaya ... ya, well, ada alasan saya tidak menggunakannya. :-)
CommonsWare

6
Saya ingin tahu mengapa ini seperti PITA yang secara terprogram menghasilkan UI
Seseorang di suatu tempat

3
Butuh waktu lama bagi saya untuk menyadari, bahwa ternyata beberapa hari yang lalu saya mengimpor LayoutParams yang salah yang tidak mendukung Margin ... Membaca jawaban ini saya memutuskan untuk menghapus impor saya. Ada lebih dari 10 opsi D: Saya menggunakan linearLayout.LayoutParams. Bekerja
Doomsknight

31

Untuk menambahkan margin secara langsung ke item (beberapa item memungkinkan pengeditan margin secara langsung), Anda dapat melakukan:

LayoutParams lp = ((ViewGroup) something).getLayoutParams();
if( lp instanceof MarginLayoutParams )
{
    ((MarginLayoutParams) lp).topMargin = ...;
    ((MarginLayoutParams) lp).leftMargin = ...;
    //... etc
}
else
    Log.e("MyApp", "Attempted to set the margins on a class that doesn't support margins: "+something.getClass().getName() );

... ini berfungsi tanpa perlu tahu tentang / mengedit tata letak di sekitarnya. Perhatikan cek "instanceof" jika Anda mencoba dan menjalankan ini terhadap sesuatu yang tidak mendukung margin.


2
Persis yang saya cari.
djdance

21

Karena variasi dalam kerapatan piksel layar perangkat, ada baiknya untuk selalu menggunakan DIPunit untuk mengatur margin secara terprogram. Seperti di bawah ini_

//get resources
Resources r = getResources();
float pxLeftMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxTopMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxRightMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxBottomMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());

//get layout params...
LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.setMargins(Math.round(pxLeftMargin), Math.round(pxTopMargin), Math.round(pxRightMargin), Math.round(pxBottomMargin));

//set margin...
yourLayoutTOsetMargin.setLayoutParams(params); 

Semoga ini bisa membantu.


10

Saya telah mengatur margin secara langsung menggunakan kode di bawah ini

LinearLayout layout = (LinearLayout)findViewById(R.id.yourrelative_layout);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);            
params.setMargins(3, 300, 3, 3); 
layout.setLayoutParams(params);

Satu-satunya hal di sini adalah pemberitahuan yang LayoutParamsharus diimpor untuk paket berikut android.widget.RelativeLayout.LayoutParams, atau ada kesalahan.


7

Coba ini

 LayoutParams params = new LayoutParams(
            LayoutParams.WRAP_CONTENT,      
            LayoutParams.WRAP_CONTENT
    );
    params.setMargins(left, top, right, bottom);
    yourbutton.setLayoutParams(params);

7
 MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
 layoutParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);

2
“Meskipun kode ini dapat menjawab pertanyaan, lebih baik untuk memasukkan penjelasan kode di sini.
xenteros

4

Coba ini:

MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
params.width = 250;
params.leftMargin = 50;
params.topMargin = 50;

3
/*
 * invalid margin
 */
private void invalidMarginBottom() {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) frameLayoutContent.getLayoutParams();
    lp.setMargins(0, 0, 0, 0);
    frameLayoutContent.setLayoutParams(lp);
}

Anda harus mengetahui jenis viewGroup view.Pada kode di atas, misalnya, saya ingin mengubah margin frameLayout, dan grup view frameLayout adalah RelativeLayout, jadi Anda perlu untuk menyamar menjadi (RelativeLayout.LayoutParams)


0

Di sini Solusi satu baris:

((LinearLayout.LayoutParams) yourLinearLayout.getLayoutParams()).marginToAdd = ((int)(Resources.getSystem().getDisplayMetrics().density * yourDPValue));
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.