Hintergrund
Ich bin damit beauftragt, eine Benutzeroberfläche zu erstellen, die sich ähnlich verhält wie Google Maps ein unteres Blatt für ein gefundenes Ergebnis anzeigt.
Es hat drei verschiedene Phasen:
- Unterer Inhalt. Der obere Bereich ist noch berührbar und wird unten nichts scrollen
- Vollbildinhalt, während der obere Bereich eine große Kopfzeile hat.
- Vollbildinhalt, während der obere Bereich nur die Symbolleiste enthält.
Ich spreche in Google Maps über Folgendes:
Das Problem
Das Ding ist, das untere Blatt nicht ein Teil der Design - Bibliothek ist noch (obwohl es angefordert wurde, hier ).
Darüber hinaus scheint die Benutzeroberfläche recht komplex zu sein und muss in mehreren Phasen mit der Symbolleiste behandelt werden.
Was ich versucht habe
Ich habe eine gute (ausreichende) Bibliothek für das untere Blatt ( hier ) gefunden und dem Fragmentbeispiel Inhalt hinzugefügt, um ungefähr die gleichen Ansichten wie bei Materialdesignbeispielen (wie hier ) zu haben und ein CollapsingToolbarLayout zu haben, das sich darum kümmert der Phasen 2 + 3.
In der App, die ich mache, muss ich beim Scrollen auch ein Symbol verschieben, aber ich denke, wenn ich mit dem Rest Erfolg habe, sollte dies einfach sein. Hier ist der Code:
fragment_my.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="@dimen/detail_backdrop_height"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/card_margin">
<LinearLayout
style="@style/Widget.CardContent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Info"
android:textAppearance="@style/TextAppearance.AppCompat.Title"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/cheese_ipsum"/>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/card_margin"
android:layout_marginLeft="@dimen/card_margin"
android:layout_marginRight="@dimen/card_margin">
<LinearLayout
style="@style/Widget.CardContent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Friends"
android:textAppearance="@style/TextAppearance.AppCompat.Title"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/cheese_ipsum"/>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/card_margin"
android:layout_marginLeft="@dimen/card_margin"
android:layout_marginRight="@dimen/card_margin">
<LinearLayout
style="@style/Widget.CardContent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Related"
android:textAppearance="@style/TextAppearance.AppCompat.Title"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/cheese_ipsum"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:clickable="true"
android:src="@android:drawable/ic_menu_send"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"/>
</android.support.design.widget.CoordinatorLayout>
MyFragment.java
public class MyFragment extends BottomSheetFragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_my, container, false);
view.setMinimumHeight(getResources().getDisplayMetrics().heightPixels);
CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) view.findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle("AAA");
final Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
final AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
NavUtils.navigateUpFromSameTask(getActivity());
}
});
final ImageView imageView = (ImageView) view.findViewById(R.id.backdrop);
Glide.with(this).load(R.drawable.cheese_1).centerCrop().into(imageView);
return view;
}
}
BottomSheetFragmentActivity.java
public final class BottomSheetFragmentActivity extends AppCompatActivity {
protected BottomSheetLayout bottomSheetLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bottom_sheet_fragment);
bottomSheetLayout = (BottomSheetLayout) findViewById(R.id.bottomsheet);
findViewById(R.id.bottomsheet_fragment_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new MyFragment().show(getSupportFragmentManager(), R.id.bottomsheet);
}
});
bottomSheetLayout.setShouldDimContentView(false);
bottomSheetLayout.setPeekOnDismiss(true);
bottomSheetLayout.setPeekSheetTranslation(200);
bottomSheetLayout.setInterceptContentTouch(false);
bottomSheetLayout.setDefaultViewTransformer(new BaseViewTransformer() {
@Override
public void transformView(final float translation, final float maxTranslation, final float peekedTranslation, final BottomSheetLayout parent, final View view) {
Log.d("AppLog", "translation:" + translation + " maxTranslation:" + maxTranslation + " peekedTranslation:" + peekedTranslation);
}
});
}
}
Es funktioniert fast gut. Das einzige Problem ist der Übergang von # 3 zurück zu # 2:
Die Frage
Was ist los mit dem Code? Was kann ich tun, um das erforderliche Verhalten zu erreichen?
quelle
CoordinatorLayout
auf dem 2. Bildschirm verwendet?Antworten:
Hinweis : Lesen Sie die Änderungen unten
OK, ich habe einen Weg gefunden, dies zu tun, aber ich musste den Code mehrerer Klassen ändern, damit das untere Blatt den Status des appBarLayout (erweitert oder nicht) kennt und das Scrollen nach oben ignoriert, falls dies der Fall ist nicht erweitert:
BottomSheetLayout.java
Felder hinzugefügt:
init () - hat Folgendes hinzugefügt:
Funktion zum Festlegen des appBarLayout hinzugefügt:
onDetachedFromWindow () - hat Folgendes hinzugefügt:
onTouchEvent () - hat Folgendes hinzugefügt:
Das waren die wichtigsten Änderungen. Nun zu dem, was sie ausmacht:
MyFragment.java
onCreateView () - hat Folgendes hinzugefügt:
Ich habe auch diese Funktion hinzugefügt:
So teilt die Aktivität dem Fragment das appBarLayout mit:
Das Projekt ist jetzt auf GitHub verfügbar:
https://github.com/AndroidDeveloperLB/ThreePhasesBottomSheet
Ich hoffe es hat keine Bugs.
Die Lösung hat leider Fehler, daher werde ich diese Antwort nicht als die richtige markieren:
Wenn jemand dabei helfen kann, bitte.
Für Problem Nr. 1 habe ich versucht, einen Fix hinzuzufügen, indem ich die Sichtbarkeit auf UNSICHTBAR gesetzt habe, wenn das untere Blatt noch nicht gesehen wurde, aber es funktioniert nicht immer, insbesondere wenn eine Tastatur angezeigt wird.
Für Problem Nr. 1 habe ich herausgefunden, wie es behoben werden kann, indem ich einfach (in "fragment_my.xml") das CoordinatorLayout mit einer beliebigen Ansicht umhülle, die Sie verwenden möchten (ich habe FrameLayout verwendet), und auch eine Ansicht in voller Größe eingefügt habe es (ich habe gerade "Ansicht" gesetzt) als solches:
Es hat wahrscheinlich das untere Blatt verwirrt, als ich das CoordinatorLayout als Ansicht hatte. Ich habe das Projekt aktualisiert, aber wenn es eine Möglichkeit gibt, eine bessere Lösung zu finden, würde ich gerne davon erfahren.
In den letzten Monaten hat Google eine eigene bottomSheet-Klasse veröffentlicht, aber wie ich festgestellt habe, gibt es viele Probleme, sodass ich sie nicht einmal ausprobieren kann.
quelle
GROSSES UPDATE
Da es ungefähr 4 oder 5 Fragen zum selben Thema gab, ABER mit VERSCHIEDENEN Anforderungen, und ich versuchte, alle zu beantworten, löschte / schloss ein unhöflicher Administrator sie, sodass ich für jedes ein Ticket erstellte und sie in änderte Vermeiden Sie "Kopieren Einfügen" Ich werde Ihnen einen Link zur vollständigen Antwort geben, in dem Sie alle Erklärungen finden, wie Sie ein vollständiges Verhalten wie Google Maps erhalten.
Beantwortung Ihrer Frage
Mit der Support-Bibliothek 23.x.x + können Sie die Standardeinstellung ändern
BottomSheetBehavior
und eine weitere Statistik mit den folgenden Schritten hinzufügen:CoordinatorLayout.Behavior<V>
BottomSheetBehavior
in Ihre neue.Ändern Sie die Methode
clampViewPositionVertical
mit dem folgenden Code:Neuen Status hinzufügen:
Ändern Sie die folgenden Methoden:
onLayoutChild
,onStopNestedScroll
,BottomSheetBehavior<V> from(V view)
undsetState
(optional)Ich werde diese geänderten Methoden und einen Link zum Beispielprojekt hinzufügen .
Und so sieht es aus:
quelle
CoordinatorLayout
In hinzufügenactivity_main.xml
. Ich denke, Sie haben gute Erfahrungen mit dem Layout des Koordinators gemacht, ansonsten werfen Sie einen Blick auf diesen Link, den ich gefunden habeHast du das versucht? http://android-developers.blogspot.in/2016/02/android-support-library-232.html?m=1 Hier heißt es, dass wir nur ein Layoutverhalten für das untere Blatt angeben können.
AKTUALISIEREN:
Grundsätzlich heißt der Link-
Durch Anhängen eines BottomSheetBehavior an eine untergeordnete Ansicht eines CoordinatorLayout (dh Hinzufügen einer App: layout_behavior = "android.support.design.widget.BottomSheetBehavior") erhalten Sie automatisch die entsprechende Berührungserkennung für den Übergang zwischen fünf Status:
Wenn Sie Rückrufe von Statusänderungen erhalten möchten, können Sie einen BottomSheetCallback hinzufügen:
Während BottomSheetBehavior den persistenten Fall des unteren Blattes erfasst, bietet diese Version auch einen BottomSheetDialog und ein BottomSheetDialogFragment, um den Anwendungsfall der modalen unteren Blätter zu füllen. Ersetzen Sie einfach AppCompatDialog oder AppCompatDialogFragment durch ihre unteren Blattäquivalente, damit Ihr Dialog als unteres Blatt gestaltet wird.
quelle
Ich musste auch eine ähnliche Ansicht implementieren, wie Google Maps ein unteres Blatt für ein gefundenes Ergebnis anzeigt.
So sieht meins aus:
Zuerst habe ich ein unteres Blatt mit einer Kopfzeile und einem scrollbaren Inhalt definiert, aber die layout_height schien den Inhalt weder der Kopfzeile noch des scrollbaren Inhalts trotz Angabe zu umbrechen
wrap_content
.Das Problem ging weg , als ich verwenden ,
LinearLayout
anstattConstraintLayout
für dieCoordinatorLayout
Kinder s‘Layout (und für ihre Kinder).activity_main.xml
MainActivity.java
app / build.gradle
quelle