Android - Cách tắt trạng thái STATE_HALF_EXPANDED của trang dưới cùng


14

Tôi có một tờ dưới cùng nên đi giữa 2 tiểu bang STATE_COLLAPSEDSTATE_EXPANDED khi nó bị sập thì độ cao phải là 200dpvà khi được mở rộng, nó sẽ ở chế độ toàn màn hình.

Vì vậy, tôi đang thiết lập BottomSheetBehaviorvới

isFitToContents = false
peekHeight = 200dp

và tôi buộc phải đặt giá trị theo halfExpandedRatiocách khác khiSTATE_HALF_EXPANDED bảng dưới cùng sẽ chiếm một nửa màn hình.

Tôi đang làm việc com.google.android.material:material:1.1.0-rc01

Có cách nào để vô hiệu hóa STATE_HALF_EXPANDEDnhà nước?

Hoặc tôi thực sự nên thiết lập skipCollapsed=true, tìm hiểu về tỷ lệ ý nghĩa của 200dp và làm việc với STATE_HALF_EXPANDEDSTATE_EXPANDEDthay vì STATE_COLLAPSEDSTATE_EXPANDED


vui lòng cung cấp thêm chi tiết như, bảng dưới cùng trông như thế nào.
UD ..

@ UD..Tôi không nghĩ rằng nội dung dưới cùng có liên quan trong trường hợp này. Đây là một câu hỏi tổng quát hơn, có thể vô hiệu hóa một trong những trạng thái dưới cùng
Noa Drach

1
Đối với trường hợp sử dụng của tôi, nó có vẻ như thiết lập halfExpandedRatio=0.25fpeekHeight = 200dpvà sau đó điều trị STATE_COLLAPSEDSTATE_HALF_EXPANDEDnhư thể họ là những phá được cùng một trạng thái vấn đề này. Giữ câu hỏi mở trong trường hợp có ý tưởng khác.
Noa Drach

bạn có thể theo liên kết này, nó sẽ giúp androidhive.info/2017/12/android-usiness-with-bottom-sheet
UD ..

Hãy chắc chắn chấp nhận một trong những câu trả lời này, nếu một trong những đáp ứng các mục tiêu được đặt ra trong câu hỏi của bạn!
CommonsWare

Câu trả lời:


3

Giá trị của tỷ lệ mở rộng một nửa phải được đặt thành một số giá trị từ 0 đến 1 độc quyền , do đó đặt giá trị này bằng một số rất thấp mà chắc chắn là ít hơn so với chiều cao cái nhìn của bạn, hãy nói "0.0001f". Với giá trị này, bạn thậm chí không nên nhìn thấy STATE_HALF_EXPANDEDtrạng thái. Các tiểu bang sẽ dao động giữa STATE_EXPANDEDSTATE_COLLAPSED.


Giải pháp thay thế

Giải pháp trên hoạt động và vô hiệu hóa STATE_HALF_EXPANDEDnhà nước một cách hiệu quả , nhưng nó là hackish (IMO) và có thể phá vỡ trong tương lai. Chẳng hạn, nếu một giá trị hợp lý cho tỷ lệ mở rộng một nửa nằm ở đâu đó giữa chiều cao nhìn trộm và chiều cao đầy đủ được thi hành thì sao? Đó sẽ là rắc rối.

Các yêu cầu như OP đã nêu là tấm dưới cùng phải chuyển đổi giữa chiều cao nhìn trộm và chiều cao đầy đủ. Không có vấn đề với chiều cao nhìn trộm, nhưng OP chỉ địnhisFitToContents = false để có được chiều cao đầy đủ. (Tôi cho rằng tấm dưới cùng của anh ta có thể ngắn hơn không gian có sẵn.)

Thật không may, khi isFitToContents == false một hành vi "nửa chiều cao" bổ sung được đưa ra mà OP muốn tránh và do đó là câu hỏi.

Ngoài hành vi "nửa chiều cao", một hành vi khác được đưa ra là "bù đắp mở rộng". Phần bù mở rộng chỉ định khoảng cách từ màn hình dưới cùng sẽ dừng bao xa. 100fVí dụ, một giá trị sẽ để lại một100px đường viền ở trên cùng của bảng dưới cùng khi được mở rộng hoàn toàn. Mặc định cho phần bù mở rộng là zero.

