Bagaimana cara mengubah ukuran tampilan kustom secara terprogram?


164

Saya mengode tampilan kustom, diperpanjang dari RelativeLayout, dan saya ingin mengubah ukurannya secara terprogram, Bagaimana saya bisa melakukannya?

Kelas tampilan kustom adalah sesuatu seperti:

public ActiveSlideView(Context context, AttributeSet attr){
        super(context, attr);
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if(inflater != null){       
            inflater.inflate(R.layout.active_slide, this);
        }

Jawaban:


253

Android melempar pengecualian jika Anda gagal melewati ketinggian atau lebar tampilan. Alih-alih membuat objek LayoutParams baru, gunakan yang asli, sehingga semua parameter set lainnya disimpan. Perhatikan bahwa jenis LayoutParams yang dikembalikan oleh getLayoutParams adalah dari tata letak induk , bukan tampilan yang Anda ubah ukurannya.

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) someLayout.getLayoutParams();
params.height = 130;
someLayout.setLayoutParams(params);

2
Seperti @HerbertD menyebutkan saya juga mendapatkan kesalahan melakukan ini kecuali saya menggunakan LinearLayout.LayoutParams, bahkan melalui itu adalah RelativeLayout yang saya ubah ukurannya.
Martin Belcher - AtWrk

6
@Eigo Menurut dokumentasi Android, LayoutParams diteruskan ke tampilan induk, karena ini adalah tampilan yang bertanggung jawab atas tata letak.
sstn

1
Apakah nilai in harus dikonversi menjadi nilai dp atau akan berhasil.
Dory

Ini juga lebih disukai karena menghindari instantiating objek LayoutParams baru yang tidak perlu
Stephen Kidson

129
this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, theSizeIWant));

Masalah terpecahkan!

CATATAN: Pastikan untuk menggunakan Layout induk LayoutParams. Milik saya LinearLayout.LayoutParams!


3
Wut. Mengapa Anda tidak menggunakanRelativeLayout.LayoutParams?
nmr

1
Ini tidak berhasil untuk saya, saya mendapat pengecualian pemain kelas untuk itu.
Tapan Thaker

4
@Tapan Terima Kasih Gunakan LayoutParams tata letak Parent. Dan tata letak Orang Tua saya adalah LinearLayout.
herbertD

10
Saya menulis versi yang lebih umum tentang ini: private void resizeView(View view, int newWidth, int newHeight) { try { Constructor<? extends LayoutParams> ctor = view.getLayoutParams().getClass().getDeclaredConstructor(int.class, int.class); view.setLayoutParams(ctor.newInstance(newWidth, newHeight)); } catch (Exception e) { e.printStackTrace(); } }
Atroutt

2
Ini akan mengatur ulang semua parameter lainnya ke nilai default. Jawaban @smisiewicz lebih baik.
Fran Marzoa

66

Ini bekerja untuk saya:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = customHeight;
layout.requestLayout();

7
Ini jauh lebih baik daripada jawaban lain karena kode ini tidak perlu mengetahui jenis persis ViewGroup induk.
Bart Burg

1
Apakah Anda tahu apa perbedaan antara memanggil requestLayout () dan memanggil setLayoutParams (params)?
voghDev

2
setLayoutParams (params) termasuk requestLayout ().
illusionJJ

44

Untuk apa nilainya, katakanlah Anda ingin mengubah ukuran tampilan dalam piksel independen perangkat ( dp ): -

Anda perlu menggunakan metode yang disebut applyDimension, yaitu anggota kelas TypedValueuntuk mengkonversi dari piksel ke dps. Jadi jika saya ingin mengatur ketinggian ke 150dp (katakanlah) - maka saya bisa melakukan ini:

float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150, getResources().getDisplayMetrics());
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) someLayout.getLayoutParams();
params.height = (int) pixels;
someLayout.setLayoutParams(params);

