Android - Bir alt sayfanın STATE_HALF_EXPANDED durumunu devre dışı bırakma


14

Ben 2 devlet arasında gitmesi gereken bir alt levha var, STATE_COLLAPSEDve STATE_EXPANDED daraltıldığında yüksekliği olmalı 200dpve genişletilmiş tam ekran olacak.

Ben ayarlıyorum Yani BottomSheetBehaviorbirlikte

isFitToContents = false
peekHeight = 200dp

ve alt sayfada ekranın yarısını alacağı halfExpandedRatiozaman bir değer ayarlamak zorunda kalıyorum STATE_HALF_EXPANDED.

W / ile çalışıyorum com.google.android.material:material:1.1.0-rc01

Durumu devre dışı bırakmanın bir yolu var mı STATE_HALF_EXPANDED?

Ya ben aslında belirlesin skipCollapsed=trueile oran nedir 200dp araç ve iş açısından anlamaya, STATE_HALF_EXPANDEDve STATE_EXPANDEDyerine STATE_COLLAPSEDveSTATE_EXPANDED


lütfen alt sayfanın nasıl göründüğü gibi daha fazla ayrıntı sağlayın.
UD ..

@ UD..Bu durumda alt sayfa içeriğinin alakalı olduğunu düşünmüyorum. Bu daha genel bir soru, alt sayfa durumlarından birini devre dışı bırakmak mümkün

1
Benim kullanım durumunda için, bu ayarı görünüyor oluyor halfExpandedRatio=0.25fve peekHeight = 200dpardından tedavi STATE_COLLAPSEDve STATE_HALF_EXPANDEDsanki onlar aynı devlet çözer sorunu vardır. Başka fikirlerin olması durumunda soruyu açık tutmak.
Noa Drach

Eğer yardımcı olacaktır, bu bağlantıyı takip edebilirsiniz androidhive.info/2017/12/android-working-with-bottom-sheet
.. UD

Sorunuzda belirtilen hedeflere uygunsa, bu cevaplardan birini kabul ettiğinizden emin olun!
CommonsWare

Yanıtlar:


3

Yarım genişletilmiş oranının değeri 0 ile 1 arasında bazı değere ayarlanması gerekir münhasır az sizin gözetleme yükseklikten daha olması kesindir bazı çok az sayıda bu değeri ayarlamak yüzden, "0.0001f" derler. Bu değerle STATE_HALF_EXPANDEDdurumu bile görmemelisiniz . Devletler STATE_EXPANDEDve arasında dalgalanacaktır STATE_COLLAPSED.


Alternatif çözüm

Yukarıdaki çözüm STATE_HALF_EXPANDEDdevleti işler ve etkili bir şekilde devre dışı bırakır , ancak hackish (IMO) ve gelecekte kırılabilir. Örneğin, göz yüksekliği ile tam yükseklik arasında bir yerde bulunan yarı genişletilmiş oran için makul bir değer uygulanırsa ne olur? Bu bela olur.

OP tarafından belirtilen şartlar, alt tabakanın göz yüksekliği ile tam yükseklik arasında geçiş yapmasıdır. Peek yüksekliği ile ilgili bir sorun yoktur, ancak OP isFitToContents = falsetam yüksekliğe ulaşmayı belirtir . (Alt tabakasının kullanılabilir alandan daha kısa olabileceğini varsayıyorum.)

Ne yazık ki, isFitToContents == falseOP'nin kaçınmak istediği ek bir "yarı yükseklik" davranışı ve dolayısıyla soru sorulduğunda.

"Yarım yükseklik" davranışına ek olarak, "genişletilmiş ofset" olan başka bir davranış ortaya çıkar. Genişletilmiş ofset, alt sayfanın tam ekrandan ne kadar aşağı duracağını belirtir. 100fÖrneğin değeri, 100pxtamamen genişletildiğinde alt sayfanın üstünde bir kenarlık bırakacaktır . Genişletilmiş ofset için varsayılan değer sıfırdır.

isFitToContents == falseYukarıda belirtilenler dışında ortaya çıkan davranışların farkında değilim .

Peki, bu gereksinimler göz isFitToContents == trueönüne alındığında, "yarım yükseklik" probleminden kaçınarak, göz yüksekliği ve tam yükseklik arasında hareket eden bir alt tabaka oluşturabilir miyiz ? Sıfır olmayan bir genişletilmiş ofset için herhangi bir gereklilik yoktur, bu yüzden bunun için endişelenmemiz gerekmez.

İşte sağ alt sayfa yapısıyla bu gereksinimleri karşılayabileceğimizi gösteren kısa bir demo uygulaması:

