2013-05-25 20 views
18

creo la mia classe per la pianta quadrata:Custom Square LinearLayout. Come?

public class SquareLayout extends LinearLayout{ 

    public SquareLayout(Context context) { 
     super(context); 
    } 

    public SquareLayout(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public SquareLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 


    @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     int width = MeasureSpec.getSize(widthMeasureSpec); 
     int height = MeasureSpec.getSize(heightMeasureSpec); 
     int size = width > height ? height : width; 
     setMeasuredDimension(size, size); 
    } 

Poi, nel mio xml:

... 
     <com.myApp.SquareLayout 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:layout_gravity="center_horizontal" 
      android:orientation="horizontal" > 

      <ImageView 
       android:id="@+id/cellImageView" 
       android:adjustViewBounds="true" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:layout_marginTop="2dp" 
       android:padding="2dp" 
       android:scaleType="centerCrop" 
       android:src="@drawable/image" /> 
     </com.myApp.SquareLayout> 
... 

Niente di scritto più nel mio codice Java. Ma invece se il mio layout e la mia immagine, vedo solo un rettangolo bianco ...

Cosa ho sbagliato?

+0

tag di apertura - ' ' ??? – Simon

+0

corretto :-) Grazie. – Geltrude

+0

Questo potrebbe aiutare http://www.gadgetsaint.com/tips/dynamic-square-rectangular-layouts-android/#.WRRjMvl96Hs – ASP

risposta

19

// si dimentica di chiamare super.onMisura (widthMeasureSpec, widthMeasureSpec);

@Override 
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

    super.onMeasure(widthMeasureSpec, widthMeasureSpec); 
    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = MeasureSpec.getSize(heightMeasureSpec); 
    int size = width > height ? height : width; 
    setMeasuredDimension(size, size); 

} 

// file XML

<com.example.testapplication.SquareLayout 
    android:id="@+id/layout" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:layout_gravity="center_horizontal" 
    android:orientation="horizontal" > 

    <ImageView 
     android:id="@+id/cellImageView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="2dp" 
     android:adjustViewBounds="true" 
     android:padding="2dp" 
     android:scaleType="centerCrop" 
     android:src="@drawable/ic_launcher" /> 

    </com.example.testapplication.SquareLayout> 
+0

com.example.testapplication.SquareLayout è il percorso completo del file SquareLayout –

+1

Avviso: questo non funziona con un 'RelativeLayout' come classe base. Stavo cercando di fare esattamente questo, ma con una classe base di 'RelativeLayout', e il bambino con' centerInParent', e non era in modo appropriato ridisegnare i bambini. Con un 'LinearLayout' invece, funziona perfettamente. – karl

9

ho avuto problemi chiamando setMeasuredDimension direttamente quando si applica la stessa tecnica per un RelativeLayout. Non ero in grado di allineare correttamente contro il bordo inferiore. Cambiare per chiamare invece fino a super.onMeasure() con una nuova misura specifica ha funzionato meglio.

@Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = MeasureSpec.getSize(heightMeasureSpec); 
    int size = Math.min(width, height); 
    super.onMeasure(MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY), 
     MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY)); 
    } 
+3

Questa è una soluzione molto più flessibile rispetto alla risposta accettata in quanto può essere utilizzata con molte diverse superclassi oltre a LinearLayout. – Matej

+0

Tutte le risposte disponibili sono simili, ma hanno problemi con la misurazione della dimensione dei bambini, questa è la risposta giusta, grazie mille. –

6

Edit:

La soluzione qui di seguito è stato ormai deprecato, come ConstraintLayout è diventato il nuovo standard e fornisce questa funzionalità.

risposta originale:

scopre il team di Android ci ha dato la soluzione, ma nessuno lo sa! Dai un'occhiata a queste due classi dalla Percent Support Library:

Se si vuole imporre il rapporto di una vista, è necessario collocarlo all'interno di uno di questi layout. In questo caso, devi posizionare uno standard LinearLayout, non la sottoclasse, all'interno di uno di questi layout con le proporzioni corrette. Esempio se si desidera utilizzare un PercentFrameLayout:

<android.support.percent.PercentFrameLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:layout_aspectRatio="100%"> 
     <!-- Whatever subviews you want here --> 
    </LinearLayout> 
</android.support.percent.PercentFrameLayout> 

E ci si va, tutti i vostri punti di vista sarà compresa in un quadrato di layout lineare !

non dimenticate di aggiungere la dipendenza Gradle compile 'com.android.support:percent:23.3.0' Regolare il numero di versione come richiesto

+2

Le proporzioni non sembrano funzionare a meno che non sia definita solo la larghezza o l'altezza e sia definita come un numero fisso (invece di 'match_parent'). Utilizzando 'com.android.support: percent: 25.0.1'. – Pang

+0

Sia PercentFrameLayout che PercentRelativeLayout sono ora deprecati. Si consiglia di utilizzare ConstraintLayout. – dzikovskyy