2016-03-20 2 views
8

Я пытаюсь реализовать нижний лист в одном из своих действий, и я немного смущен тем, как он себя ведет!Попытайтесь понять поведение BottomSheet в библиотеке поддержки android 23.2.1

Так вот проблема, у меня есть деятельность, в которой я пытаюсь показать нижний лист, и я вижу, что:

  1. если мы не установить app:behavior_peekHeight свойство, то нижний лист никогда не работает

  2. Если установить PeekHeight на что-то меньше, чем 30dp (в основном только, чтобы скрыть его от экрана)

  3. Если вы установите app:behavior_peekHeight более чем 30dp в файле макета и попытаться установить состояние bottomSheetBehavior до STATE_HIDDEN в вас OnCreate метод вашего приложения аварий с этой ошибкой

вызвано следующими причинами:

Я действительно запутался почему он не позволяет мне скрывать в OnCreate? или почему мы не можем установить peekHeight в 0, чтобы он не отображался на экране, если мы не вызываем STATE_EXPANDED или даже не устанавливаем, что это свойство должно по умолчанию его скрывать! или, по крайней мере, я должен уметь устанавливать его как скрытый в моем onCreate!

Я что-то упустил? или поведение жесткого диска BottomSheet?

мой файл макета для BottomSheet что-то вроде этого:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:background="@android:color/white" 
android:layout_height="100dp" 
android:orientation="vertical" 
app:behavior_hideable="true" 
app:behavior_peekHeight="40dp" <!-- I cant set this less than 30dp just to hide--> 
app:layout_behavior="@string/bottom_sheet_behavior" 
tools:context="someActivity" 
android:id="@+id/addressbottomSheet" 
tools:showIn="@layout/some_activity"> 

в моей деятельности я делаю что-то вроде этого:

@InjectView(R.id.addressbottomSheet) 
View bottomSheetView; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
.... 
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetView); 

// only if I have set peek_height to more than 30dp 
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 
} 

В моей OnClick я это делаю:

@Override 
public void onItemClick(View view, int position) { 
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); 
} 
+1

ли вы вычисляете из причины для первого случая: если мы не установили свойство app: behavior_peekHeight, то нижний лист никогда не работает? я попал в то же самое. –

+0

@ LạngHoàng Этот ответ может помочь вам http: // stackoverflow.com/a/36236743/3000299 – sujay

ответ

4

После работы по этому вопросу на несколько дней я нашел одно альтернативное решение для этого:

Вместо использования Bottom_sheet непосредственно внутри макета, если мы создать фрагмент Bottom_Sheet, а затем создать его экземпляр в своей деятельности этот вопрос не будет происходить, и нижний лист будет скрыт и нам не нужно, чтобы указать peek_height

вот что я сделал

public class BottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener { 
    @Override 
    public View onCreateView(LayoutInflater inflater, 
          ViewGroup container, 
          Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.fragment_bottom_sheet, container, false); 
} 

Тогда в моей деятельности

bottomSheetDialog = BottomSheetDialog.newInstance(addressList.get(position), position); 
bottomSheetDialog.show(getSupportFragmentManager(), AddressActivity.class.getSimpleName()); 

Это на самом деле решить мою проблему нижнего листа быть не скрыт, когда начинается деятельность, но я до сих пор не может понять, почему если bottom_sheet включен непосредственно перед нами этой проблемой!

+1

Выполнение этого приведет к изменению вашего листа от постоянного нижнего листа до модели нижнего листа. Все это может показаться несущественным, оно может иметь огромное влияние. Постоянный нижний лист, например, позволяет взаимодействовать с содержимым над ним (прокрутка, ввод текста и т. Д.). В то время как модельный нижний лист нет. – Entreco

1

Причина его срыва связана с тем, что слабая ссылка не установлена ​​до тех пор, пока одна из последних строк в onLayoutChild, которая дает вам исключение null ptr.

