2016-02-28 5 views
20

Używam BottomSheetBehavior z Google ostatnio wydanego AppCompat v23.2. Wysokość dolnego arkusza zależy od zawartości wyświetlanej w dolnej części arkusza (podobnie jak w przypadku aplikacji Google w aplikacji Mapy).Dynamicznie zmienia wysokość BottomSheetBehavior

Działa to dobrze z wczytanymi danymi, ale moja aplikacja zmienia zawartość wyświetlaną w czasie wykonywania, a kiedy tak się dzieje, dolny arkusz zachowuje swoją dawną wysokość, co prowadzi do niewykorzystanego miejsca na dole lub skrótu widoku.

Czy istnieje sposób informowania układu dolnego arkusza o ponownym obliczeniu wysokości używanej dla stanu rozwiniętego (gdy wysokość ViewGroup jest ustawiona na MATCH_HEIGHT) lub w dowolny sposób ręcznie ustawić wymaganą wysokość?


EDIT: Próbowałem też ręcznie wywołać invalidate() na ViewGroup i rodzica niego, ale bez powodzenia.

+0

można zrobić wysokość widok ustawiony wrap_parent a następnie widok po treści unieważnienie jest ładowany –

+0

widok wysokość jest ustawiona na wrap_parent, ale moim problemem jest to, że gdy widok jest unieważnione nie przeliczyć wysokość to i dolny arkusz pozostaje tak, jak było przed – miho

+0

Patrząc na kod BottomSheetBehavior, oblicza on wysokość w metodzie onLayoutChild, która jest wywoływana przez CoordinatorLayout. Czy próbowałeś unieważnić to przez wywołanie na requestLayout()? – mattmook

Odpowiedz

6

Możesz użyć do tego celu BottomSheetBehavior#setPeekHeight.

FrameLayout bottomSheet = (FrameLayout) findViewById(R.id.bottom_sheet); 
BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet); 
behavior.setPeekHeight(newHeight); 

Nie spowoduje to automatycznie przesunięcia dolnego arkusza do wysokości ekranu. Możesz zadzwonić pod numer BottomSheetBehavior#setState, aby dostosować dolny arkusz do nowej wysokości podglądu.

behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); 
+1

Nie, szukam rozszerzonego rozmiaru. Używam już stanu zwiniętego z wysokością podglądu. Jednak mój rozmiar podglądu jest zawsze ograniczony do nagłówka podglądu, a rozmiar rozwinięty zależy od tego, ile treści jest dostępna. (Na przykład opis obiektów.) – miho

19

Miałem ten sam problem z RelativeLayout jako mój dolny arkusz. Wysokość nie zostanie ponownie obliczona. Musiałem uciekać się do ustawienia wysokości przez nowo przeliczoną wartość i zadzwonić pod numer BottomSheetBehavior.onLayoutChild.

To jest moje rozwiązanie tymczasowe:

coordinatorLayout = (CoordinatorLayout)findViewById(R.id.coordinator_layout); 
bottomSheet = findViewById(R.id.bottom_sheet); 

int accountHeight = accountTextView.getHeight(); 
accountTextView.setVisibility(View.GONE); 

bottomSheet.getLayoutParams().height = bottomSheet.getHeight() - accountHeight; 
bottomSheet.requestLayout(); 
behavior.onLayoutChild(coordinatorLayout, bottomSheet, ViewCompat.LAYOUT_DIRECTION_LTR); 
+2

Chciałbym zobaczyć lepsze rozwiązanie, ale teraz wydaje się, że jest to jedyny sposób, aby to zrobić. – miho

+2

dla mnie 'bottomSheet.requestLayout()' było wystarczające po zmianie widoku – Odys

+1

cofając mój poprzedni komentarz, natychmiastowy przebieg oszukał mnie – Odys

0

byłem stoi ten sam problem, kiedy użyłem recyclerview wewnątrz BottomSheet i pozycje zmieniane dynamicznie. Jak wspomniał @sosite w swoim komentarzu, problem jest rejestrowany i naprawili go w najnowszym wydaniu. Issue log here

Zaktualizuj bibliotekę wsparcia projektu do wersji 24.0.0 i sprawdź.

0

Mimo że problem został rozwiązany w bibliotece wsparcia> = 24.0.0, jeśli z jakiegoś powodu nadal musisz korzystać ze starszej wersji, oto sposób obejścia tego problemu.

mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 
     @Override 
     public void onStateChanged(@NonNull final View bottomSheet, int newState) { 
      bottomSheet.post(new Runnable() { 
       @Override 
       public void run() { 
        //workaround for the bottomsheet bug 
        bottomSheet.requestLayout(); 
        bottomSheet.invalidate(); 
       } 
      }); 
     } 

     @Override 
     public void onSlide(@NonNull View bottomSheet, float slideOffset) { 
     } 
    }); 
0

Napotkałem ten sam problem, gdy próbowałem zaktualizować wysokość ekranu w oparciu o jego zawartość, znaleziono wysokość z poprzedniego układu. Ma to sens, ponieważ nowy układ jeszcze się nie odbył. Publikując w wątku UI, wysokość układu jest obliczana po nowym layoucie, a kolejne żądanie układu jest aktualizowane w celu zaktualizowania dolnego arkusza do odpowiedniej wysokości.

void show() { 
    setVisibility(View.VISIBLE); 
    post(new Runnable() { 
     @Override 
     public void run() { 
      mBottomSheetBehavior.setPeekHeight(findViewById(R.id.sheetPeek).getHeight()); 
      requestLayout(); 
     } 
    }) 
}