resim açıklamasını buraya girin

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>

Uzun bir alt tabakamız varsa, aşağıdaki yapı sayfayı kaydırmak için çalışır:

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>

İlk yanıtınızla ilgili olarak - Yarı genişletilmiş oran ayarlasam bile, alt tabakanın çok ince bir ipucunun hala görülebildiğini gördüm. Her neyse, aradığım davranış bu değil. "Alternatif çözüm" - "de belirtildiği gibi alt tabaka göz yüksekliği ile tam yükseklik arasında geçiş yapmalıdır"
Noa Drach

"Alternatif çözümünüz" çalışıyor gibi görünüyor ve ihtiyacım olan çözüm, ilk testim kullanmam gerektiğini gösterdi isFitToContents = false, ancak şimdi w / isFitToContents = trueçalışıyor tamam
Noa Drach

@NoaDrach Alt sayfa gizlenebilir durumdaysa, alt sayfa ofsetinin nasıl hesaplandığından dolayı altta en az 1 piksel gösterilir. Sayfanın gizleneceğini düşünmüyordum, ancak 1 piksel gösterildiğinde, sheetBehavior.state = BottomSheetBehavior.STATE_HIDDENyarı genişletilmiş duruma ulaşıldığında sayfa gizlenmeye zorlanabilirdi , ancak bu biraz karmaşıklaşıyor. Alternatif çözüm daha iyidir.
Cheticamp

2

resim açıklamasını buraya girin

yukarıdaki gibi görüntüde denemek istiyorsanız, aşağıdaki kodu takip edebilirsiniz, size yardımcı olabilir !!!

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>

çok iyi bir cevap ... günümü kurtardı
Ocak'ta

1

addBottomSheetCallbacküzerinde bir ayar yapmayı deneyin BottomSheetBehaviorve bir STATE_HALF_EXPANDEDdurum tespit ettiğinizde setState(STATE_HIDDEN), alt sayfa yarıya ulaşmaya çalıştığında, yalnızca kapanacak şekilde arayın .


güzel bir fikir, benim durumumda ben devleti kuracak STATE_COLLAPSEDve STATE_HIDDEN. Ama bunu ve geçişi uygulamaya çalışmıştır STATE_HALF_EXPANDEDiçin STATE_COLLAPSEDhissediyor aksak. Durumlar arasındaki geçiş canlandırılmıştır, bu nedenle alt sayfanın durduğunu görürsünüz STATE_HALF_EXPANDEDve sonraSTATE_COLLAPSED
Noa Drach

Bunu 0'lık bir halfExpandedRatio ile birleştirebilir misiniz?
19'da gülünç

@Ridcully - 2 sayı burada - 1. halfExpandedRatio 0'ın üstünde olmalıdır. 2. Çok düşük bir değere ayarlanması, daraltılmış duruma yakalanmadan önce neredeyse tamamen (yarı genişletilmiş durum) en aza indirgemenize neden olur. Bu öneriyi çalışma çözümümle birleştirmeyi düşündüm halfExpandedState=0.25f, b / c sonra devletler arasındaki geçiş bu kadar açık olmayacak. Ama, zaten sahip olduğumdan daha büyük bir değişiklik olacağından emin değilim
Noa Drach

1

Düzenin yüksekliğin üçte biri olması gereken benzer bir kullanım durumum vardı. Aşağıdakileri denedim ve harika çalıştı.

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

Ben alt sayfada aşağıdaki ayarlamak bu dinamik olarak değiştirmek zorunda kaldı ama bunu sadece xml de yapabilirsiniz:

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

Kapatmak için, aşağıdaki işlevi kullanarak parçama animasyon ekledim:

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

Bu yardımcı olur umarım



0

Farklı yollar denedim, ama hiçbir teknik mükemmel çalışmadı. Olayları durdurmayı denedim BottomSheetBehavior.BottomSheetCallback {}ve dismiss()özel mantığa dayanarak aradım ama bir sarsıntıya neden oldu.

Sonunda, BottomSheetDialogFragmentekledim bottomSheetBehavior.isDraggable = falseve bu alt sayfanın sürüklenmesine dokunarak neden oldu Ve iletişim kutusunun işten çıkarılmasını kendi başıma hallettim. boş alan iletişim kutusunda zaten reddedilir.

Alt sayfanın yine de animasyonla genişlediğini unutmayın. Gerçekten harika!

eğlenceyi geçersiz kıl onCreateDialog (savedInstanceState: Bundle?): Dialog {val dialog = super.onCreateDialog (savedInstanceState)

    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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.