2016-11-24 12 views
7

W mojej aplikacji mam widok przewijania. Podczas życia mojej aplikacji dynamicznie dodawam nowe widoki do przewijanego widoku. Mogę dodawać widoki z niewielkim problemem, jednak nie mogę uzyskać właściwych wymiarów. Oto szkic mojego pożądanym układzie:Jak napompować rozwijany widok o stałym współczynniku kształtu

enter image description here

W obrazie Mam ekran o wymiarach Width przez Height. Zawiera on HorizontalScrollView (lub może RecyclerView, ale nie jestem pewien, jak używać tego), który będzie rósł, gdy zostaną do niego dodane widoki. Chcę, aby każdy element dodawany do widoku miał szerokość równą jednej piątej wysokości ekranu i miał odpowiednie wysokości. Mogę sprawić, żeby to działało, gdybym zakodował szerokość nadmuchanego widoku, ale mój widok nie będzie miał takiego samego współczynnika proporcji na wszystkich telefonach.

Uwaga: Próbowałem używać PercentRelativeLayout, ale nie mogłem go uruchomić. Nie wiesz, jak rozwiązać ten problem ... jakieś pomysły?


Uwaga na Bounty: będę akceptować odpowiedzi, które są w języku Java lub C# (Xamarin) !! Mój projekt jest w Xamarinie, więc byłoby miło, gdyby to działało, lub gdyby można go było łatwo zaadaptować do pracy w C#

+0

To naprawdę zależy od tego, czy rozmiary są dynamiczne lub stałe. Jeśli są naprawione, możesz zakodować wymiary w układzie i użyć tylko różnych nadpisań dpi, aby zmienić rozmiary wymiarów. Jeśli chcesz, aby rozmiary były dynamiczne, to też mogę na to odpowiedzieć, ale zobacz, czy możesz nim zarządzać, najpierw z układem xml i wymiarami. Sugerowałbym również, aby przyjrzeć się użyciu RecylerView. To trochę, aby owinąć głowę, ale oferuje dużo większą elastyczność i kontrolę. W ten sposób można to zrobić w poziomie: http://stackoverflow.com/a/28460399/1740059 –

+0

@JustinMitchell stosunek będzie stały, najlepiej zdefiniowany w xml jako procent. Próbowałem utworzyć niestandardowy widok, który nadpisuje rozmiar, ale nie mogłem go uruchomić bez zniekształcania rozmiaru jego widoków podrzędnych. – flakes

+0

Nie używaj procentów, używaj stałych wartości dp. Jednak nadal można zmienić rozmiar widoku w metodzie onCreateView. Upewnij się, że utworzysz obserwatora, który nasłuchuje zmian drzewa widoku, abyś mógł uzyskać prawdziwe wymiary widoku, w przeciwnym razie wymiary zostaną wyłączone. –

Odpowiedz

4

Nie chcesz, aby twój widok był jedną piątą wysokości ekranu, chcesz, aby był jedna piąta nadrzędnej wysokości widoku. Albo, aby być idealnie dokładnym, chcesz, aby szerokość była jedną piątą wysokości widoku.

Różnica polega na tym, że użycie szerokości/wysokości ekranu może zadziałać na Twoim urządzeniu, ale zepsuć innym. Co byś zrobił, gdyby ktoś otworzył twoją aplikację z podzielonym ekranem?

Jednak definicja wymiarów widoku, podejście jest takie samo: Jeśli chcesz, aby widok był zgodny z niektórymi regułami, będziesz musiał stworzyć własne i odpowiednio zmierzyć swój widok.

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int availableHeight = MeasureSpec.getSize(heightMeasureSpec); 
    int wantedWidth = availableHeight/5; 

    setMeasuredDimension(wantedWidth, availableHeight); 
} 

I to w zasadzie to. Możesz przeczytać odpowiednią dokumentację na temat MeasureSpec i ogólnie mierzyć widoki. Napisałem też wpis na blogu o numerze custom views, który zawiera kilka podstawowych informacji.