di mana ekspresi: getResources().getDisplayMetrics()mendapatkan kepadatan layar / resolusi


6
Alih-alih mengkodekan dimensi Anda, Anda juga dapat menggunakan ini untuk ketinggian dalam piksel:float pixels = context.getResources().getDimensionPixelSize(R.dimen.card_height);
Francois Dermu

jawaban ini lebih tepat sebagai jawaban yang benar !. Terima kasih
Yunus Kulyyev


6

coba yang ini:

...
View view = inflater.inflate(R.layout.active_slide, this);
view.setMinimumWidth(200);

Maaf saya belum mengirim semua pertanyaan sejak Anda menjawabnya. Nah, itu adalah seluruh pertanyaan. Terima kasih!
herbertD

6

Berikut versi yang lebih umum dari solusi di atas dari @herbertD:

private void resizeView(View view, int newWidth, int newHeight) { 
    try { 
        Constructor<? extends LayoutParams> ctor = view.getLayoutParams().getClass().getDeclaredConstructor(int.class, int.class); 
        view.setLayoutParams(ctor.newInstance(newWidth, newHeight));   
    } catch (Exception e) { 
        e.printStackTrace(); 
    }
}

@atroutt, Anda benar-benar menyelamatkan hari saya :)
Qasim

5

Saya menggunakan cara ini untuk meningkatkan lebar tampilan kustom

customDrawingView.post(new Runnable() {
                            @Override
                            public void run() {
                                View view_instance = customDrawingView;
                                android.view.ViewGroup.LayoutParams params = view_instance
                                        .getLayoutParams();
                                int newLayoutWidth = customDrawingView
                                        .getWidth()
                                        + customDrawingView.getWidth();
                                params.width = newLayoutWidth;
                                view_instance.setLayoutParams(params);
                                screenWidthBackup = params.width;
                            }
                        });

4

Saya menyelesaikannya dengan cara ini .. Saya pada dasarnya memiliki tampilan sederhana di dalam file xml.

 View viewname = findViewById(R.id.prod_extra);
             prodExtra.getLayoutParams().height=64;

2
haha, sangat naif tetapi cara kerjanya baik, namun saya sarankan untuk memanggil setLayoutParams () akhirnya untuk menyebarkan perubahan yang benar ke anak-anak yang mungkin bersarang, jadi setelah memperbarui. lebar dan .tinggi, panggil view.setLayoutParams (view.getLayoutParams ()) ini juga selalu ketikkan proof
comeGetSome

@Bhargav Rao dapatkah Anda membantu saya mengenai topik ini: https://stackoverflow.com/q/44259342/6596724
tux-world

2

Jika Anda hanya memiliki two or three condition(sizes)maka Anda dapat menggunakan @Overide onMeasure suka

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

Dan ubah ukuran Anda untuk kondisi ini di kelas CustomView dengan mudah.


1

jika Anda mengganti onMeasure, jangan lupa untuk memperbarui ukuran baru

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(newWidth, newHeight);
}

1

Beginilah cara saya mencapai ini. Dalam jawaban Sileria dia melakukan hal berikut:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = customHeight;
layout.requestLayout();

Ini benar, tetapi mengharapkan kita untuk memberikan ketinggian pixels, tapi saya ingin memberi dpsaya ingin ketinggian jadi saya menambahkan:

public int convertDpToPixelInt(float dp, Context context) {
    return (int) (dp * (((float) context.getResources().getDisplayMetrics().densityDpi) / 160.0f));
}

Jadi akan terlihat seperti ini:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = convertDpToPixelInt(50, getContext());
layout.requestLayout();

0

Inilah yang saya lakukan:

View myView;  
myView.getLayoutParams().height = 32;  
myView.getLayoutParams().width = 32;

Jika ada grup tampilan yang dimiliki oleh tampilan ini, Anda mungkin perlu memanggil yourViewGroup.requestLayout () agar dapat diterapkan.

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.