2016-03-20 22 views
8

Tôi đang cố gắng triển khai Trang tính dưới cùng trong một trong các hoạt động của mình và tôi hơi bối rối bởi cách hoạt động của nó!Hãy thử Hiểu hành vi của BottomSheet trong thư viện hỗ trợ Android 23.2.1

Vì vậy, đây là vấn đề, tôi có một hoạt động mà tôi đang cố gắng để hiển thị dưới tấm và tôi thấy rằng:

  1. nếu chúng tôi không thiết lập các app:behavior_peekHeight tài sản sau đó bảng dưới không bao giờ làm việc

  2. Nếu bạn đặt PeekHeight một cái gì đó ít hơn 30dp (về cơ bản chỉ để che giấu nó từ màn hình)

  3. Nếu bạn đặt app:behavior_peekHeight đến hơn 30dp trong file layout và cố gắng thiết lập trạng thái của bottomSheetBehavior-STATE_HIDDEN trong bạn onCreate phương pháp treo ứng dụng của bạn với lỗi này

do:

Tôi thực sự bối rối về việc tại sao là nó không cho phép tôi để che giấu nó trong onCreate? hoặc tại sao chúng ta không thể đặt peekHeight thành 0 để nó không hiển thị trên màn hình trừ khi chúng ta gọi STATE_EXPANDED hoặc thậm chí không thiết lập thuộc tính đó nên mặc định nó ẩn đi! hoặc ít nhất tôi sẽ có thể thiết lập nó như là ẩn trong onCreate của tôi!

Tôi có thiếu gì đó không? hoặc là hành vi của BottomSheet cứng nhắc?

file layout của tôi cho BottomSheet là một cái gì đó như thế này:

<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"> 

trong hoạt động của tôi Tôi đang làm một cái gì đó như thế này:

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

Trong tôi onclick tôi đang làm điều này:

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

Bạn có hình lý do cho trường hợp đầu tiên: nếu chúng ta không thiết lập các ứng dụng: behavior_peekHeight bất động sản sau đó tờ Bottom không bao giờ hoạt động? tôi đã vào cùng. –

+0

@ LạngHoàng câu trả lời này có thể giúp bạn http: // stackoverflow.com/a/36236743/3000299 – sujay

Trả lời

4

Sau khi làm việc về vấn đề này trong vài ngày nữa tôi tìm thấy một giải pháp thay thế cho việc này:

Thay vì sử dụng Bottom_sheet trực tiếp bên trong bố trí của bạn, nếu chúng ta tạo ra một đoạn Bottom_Sheet và sau đó nhanh chóng nó trong hoạt động vấn đề này sẽ không xảy ra và các tấm đáy sẽ được ẩn và chúng tôi không cần phải xác định peek_height

đây là những gì tôi đã làm

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

Sau đó, trong hoạt động của tôi

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

Điều này thực sự giải quyết vấn đề của tôi về tấm đáy là không ẩn khi hoạt động bắt đầu nhưng tôi vẫn không thể hiểu tại sao nếu bottom_sheet được bao gồm trực tiếp, chúng tôi phải đối mặt với vấn đề đó!

+1

Thực hiện việc này sẽ thay đổi trang tính của bạn từ một trang tính liên tục thành bảng dưới cùng của mô hình. Alltough này có vẻ không quan trọng, nó có thể có một tác động rất lớn. Bảng dưới cùng bền vững, ví dụ cho phép tương tác với nội dung ở trên nó (vuốt, đánh máy, v.v.). Trong khi đó, một tờ dưới cùng của mô hình thì không. – Entreco

1

Lý do sự cố xảy ra do thực tế là tham chiếu yếu không được đặt cho đến khi một trong những dòng cuối cùng trong onLayoutChild, cung cấp cho bạn ngoại lệ ptr null của bạn.

Việc bạn có thể làm là tạo hành vi BottomSheet tùy chỉnh và ghi đè lênLayoutChild, đặt trạng thái mở rộng ở đó.

Một ví dụ có thể được tìm thấy ở đây: NullPointerExeption with AppCompat BottomSheets

+0

đề nghị sử dụng một hoạt động tùy chỉnh và kế thừa nó giải quyết vấn đề nhưng tại sao weakReference không được đặt ở vị trí đầu tiên? nó là một điều thiết kế mà làm cho nó quan trọng để không phải thiết lập weakReference trước khi bố trí con không được tải hoàn toàn? – sujay

1

(Đề cập đến câu hỏi) Suzzi đưa ra vấn đề với mã của bạn là bạn đang cố gắng gọi phương thức setState trực tiếp bên trong onCreate. Điều này sẽ ném một nullPointer vì WeakReference chưa được khởi tạo. Nó sẽ được khởi tạo khi bố cục Coordinator sắp đặt khung nhìn con của nó.

onLayoutChild (CoordinatorLayout phụ huynh, V đứa trẻ, int layoutDirection)

Được gọi là khi phụ huynh CoordinatorLayout là về lay ra xem con cho .

Vì vậy, cách tiếp cận tốt nhất là đặt chiều cao peek là 0 và hiển thị/ẩn bên trong trình nghe onItemClick. Đây là mã của tôi:

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

    } 
    } 

Ở đây ban đầu trang tính dưới cùng không hiển thị. Khi nhấp vào nút, chúng tôi sẽ đặt trạng thái thành STATE_COLLAPSED/STATE_EXPANDED.

Các hướng dẫn tôi theo sau để làm cho ứng dụng demo này được liệt kê dưới đây: Bottom Sheet with Android Design Support Library

+0

yup Tôi đã thử cách tiếp cận này nhưng với cách tiếp cận này, vấn đề tôi có là tôi phải đặt thuộc tính peek_height ở trang tính dưới hơn 30 Tôi đã nhầm lẫn bởi vì nếu tôi đặt thành 0 thì không có gì hiệu quả! không có lỗi và không có bảng dưới cùng tôi không thể tìm ra lý do tại sao điều đó xảy ra! nhưng trong ba điều, câu trả lời của bạn đã giúp tôi tìm ra lý do cho một trong số chúng liên quan đến "weakReference"! cảm ơn cho câu trả lời – sujay

1

Để tránh con trỏ ngoại lệ Null, thiết lập nhà nước để HIDDEN như thế này trong 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

Giải pháp này hoạt động, nhưng có một vấn đề khi nói đến vòng đời của Activity ... chẳng hạn như nếu runnable thực hiện sau khi hoạt động bị tạm dừng. –

+0

cách tôi có thể nhận trạng thái, như tôi muốn xem là hiển thị toàn màn hình hoặc người dùng cần cuộn lên. để tôi có thể hiển thị thêm nút thông tin ở dưới cùng nếu có nhiều dữ liệu hơn thì chế độ xem hiện tại – andro

+0

cách tôi có thể nhận trạng thái, như tôi muốn xem là hiển thị toàn màn hình hoặc người dùng cần cuộn lên. để tôi có thể hiển thị thêm nút thông tin ở dưới cùng nếu có nhiều dữ liệu hơn thì chế độ xem hiện tại – andro

Các vấn đề liên quan