Tôi không nhận thức được bất kỳ hành vi nào isFitToContents == false giới thiệu ngoài những được đề cập ở trên.

Vì vậy, với những yêu cầu này, chúng ta có thể tạo một tấm dưới cùng di chuyển giữa chiều cao nhìn trộm và chiều cao đầy đủ trong khi chỉ định isFitToContents == true do đó tránh được vấn đề "một nửa chiều cao" không? Không có yêu cầu cho phần bù mở rộng khác không, vì vậy chúng tôi không phải lo lắng về điều đó.

Dưới đây là một ứng dụng demo ngắn chứng minh rằng chúng ta có thể đáp ứng các yêu cầu này với cấu trúc bảng dưới cùng bên phải:

nhập mô tả hình ảnh ở đây

MainActivity5.kt

class MainActivity5 : BaseActivity() {  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContentView(R.layout.activity_main5)  

        val bottomSheet = findViewById<LinearLayout>(R.id.bottom_sheet)  
        val sheetBehavior: BottomSheetBehavior<LinearLayout> = BottomSheetBehavior.from(bottomSheet)  
        sheetBehavior.isFitToContents = true // the default  
  sheetBehavior.peekHeight = 200  

  // Log the states the bottom sheet passes through.  
  sheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {  
            override fun onStateChanged(bottomSheet: View, newState: Int) {  
                Log.d("MainActivity", "<<<< $newState = ${translateSheetState(newState)}")  
            }  

            override fun onSlide(bottomSheet: View, slideOffset: Float) {}  
        })  
    }  
}

BaseActivity.kt

open class BaseActivity : AppCompatActivity() {  

    protected fun translateSheetState(state: Int): String {  
        return when (state) {  
            BottomSheetBehavior.STATE_COLLAPSED -> "STATE_COLLAPSED"  
  BottomSheetBehavior.STATE_DRAGGING -> "STATE_DRAGGING"  
  BottomSheetBehavior.STATE_EXPANDED -> "STATE_EXPANDED"  
  BottomSheetBehavior.STATE_HALF_EXPANDED -> "STATE_HALF_EXPANDED"  
  BottomSheetBehavior.STATE_HIDDEN -> "STATE_HIDDEN"  
  BottomSheetBehavior.STATE_SETTLING -> "STATE_SETTLING"  
  else -> "Unknown state: $state"  
  }  
    }  
}

Activity_main5.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_orange_light"
        android:orientation="vertical"
        android:scrollbars="none"
        app:layout_behavior="@string/bottom_sheet_behavior">

        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:text="@string/short_text"
            android:textSize="16sp" />

    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Nếu chúng ta có một tấm dưới cùng dài thì cấu trúc sau hoạt động để cuộn nó:

Activity_main6.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_orange_light"
        android:orientation="vertical"
        android:scrollbars="none"
        app:layout_behavior="@string/bottom_sheet_behavior">

        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/tv"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="16dp"
                android:text="@string/long_text"
                android:textSize="16sp" />
        </androidx.core.widget.NestedScrollView>
    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

liên quan đến phản hồi ban đầu của bạn - Tôi thấy rằng ngay cả khi tôi đặt tỷ lệ mở rộng một nửa, vẫn có thể nhìn thấy một gợi ý rất mỏng của bảng dưới cùng. Và dù sao, đây không phải là hành vi mà tôi đang tìm kiếm. như bạn đã đề cập trong "Giải pháp thay thế" - "bảng dưới cùng sẽ chuyển đổi giữa chiều cao nhìn trộm và chiều cao đầy đủ"
Noa Drach

"Giải pháp thay thế" của bạn dường như đang hoạt động và đó là giải pháp tôi cần, thử nghiệm ban đầu của tôi cho thấy tôi cần sử dụng isFitToContents = false, nhưng thử nghiệm bây giờ vẫn isFitToContents = truehoạt động tốt
Noa Drach

@NoaDrach Nếu bảng dưới cùng có thể ẩn được thì sẽ có ít nhất 1px hiển thị ở dưới cùng do cách tính bù của bảng dưới cùng. Tôi đã không nghĩ rằng trang tính sẽ bị ẩn nhưng, với hiển thị 1px, trang tính có thể bị buộc phải bị ẩn sheetBehavior.state = BottomSheetBehavior.STATE_HIDDENkhi đạt đến trạng thái mở rộng một nửa, nhưng điều đó hơi phức tạp. Các giải pháp thay thế là tốt hơn.
Cheticamp

