2013-05-25 21 views
18

tworzę moje własne klasy dla układu kwadratowy:Niestandardowy kwadrat LinearLayout. W jaki sposób?

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

Następnie w moim 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> 
... 

nic więcej napisane w moim kodu java. Ale zamiast tego, jeśli mój układ i mój obraz, widzę tylko biały prostokąt ...

Co jest nie tak?

+0

tag otwarciem - ' ' ??? – Simon

+0

poprawiono :-) Dziękuję. – Geltrude

+0

To może pomóc http://www.gadgetsaint.com/tips/dynamic-square-rectangular-layouts-android/#.WRRjMvl96Hs – ASP

Odpowiedz

19

// zapomnij wywołać super.onMeasure (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); 

} 

// plik 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 jest pełną ścieżką pliku SquareLayout –

+1

Ostrzeżenie: to nie będzie pracować z 'RelativeLayout' jako klasą podstawową. Próbowałem zrobić dokładnie to, ale z podstawową klasą "RelativeLayout" i dzieckiem z 'centerInParent', i to nie było stosownego ponownego układania dzieci. Z 'LinearLayout' zamiast tego działa idealnie. – karl

9

miałem problemy nazywając setMeasuredDimension bezpośrednio przy zastosowaniu tej samej techniki do RelativeLayout. Nie udało mi się prawidłowo wyrównać względem dolnej krawędzi. Zmiana na wywołanie na super.onMeasure() z nową miarą działa lepiej.

@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

Jest to rozwiązanie o wiele bardziej elastyczne niż przyjęta odpowiedź, ponieważ może być używane z wieloma różnymi nadklasami poza LinearLayout. – Matej

+0

Wszystkie dostępne odpowiedzi są podobne, ale mają problemy z pomiarem wielkości dzieci, to jest właściwa odpowiedź, wielkie dzięki. –

6

Edit:

Poniższy roztwór został już przestarzała, jak ConstraintLayout stał się nowym standardem i zapewnia tę funkcję.

Original Odpowiedź:

Okazuje się, że Android zespół dał nam rozwiązanie, ale nikt nie wie o tym! Sprawdź te dwie klasy z Percent Support Library:

Jeśli chcesz nałożyć stosunek widoku, trzeba umieścić go w jednym z tych układów. W takim przypadku musisz umieścić standardową LinearLayout, a nie podklasę, w jednym z tych układów o odpowiednim współczynniku proporcji. Przykład, jeśli chcesz używać 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> 

I proszę, wszystkie widoki będą zawarte w kwadratowym układzie liniowym !

nie zapomnij dodać Gradle zależność compile 'com.android.support:percent:23.3.0' Adjust numer wersji wymagane

+2

Współczynnik proporcji nie działa, chyba że zdefiniowana jest tylko szerokość lub wysokość i jest zdefiniowana jako stała liczba (zamiast "match_parent"). Używanie 'com.android.support: percent: 25.0.1'. – Pang

+0

Zarówno PercentFrameLayout, jak i PercentRelativeLayout są obecnie przestarzałe. Zalecane jest używanie ConstraintLayout. – dzikovskyy

Powiązane problemy