Następnie można po prostu dodać własne widoki do LinearLayout, wspierając ScrollView i gotowe.

Oto pełna próbka, która będzie w zasadzie działa, możesz użyć czegoś innego niż układ ramki.

public class FifthWidthView extends FrameLayout { 
    public FifthWidthView(Context context) { 
    super(context); 
    } 

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

    public FifthWidthView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     int availableHeight = MeasureSpec.getSize(heightMeasureSpec); 
     int wantedWidth = availableHeight/5; 

     setMeasuredDimension(wantedWidth, availableHeight); 
    } 
} 
+0

Spróbuję tego jutro i skontaktuję się z Tobą :) Prawdopodobnie dokonam atrybutu układu, aby ustawić dokładną wartość procentową. Czy to działa z widokiem zagnieżdżonym? – flakes

+0

@ płatki Przy takim podejściu należy raczej użyć atrybutów widoku, aby zmodyfikować współczynnik. Wystarczy zawijać widoki dodane do LinearLayout (w widoku przewijania) z podanym układem. Aby korzystać z atrybutów układu, musisz zaimplementować własną grupę ViewGroup i tworzyć układy, aby atrybuty odniosły skutek, co jest kolejnym (również ważnym) podejściem, ale trochę większym wysiłkiem) –

2

Załóżmy, że możesz użyć ViewPagera. jeśli tak, będziesz musiał zastąpić metodę getPageWidth(). Ta metoda mówi serwisowi widokowemu, jak szeroki musi być każdy widok wewnątrz, od 0 (nic) do 1 (użyj wszystkich).

Będziemy obliczyć rozmiar dynamiczny, jeśli to możliwe, biorąc pod uwagę, że chcemy użyć tylko nieco więcej jednej trzeciej ekranu. Załóżmy, że chcesz użyć całego ekranu do kolekcji z jednym elementem, pół ekranu dla kolekcji z dwoma elementami i dynamicznego obliczania dla każdego innego.

@Override 
public float getPageWidth(int position) { 

     try{ 
      Paint paint = new Paint(); 
      return 0.3f+paint.measureText(data.get(position).getSize())/ DeviceFunctions.giveScreenResolution((Activity) context).x; 
     } 
     catch(Exception e){ 

      int size = data.getValues().size(); 
      switch(size){ 

       case 1: return 1.f; 
       case 2: return 0.5f; 
       case 3: return 0.33f; 
       default: return 0.33f; 
      } 
     } 
    } 

zakładamy:

-the zbieranie danych pozwala na wykrycie zamierzoną szerokość widoku. Możesz to zmienić za pomocą dowolnego odnośnika. Albo można dać stałą wielkość w oparciu o położenie widoku za:

@Override 
public float getPageWidth(int position) { 

      int size = data.getValues().size(); 
       switch(size){ 

        case 1: return 0.35f; 
        case 2: return 0.35f; 
        case 3: return 0.30f; 
        default: return 0.33f; 
       } 
     } 

A dla uzyskania rozdzielczość ekranu:

@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) 
    public static Point giveScreenResolution(Activity activity){ 

     Display display = activity.getWindowManager().getDefaultDisplay(); 
     Point size = new Point(); 
     display.getSize(size); 
     return size; 
    } 
1

w jednym z moich aplikacja służąca ten kod i działa perfekcyjnie.

public static int getScreenHeight(Activity context) 
     { 
      Display display = context.getWindowManager().getDefaultDisplay(); 
      Point size = new Point(); 
      display.getSize(size); 
      int height = size.y; 
      return height; 
     } 

W mojej działalności używam kod mieszkowe

//Container layout may be child of HorizontalScrollView 
LinearLayout parent = (LinearLayout)findViewById(R.id.splash_screen_logo); 
//Child layout to be added 
View mychildview = getLayoutInflater().inflate((R.layout.childView); 
mychildview.getLayoutParams().width = Utils.getScreenHeight(this)/5; 
mychildview.getLayoutParams().height = Utils.getScreenHeight(this); 
parent.addview(mychildview) 
Powiązane problemy