2

nhập mô tả hình ảnh ở đây

Nếu bạn muốn thử ở trên như trong hình ảnh, bạn có thể làm theo mã bên dưới, có thể nó sẽ giúp bạn !!!

public class CollectionsBottomSheet extends BottomSheetDialogFragment {
    private BottomSheetBehavior mBehavior;


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
        View view = View.inflate(getContext(), R.layout.collections_layout, null);
        LinearLayout linearLayout = view.findViewById(R.id.root);
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) linearLayout.getLayoutParams();
        params.height = getScreenHeight();
        linearLayout.setLayoutParams(params);
        dialog.setContentView(view);
        mBehavior = BottomSheetBehavior.from((View) view.getParent());
        return dialog;

    }

    @Override
    public void onStart() {
        super.onStart();
        mBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
    }

    public static int getScreenHeight() {
        return Resources.getSystem().getDisplayMetrics().heightPixels;
    }
}



xml 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/bottom_sheet"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:fitsSystemWindows="true">


    <LinearLayout
        android:id="@+id/root"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/filter_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:drawableStart="@drawable/ic_cancel"
                android:drawableLeft="@drawable/ic_cancel"
                android:drawablePadding="30dp"
                android:gravity="center_vertical"
                android:padding="12dp"
                android:text="Filters"
                android:textColor="@color/black"
                android:textSize="18sp" />

            <View
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_weight="1" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="10dp"
                android:layout_marginRight="10dp"
                android:padding="5dp"
                android:text="Reset ALL"
                android:textColor="#6f6f6f"
                android:textSize="12sp" />

        </LinearLayout>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#d8dbdb" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/sort_background"
            android:drawableStart="@drawable/ic_star"
            android:drawableLeft="@drawable/ic_star"
            android:drawablePadding="15dp"
            android:padding="15dp"
            android:text="GUEST RATINGS"
            android:textColor="#6f6f6f"
            android:textSize="16sp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/sort_background"
            android:drawableStart="@drawable/ic_money"
            android:drawableLeft="@drawable/ic_money"
            android:drawablePadding="15dp"
            android:padding="15dp"
            android:text="PRICE RANGE"
            android:textColor="#6f6f6f"
            android:textSize="16sp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/sort_background"
            android:drawableStart="@drawable/ic_loan"
            android:drawableLeft="@drawable/ic_star"
            android:drawablePadding="15dp"
            android:padding="15dp"
            android:text="PAY AT HOTEL"
            android:textColor="#6f6f6f"
            android:textSize="16sp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/sort_background"
            android:drawableStart="@drawable/ic_folder"
            android:drawableLeft="@drawable/ic_folder"
            android:drawablePadding="15dp"
            android:padding="15dp"
            android:text="COLLECTIONS"
            android:textColor="#6f6f6f"
            android:textSize="16sp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/sort_background"
            android:drawableStart="@drawable/ic_perm_identity_black_24dp"
            android:drawableLeft="@drawable/ic_perm_identity_black_24dp"
            android:drawablePadding="15dp"
            android:padding="15dp"
            android:text="FACILITIES"
            android:textColor="#6f6f6f"
            android:textSize="16sp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/sort_background"
            android:drawableStart="@drawable/ic_apartment"
            android:drawableLeft="@drawable/ic_apartment"
            android:drawablePadding="15dp"
            android:padding="15dp"
            android:text="CATEGORIES"
            android:textColor="#6f6f6f"
            android:textSize="16sp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/sort_background"
            android:drawableStart="@drawable/ic_hotel_building"
            android:drawableLeft="@drawable/ic_hotel_building"
            android:drawablePadding="15dp"
            android:padding="15dp"
            android:text="ACCOMMODATION TYPE"
            android:textColor="#6f6f6f"
            android:textSize="16sp" />

    </LinearLayout>


</LinearLayout>

câu trả lời rất hay ... đã cứu ngày của tôi
unownsp

1

