Ik heb een BottomSheetView
met animateLayoutChanges="true"
. In eerste instantie komt het goed over. Maar als de visibility
van een weergave (in BottomSheetView
) wordt gewijzigd van GONE
in VISIBLE
, verprutst de app de berekeningen en mijn BottomSheetView
gaat naar de bovenkant van het scherm. ik heb geprobeerd layout_gravity=bottom
in te stellen in de hoofdmap van de lay-out BottomSheetView
. Maar geen succes.
Hier heb ik de afbeelding van mijn BottomSheetView
voordat ik de zichtbaarheid van een weergave verander. (Klik op afbeelding voor volledige grootte)
Nadat ik de zichtbaarheid van een weergave heb gewijzigd (GONE
in VISIBLE
of VISIBLE
in GONE
), wordt mijn BottomSheetView gaat naar boven. (Klik op afbeelding voor volledige grootte)
Ik denk dat Android aan het verknoeien is bij het maken van berekeningen over de meting van de weergave width
en height
. Is er een manier om dit op te lossen??
Ik heb ook geprobeerd om mijn BottomSheetView volledig uit te breiden om overeen te komen met de bovenliggende weergave, maar op de een of andere manier maakt dat de height
van de BottomSheetView
langer dan het telefoonscherm en in- tun het creëren van scrollproblemen.
Verwachte oplossingen:
1> Voorkom dat BottomSheetView
zijn positie verandert, zelfs wanneer de visibility
van een weergave wordt gewijzigd.
OF
2>Zorg ervoor dat de BottomSheetView
overeenkomt met de ouder, zodat het er niet slecht uitziet na het verknoeien van de berekeningen.
Antwoord 1, autoriteit 100%
Het BottomSheetBehavior werkt voorlopig niet goed met LayoutTransition
(animateLayoutChanges="true"
). Ik zal aan een oplossing werken.
Voorlopig kun je in plaats daarvan Transition
gebruiken. Zoiets vervaagt het zicht binnenin en animeert het formaat van het onderste vel.
ViewGroup bottomSheet = ...;
View hidingView = ...;
TransitionManager.beginDelayedTransition(bottomSheet);
hidingView.setVisibility(View.GONE);
Je kunt Een transitie toepassenraadplegen voor meer informatie, waaronder het aanpassen de animatie.
Antwoord 2, autoriteit 38%
Ik liep tegen hetzelfde probleem aan en was vastbesloten om een oplossing te vinden. Ik heb de onderliggende oorzaak kunnen vinden, maar helaas zie ik momenteel geen goede oplossing.
De oorzaak:
Het probleem doet zich voor tussen het gedrag van het onderblad en de LayoutTransition. Wanneer de LayoutTransition is gemaakt, wordt een OnLayoutChangeListener in de weergave gemaakt, zodat deze de eindwaarden kan vastleggen en een animator met de juiste waarden kan instellen. Deze OnLayoutChangeListener wordt geactiveerd in de onLayout()
-aanroep van bottomSheetBehavior wanneer deze voor het eerst parent.onLayout(child)
aanroept. De ouder zal het kind indelen zoals het normaal zou doen, en negeert eventuele verschuivingen die het gedrag later zou veranderen. Het probleem ligt hier. De waarden van de weergave op dit punt worden vastgelegd door de OnLayoutChangeListener en opgeslagen in de animator. Wanneer de animatie wordt uitgevoerd, wordt deze geanimeerd naar deze waarden, niet naar waar uw gedrag definieert. Helaas geeft de klasse LayoutTransition ons geen toegang tot de animators om het bijwerken van de eindwaarden mogelijk te maken.
De oplossing:
Momenteel zie ik geen elegante oplossing voor LayoutTransitions. Ik ga een bug indienen voor een manier om LayoutTransition-animators te openen en bij te werken. Voor nu kun je elke layoutTransition op de bovenliggende container uitschakelen met layoutTransition.setAnimateParentHierarchy(false)
. Vervolgens kunt u de wijziging zelf animeren. Ik zal mijn antwoord zo snel mogelijk bijwerken met een werkend voorbeeld.
Antwoord 3, autoriteit 25%
De vraag is meer dan twee jaar geleden gesteld, maar helaas blijft het probleem bestaan.
Ik heb eindelijk een oplossing om de aanroep van de functies addView
en removeView
in een BottomSheet te houden, terwijl ik animateLayoutChanges="true"
heb .
BottomSheetBehavior
kan de juiste hoogte niet berekenen wanneer deze verandert, dus de hoogte moet hetzelfde blijven. Om dit te doen, stel ik de hoogte van de BottomSheet
in op match_parent
en verdeel het in twee onderliggende items: de inhoud en een Space
die van hoogte verandert naargelang tot de hoogte van de inhoud.
Om het ware gedrag van een BottomSheet
zo goed mogelijk na te bootsen, moet je ook een TouchToDismiss-weergave toevoegen die de achtergrond donkerder maakt wanneer de BottomSheet
wordt verlengd, maar ook om de BottomSheet
wanneer de gebruiker buiten de inhoud drukt.
Hier is de code:
activiteit.xml
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/show_bottom_sheet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show bottom sheet"/>
<View
android:id="@+id/touch_to_dismiss"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:background="#9000"/>
<LinearLayout
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<Space
android:id="@+id/space"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:id="@+id/bottom_sheet_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:animateLayoutChanges="true">
<Button
android:id="@+id/add_or_remove_another_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add another view"/>
<TextView
android:id="@+id/another_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Another view"/>
</LinearLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
activiteit.java
BottomSheetBehavior bottomSheetBehavior;
View touchToDismiss;
LinearLayout bottomSheet;
Button showBottomSheet;
Space space;
LinearLayout bottomSheetContent;
Button addOrRemoveAnotherView;
TextView anotherView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
touchToDismiss = findViewById(R.id.touch_to_dismiss);
touchToDismiss.setVisibility(View.GONE);
touchToDismiss.setOnClickListener(this);
bottomSheet = findViewById(R.id.bottom_sheet);
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setPeekHeight(0);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN || newState == BottomSheetBehavior.STATE_COLLAPSED) {
touchToDismiss.setVisibility(View.GONE);
}else {
touchToDismiss.setVisibility(View.VISIBLE);
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
touchToDismiss.setAlpha(getRealOffset());
}
});
showBottomSheet = findViewById(R.id.show_bottom_sheet);
showBottomSheet.setOnClickListener(this);
space = findViewById(R.id.space);
bottomSheetContent = findViewById(R.id.bottom_sheet_content);
addOrRemoveAnotherView = findViewById(R.id.add_or_remove_another_view);
addOrRemoveAnotherView.setOnClickListener(this);
anotherView = findViewById(R.id.another_view);
bottomSheetContent.removeView(anotherView);
}
@Override
public void onClick(View v) {
if (v == showBottomSheet)
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
else if (v == addOrRemoveAnotherView) {
if (anotherView.getParent() == null)
bottomSheetContent.addView(anotherView);
else
bottomSheetContent.removeView(anotherView);
}
else if (v == touchToDismiss)
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
/**
* Since the height does not change and remains at match_parent, it is required to calculate the true offset.
* @return Real offset of the BottomSheet content.
*/
public float getRealOffset() {
float num = (space.getHeight() + bottomSheetContent.getHeight()) - (bottomSheet.getY() + space.getHeight());
float den = bottomSheetContent.getHeight();
return (num / den);
}
Dit is het resultaat verkregen met deze code:
Hopelijk zal iemand er iets aan hebben, aangezien het probleem er nog steeds is!
Antwoord 4, autoriteit 6%
In de standaardlay-out van BottomSheetDialog (design_bottom_sheet_dialog ) er is een TOPzwaartekracht op de design_bottom_sheet
FrameLayout van het dialoogvenster:
android:layout_gravity="center_horizontal|top"
Ik weet niet echt waarom op BottomSheetDialog de zwaartekracht bovenaan is.
U moet hetzelfde lay-outbestand (dezelfde inhoud en naam) in uw project maken en deze regel vervangen door:
android:layout_gravity="center_horizontal|bottom"
Antwoord 5
In ons geval gaven we een voortgangsbalk weer op een knoponderdeel. Dit was het verbergen van de knoptekst en het weergeven van de voortgangsbalk. Dit veroorzaakte een sprong in het onderste bladfragment. Het gebruik van Invisible in plaats van Gone loste het probleem op.
Antwoord 6
Als je zicht het toelaat, maak dan de zichtbaarheid ONZICHTBAAR in plaats van GEGAAN.