Что вы можете сделать, это создать пользовательское поведение BottomSheet и переопределить onLayoutChild, установив там расширенное состояние.

Пример можно найти здесь: NullPointerExeption with AppCompat BottomSheets

+0

предложение использовать пользовательскую деятельность и наследовать ее решает проблему, но почему значение weakReference не задано на первом месте? является ли это конструктивной вещью, которая делает важным не устанавливать weakReference до того, как макет ребенка полностью не загружен? – sujay

1

(Ссылаясь на вопрос) Suzzi bro проблема с вашим кодом заключается в том, что вы пытаетесь вызвать метод setState непосредственно внутри onCreate. Это будет генерировать nullPointer, потому что WeakReference еще не инициализирован. Он будет инициализирован, когда макет Координатора собирается заложить свое дочернее представление.

onLayoutChild (CoordinatorLayout родитель, V ребенок, Int LayoutDirection)

Вызывается, когда родитель CoordinatorLayout идет о раскладывать данного зрения ребенка.

Таким образом, наилучшим подходом является высота заглядывания до 0 и отображение/скрытие внутри прослушивателя onItemClick. Вот мой код:

bottom_sheet.xml

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#ffffff" 
    android:gravity="center" 
    android:orientation="vertical"> 

    <ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@mipmap/ic_launcher" /> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:text="Bottom sheet" 
     android:textColor="@android:color/black" /> 

</LinearLayout> 

activity_main.xml

<Button 
    android:id="@+id/button" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Show hide bottom sheet" /> 


<include 
    android:id="@+id/gmail_bottom_sheet" 
    layout="@layout/bottom_sheet" /> 

MainActivity.java

public class MainActivity extends AppCompatActivity { 
     boolean isExpanded; 
     Button button; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.gmail_coordinator); 
     final View bottomSheet = coordinatorLayout.findViewById(R.id.gmail_bottom_sheet); 
     final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet); 
     button = (Button) findViewById(R.id.button); 
     button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       if (isExpanded) { 
        behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); 
       } else { 
        behavior.setState(BottomSheetBehavior.STATE_EXPANDED); 
       } 
       isExpanded = !isExpanded; 
      } 
     }); 

    } 
    } 

Здесь первоначально нижний лист не виден. При нажатии кнопки мы будем устанавливать состояние STATE_COLLAPSED/STATE_EXPANDED.

В учебнике я следовал, чтобы сделать это демонстрационное приложение перечислены ниже: Bottom Sheet with Android Design Support Library

+0

yup Я пробовал этот подход, но при таком подходе проблема у меня была, я должен был установить свойство peek_height в нижнем листе, чтобы быть более 30. Я был немного смущен, потому что, если бы я установил его на ноль, то ничего не получилось! никаких ошибок и ни одного нижнего листа я не мог понять, почему это произошло! но из трех вещей ваш ответ помог мне разобраться в причине одного из них, который касался «слабого восприятия»! спасибо за ответ – sujay

1

Чтобы избежать исключения нулевого указателя, установите состояние в HIDDEN, как это в OnCreate()

View bottomSheetView = findViewById(R.id.bottomsheet_review_detail_id); 
mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheetView); 
bottomSheetView.post(new Runnable() { 
      @Override 
      public void run() { 
       mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 
      } 
     }); 
+0

Это решение работает, но есть проблема, когда дело доходит до жизненного цикла Activity ... например, если runnable выполняется после того, как действие приостановлено. –

+0

как я могу получить состояние, как я хочу видеть, отображается полный просмотр, или пользователям нужно прокручивать вверх. так что я могу показать дополнительную информацию в нижней части, если больше данных присутствует, а затем текущий вид – andro

+0

, как я могу получить состояние, например, я хочу видеть, отображается полный просмотр или пользователям нужно прокручивать вверх. так что я могу показать дополнительную информацию в нижней части, если присутствует больше данных, а затем текущий вид – andro

Смежные вопросы