hãy thử cài đặt addBottomSheetCallbacktrên trạng thái của bạn BottomSheetBehaviorvà khi bạn phát hiện STATE_HALF_EXPANDEDtrạng thái, hãy gọi setState(STATE_HIDDEN)bất cứ khi nào bảng dưới cùng cố gắng đạt đến trạng thái nửa chừng, nó sẽ đóng lại.


ý tưởng tốt, trong trường hợp của tôi, tôi sẽ thiết lập trạng thái STATE_COLLAPSEDvà không STATE_HIDDEN. Nhưng tôi đã cố gắng để thực hiện nó và quá trình chuyển đổi từ STATE_HALF_EXPANDEDđể STATE_COLLAPSEDcảm thấy phiền phức. Quá trình chuyển đổi giữa các trạng thái là hoạt hình, vì vậy bạn thấy bảng dưới cùng dừng lại STATE_HALF_EXPANDEDvà sau đó nó chuyển sangSTATE_COLLAPSED
Noa Drach

Bạn có thể kết hợp điều này với HalfExpandedRatio bằng 0 không?
Vô lý

@Ridcully - 2 vấn đề ở đây - 1. HalfExpandedRatio phải trên 0 2. đặt nó thành một giá trị rất thấp sẽ khiến tôi giảm thiểu gần như hoàn toàn (trạng thái mở rộng một nửa), trước khi bị ngắt sang trạng thái sụp đổ. Tôi đã nghĩ đến việc kết hợp đề xuất này với giải pháp làm việc của tôi halfExpandedState=0.25f, b / c thì việc chuyển đổi giữa các quốc gia sẽ không rõ ràng. Nhưng, tôi không chắc đó sẽ là một thay đổi lớn so với những gì tôi đã có
Noa Drach

1

Tôi đã có một trường hợp sử dụng tương tự trong đó bố cục phải là một phần ba chiều cao. Tôi đã thử sau đây và nó đã làm việc tuyệt vời.

<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/bottom_sheet_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/grey"
    android:clickable="true">

    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/rounded_bottom_sheet_background"
        android:orientation="vertical"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Tôi đã phải thay đổi chúng một cách linh hoạt vì vậy tôi đặt phần sau vào bảng dưới cùng nhưng bạn cũng có thể làm điều này trong xml:

bottomSheet.setPeekHeight(200);// 200px
bottomSheet.setHideable(false);

Để loại bỏ, tôi đã thêm hình ảnh động vào đoạn của mình bằng cách sử dụng chức năng sau:

fragmentTransaction.setCustomAnimations(
                    R.anim.fade_in,
                    R.anim.fade_out,
                    R.anim.fade_in,
                    R.anim.fade_out)

Hi vọng điêu nay co ich



0

Tôi đã thử nhiều cách khác nhau, nhưng không có kỹ thuật nào hoạt động hoàn hảo. Tôi đã cố gắng chặn các sự kiện trong BottomSheetBehavior.BottomSheetCallback {}và gọidismiss() dựa trên logic tùy chỉnh nhưng nó đã gây ra một cú giật.

Vì vậy, cuối cùng, BottomSheetDialogFragmenttôi đã thêmbottomSheetBehavior.isDraggable = false và điều này đã gây ra việc Kéo tấm dưới cùng bằng cách chạm Và, tôi đã tự mình xử lý việc loại bỏ hộp thoại. trên hộp thoại khu vực trống dù sao cũng bị loại bỏ.

Lưu ý rằng, Bảng dưới cùng vẫn mở rộng với hình ảnh động. Điều đó 'thực sự tuyệt vời!

ghi đè lên niềm vui onCreateDialog (yetInstanceState: Bundle?): Dialog {val đàm thoại = super.onCreateDialog (yetInstanceState)

    dialog.setOnShowListener {
        val bottomSheetDialog = it as BottomSheetDialog
        val bottomSheet =
            bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
                ?: return@setOnShowListener

        //Making background to transparent to avoid white background to given space margin.
        bottomSheet.setBackgroundColor(ContextCompat.getColor(context!!, R.color.transparent))

        val inflatedView = fragmentProfileDialogBinding.root
        val parent = inflatedView.parent as View

        val bottomSheetBehavior = BottomSheetBehavior.from(parent)
        bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
        bottomSheetBehavior.isDraggable = false
    }

    return dialog
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.