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

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);
smisiewicz
sumber
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!

herbert
sumber
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();
Sileria
sumber
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

Danield
sumber
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
19

Di Kotlin, Anda dapat menggunakan ekstensi ktx :

yourView.updateLayoutParams {
   height = <YOUR_HEIGHT>
}
Phil
sumber
2
Ini luar biasa!
user1032613
6

coba yang ini:

...
View view = inflater.inflate(R.layout.active_slide, this);
view.setMinimumWidth(200);
zed_0xff
sumber
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
sumber
@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;
                            }
                        });
AkhilGite
sumber
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;
Aplikasi DazzleGifts
sumber
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.

Xar-e-ahmer Khan
sumber
1

jika Anda mengganti onMeasure, jangan lupa untuk memperbarui ukuran baru

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(newWidth, newHeight);
}
XurajB
sumber
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();
Kelas A
sumber
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.

us_david
sumber