2016-02-28 4 views
20

Я использую BottomSheetBehavior от недавно выпущенного AppCompat v23.2 от Google. Высота моего нижнего листа зависит от содержимого, отображаемого внутри нижнего листа (аналогично тому, что делает Google в приложении «Карты»).Динамически меняйте высоту BottomSheetBehavior

Он отлично работает с первоначально загруженными данными, но мое приложение меняет содержимое, отображаемое во время выполнения, и когда это происходит, нижний лист сохраняет свою прежнюю высоту, что либо приводит к неиспользованному пространству внизу, либо к разрезу зрения.

Есть ли способ сообщить строчку нижнего листа, чтобы пересчитать высоту, используемую для расширенного состояния (когда высота ViewGroup установлена ​​на MATCH_HEIGHT) или любым способом вручную установить требуемую высоту?


EDIT: Я также попытался вручную вызвать invalidate() на ViewGroup и родителя его, но без какого-либо успеха.

+0

вы могли бы сделать высоту вида, установленного на wrap_parent, а затем аннулировать вид после вашего контента загружается –

+0

высота вид устанавливается на wrap_parent, но моя проблема в том, что когда-то точка зрения признана недействительной не пересчитывать высоту он и нижний лист просто остаются такими, какими они были до – miho

+0

. Смотря на код BottomSheetBehavior, он вычисляет высоту в методе onLayoutChild, который вызывается CoordinatorLayout. Вы пытались сделать недействительным то, что вызвав requestLayout() на нем? – mattmook

ответ

6

Для этого вы можете использовать BottomSheetBehavior#setPeekHeight.

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

Это не автоматически перемещает нижний лист на высоту заглядывания. Вы можете позвонить BottomSheetBehavior#setState, чтобы настроить нижний лист на новую высоту заглядывания.

behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); 
+1

Нет, я ищу расширенный размер. Я уже использую свернутое состояние с высотой заглядывания. Однако мой размер peek всегда ограничен заголовком предварительного просмотра, а расширенный размер зависит от того, сколько контента доступно. (Например, описание объектов.) – miho

19

У меня была та же проблема с RelativeLayout как мой нижний лист. Высота не будет пересчитана. Мне пришлось прибегнуть к настройке высоты по новому пересчитанному значению и позвоните по номеру BottomSheetBehavior.onLayoutChild.

Это мое временное решение:

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

Мне бы хотелось увидеть лучшее решение, но сейчас это единственный способ сделать это. – miho

+2

для меня 'bottomSheet.requestLayout()' было достаточно после изменения вида – Odys

+1

, взяв мой предыдущий комментарий, мгновенный запуск обманул меня – Odys

0

Я столкнулась с такой же вопрос, когда я использовал recyclerview внутри BottomSheet и элементы динамически изменяются. Как отметил @sosite в своем комментарии, проблема регистрируется, и они исправили ее в последней версии. Issue log here

Просто обновите свою библиотеку поддержки дизайна до версии 24.0.0 и проверьте.

0

Хотя проблема была решена в библиотеке поддержки> = 24.0.0, если по какой-то причине вам все еще нужно использовать более старую версию, это обходное решение.

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

Я сталкивался с таким же вопросом, при попытке обновить высоту быстрого взгляда, основываясь на его содержание, высота от предыдущего макета была найдена. Это имеет смысл, поскольку новый макет еще не состоялся. По проводке в потоке пользовательского интерфейса высота макета вычисляется после нового макета, и выполняется другой запрос макета, чтобы обновить нижний лист до нужной высоты.

void show() { 
    setVisibility(View.VISIBLE); 
    post(new Runnable() { 
     @Override 
     public void run() { 
      mBottomSheetBehavior.setPeekHeight(findViewById(R.id.sheetPeek).getHeight()); 
      requestLayout(); 
     } 
    }) 
} 
Смежные вопросы