Як змінити розмір спеціального перегляду програмно?


164

Я кодую спеціальний вигляд, розширений з RelativeLayout, і я хочу його змінити в розмірі програмно. Як це зробити?

Спеціальний клас перегляду - це щось на кшталт:

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

Відповіді:


253

Android кидає виняток, якщо ви не переходите висоту чи ширину перегляду. Замість створення нового об'єкта LayoutParams використовуйте оригінальний, щоб збереглися всі інші задані параметри. Зауважте, що тип LayoutParams, повернутий getLayoutParams, - це тип батьківського макета, а не перегляд, який ви змінюєте.

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

2
Як згадує @HerbertD, я також отримую помилку, роблячи це, якщо я не використовую LinearLayout.LayoutParams, навіть через нього є відносний макет, який я змінюю за розміром.
Мартін Белхер - AtWrk

6
@Eigo Відповідно до документації на Android, LayoutParams передається батьківському виду, оскільки це вид, який відповідає за макет.
sstn

1
Чи варто перетворювати значення в dp або воно буде працювати.
Dory

Це також бажано, оскільки це дозволяє уникати екземплярів нового об'єкта LayoutParams
Стівен Кідсон

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

Проблема вирішена!

ПРИМІТКА. Обов’язково використовуйте батьківський макет LayoutParams. Моє є LinearLayout.LayoutParams!


3
Вут. Чому б вам не скористатисяRelativeLayout.LayoutParams?
nmr

1
Це не спрацювало для мене, я отримав для нього виключення з класу.
Tapan Thaker

4
@Tapan Thanker Використовуйте батьківський макет LayoutParams. І мій батьківський макет - LinearLayout.
herbertD

10
Я написав більш загальну версію цього: 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
Це відновить усі інші параметри до значень за замовчуванням. @smisiewicz відповідь краще.
Fran Marzoa

66

Це працює для мене:

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

7
Це набагато краще, ніж інші відповіді, оскільки цей код не вимагає знати точний тип батьківської ViewGroup.
Bart Burg

1
Чи знаєте ви, в чому різниця між викликом callLayout () та викликом setLayoutParams (парами)?
voghDev

2
setLayoutParams (парами) включає requestLayout ().
illusionJJ

44

Для чого варто сказати, що ви хотіли змінити розмір перегляду в незалежних пікселях пристрою ( dp ): -

Вам потрібно скористатися методом applyDimension, який називається , що є членом класу TypedValueдля перетворення з пікселів у dps. Тож якщо я хочу встановити висоту 150dp (скажімо) - тоді я можу це зробити:

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

де вираз: getResources().getDisplayMetrics()отримує щільність екрана / роздільну здатність


6
Замість жорсткого кодування вашого виміру ви також можете використовувати це для висоти в пікселях:float pixels = context.getResources().getDimensionPixelSize(R.dimen.card_height);
Francois Dermu

ця відповідь доречніша як правильна відповідь !. Спасибі
Юнус Кулиєв


6

спробуйте це:

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

Вибачте, що я не опублікував усі запитання, оскільки ви відповіли на нього. Тепер це все питання. Дякую!
herbertD

6

Ось більш загальна версія рішення вище від @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, ти буквально врятував мені день :)
Qasim

5

Я використовував цей спосіб для збільшення ширини користувацького перегляду

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

Я вирішив це таким чином .. У мене в основному простий перегляд всередині xml-файлу.

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

2
ха-ха, дуже наївний, але добре працюючий спосіб, проте я рекомендую зателефонувати на setLayoutParams (), щоб врешті-решт правильно розповсюдити зміни до можливих вкладених дітей, тому після оновлення .width та .height викликайте view.setLayoutParams (view.getLayoutParams ()) це також завжди
набирайте

@Bhargav Rao, чи можете ви мені допомогти з цієї теми: https://stackoverflow.com/q/44259342/6596724
tux-world

2

Якщо у вас є тільки two or three condition(sizes)тоді, ви можете використовувати @Overide, onMeasure як

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

І легко змінити розмір для цих умов у класі CustomView легко.


1

якщо ви переосмислите onMeasure, не забудьте оновити нові розміри

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

1

Ось як я цього досяг. У відповіді на Сілерія він / вона зробив наступне:

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

Це правильно, але він очікує, що ми зробимо висоту pixels, але я хотів дати так, dpщоб висота була, тому я додав:

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

Так буде виглядати приблизно так:

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

0

Ось що я зробив:

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

Якщо є група переглядів, до якої належить цей погляд, вам також може знадобитися зателефонувати на вашViewGroup.requestLayout (), щоб він набув чинності.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.