Come ridimensionare una vista personalizzata a livello di codice?


164

Sto codificando una vista personalizzata, estesa da RelativeLayout e desidero ridimensionarla a livello di codice, come posso fare?

la classe di visualizzazione personalizzata è simile a:

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

Risposte:


253

Android genera un'eccezione se non si riesce a superare l'altezza o la larghezza di una vista. Invece di creare un nuovo oggetto LayoutParams, utilizzare quello originale, in modo da mantenere tutti gli altri parametri impostati. Si noti che il tipo di LayoutParams restituito da getLayoutParams è quello del layout principale , non della vista che si sta ridimensionando.

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

2
Come menziona @HerbertD, ricevo anche un errore a meno che non utilizzi LinearLayout.LayoutParams, anche se è un RelativeLayout che sto ridimensionando.
Martin Belcher - AtWrk

6
@Eigo Secondo la documentazione di Android, LayoutParams viene passato alla vista padre, poiché questa è la vista responsabile del layout.
sabato

1
Se il valore in deve essere convertito in valore dp o funzionerebbe.
Dory,

Questo è anche preferibile in quanto evita inutilmente un'istanza di un nuovo oggetto LayoutParams
Stephen Kidson,

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

Problema risolto!

NOTA: assicurarsi di utilizzare il layout principale LayoutParams. Il mio è LinearLayout.LayoutParams!


3
Wut. Perché non dovresti usareRelativeLayout.LayoutParams?
nmr

1
Questo non ha funzionato per me, ho ottenuto un'eccezione per il cast di classe.
Tapan Thaker,

4
@Tapan Thanker Usa LayoutParams del layout principale. E il layout di My Parent è LinearLayout.
HerbertD

10
Ho scritto una versione più generica di questo: 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
Ciò ripristinerà tutti gli altri parametri ai valori predefiniti. La risposta di @smisiewicz è migliore.
Fran Marzoa,

66

Questo funziona per me:

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

7
Questo è molto meglio delle altre risposte perché questo codice non richiede di conoscere il tipo esatto del ViewGroup principale.
Bart Burg,

1
Sai qual è la differenza tra chiamare requestLayout () e chiamare setLayoutParams (params)?
voghDev,

2
setLayoutParams (params) include requestLayout ().
illusionJJ

44

Per quello che vale, supponiamo che tu voglia ridimensionare la vista in pixel indipendenti dal dispositivo ( dp ): -

Devi usare un metodo chiamato applyDimension, che è un membro della classe TypedValueper convertire da pixel a dps. Quindi, se voglio impostare l'altezza su 150dp (diciamo), allora potrei farlo:

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

dove l'espressione: getResources().getDisplayMetrics()ottiene la densità / risoluzione dello schermo


6
Invece di codificare con forza la tua dimensione puoi anche usarla per l'altezza in pixel:float pixels = context.getResources().getDimensionPixelSize(R.dimen.card_height);
Francois Dermu,

questa risposta è più appropriata come risposta corretta !. Grazie
Yunus Kulyyev il


6

prova questo:

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

Mi dispiace non ho pubblicato tutte le domande da quando hai risposto. Questa è l'intera domanda. Grazie!
HerbertD

6

Ecco una versione più generica della soluzione sopra da @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, mi hai letteralmente salvato la giornata :)
Qasim

5

Ho usato questo modo per aumentare la larghezza della vista personalizzata

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

L'ho risolto in questo modo .. Ho sostanzialmente una vista semplice all'interno del file XML.

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

2
haha, un modo molto ingenuo ma ben funzionante, tuttavia consiglio di chiamare setLayoutParams () alla fine per propagare correttamente il cambiamento ai possibili figli annidati, quindi dopo l'aggiornamento di .width e .height, chiama view.setLayoutParams (view.getLayoutParams ()) anche questo è digitare sempre proof
comeGetSome

@Bhargav Rao potresti aiutarmi su questo argomento: https://stackoverflow.com/q/44259342/6596724
tux-world,

2

Se hai solo two or three condition(sizes)allora puoi usare @Overide onMeasure come

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

E modifica facilmente le dimensioni per queste condizioni nella classe CustomView.


1

se hai la precedenza onMeasure, non dimenticare di aggiornare le nuove dimensioni

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

1

Questo è come l'ho raggiunto. In Sileria risponde ha fatto quanto segue:

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

Questo è corretto, ma ci si aspetta di dare l'altezza pixels, ma volevo dare dpl'altezza desiderata, quindi ho aggiunto:

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

Quindi sarà simile a questo:

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

0

Questo è quello che ho fatto:

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

Se esiste un gruppo di viste a cui appartiene questa vista, potrebbe essere necessario chiamare yourViewGroup.requestLayout () affinché abbia effetto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.