Wie implementiere ich Custom Collapsable Toolbar in Android?

81

Verwenden dieses Lernprogramms zum Implementieren eines Flexible Space-Musters (das mit der reduzierten Symbolleiste).

Ich versuche, einen ähnlichen Effekt wie in der Aktivität "Lollipop-Kontakte" zu erzielen. Zu Beginn der Aktivität sind Ansichten nur ein Teil des Bildheaders:

Geben Sie hier die Bildbeschreibung ein

Anschließend kann der Benutzer das Layout unter dem Bild nach unten scrollen, um mehr davon anzuzeigen, bis das Maximum erreicht ist:

Geben Sie hier die Bildbeschreibung ein

In meiner App kann ich es nicht schaffen, dass es funktioniert.

Beim Eingeben der Aktivität wird der Bildheader in seiner maximalen Größe, der Größe des AppBarLayout, wie im obigen Layout und anders als in der Aktivität "Lollipop-Kontakte" angezeigt, in der nur ein Teil des Bildes angezeigt wird .

Dies ist der Code, der die Höhe des AppBarLayout festlegt (ich möchte, dass die Bildschirmbreite die maximale Höhe ist):

int widthPx = getResources().getDisplayMetrics().widthPixels;
AppBarLayout appbar = (AppBarLayout)findViewById(R.id.appbar);
appbar.setLayoutParams(new CoordinatorLayout.LayoutParams(CoordinatorLayout.LayoutParams.MATCH_PARENT, widthPx));

Und dies ist der Code, der die RecyclerView festlegt. Versucht mit scrollToPosition, dachte, es würde die Ansicht der RecyclerView nach oben heben, aber es hat überhaupt keine Wirkung:

mRecyclerView = (RecyclerView) findViewById(R.id.activity_profile_bottom_recyclerview);

    mRecyclerView.setHasFixedSize(true);

    // use a linear layout manager
    mLayoutManager = new LinearLayoutManager(this);

    mRecyclerView.setLayoutManager(mLayoutManager);

    // specify an adapter (see also next example)
    if(mAdapter == null){
        mAdapter = new ProfileAdapter(this, user, inEditMode);
        mRecyclerView.setAdapter(mAdapter);
    }

    mRecyclerView.scrollToPosition(mAdapter.getItemCount() - 1); // itemCount is 4

Dies ist das Layout xml:

<android.support.v4.widget.DrawerLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_profile"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="0dp" // set programatically
        android:fitsSystemWindows="true"
        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"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginBottom="32dp"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                android:id="@+id/header"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/header"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />
            <android.support.v7.widget.Toolbar
                android:id="@+id/anim_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.v7.widget.RecyclerView
        android:id="@+id/activity_profile_bottom_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

    </android.support.design.widget.CoordinatorLayout>

    <include layout="@layout/navigation_view"/>
</android.support.v4.widget.DrawerLayout>

Hinweis: Wenn ich manuell nach unten scrolle, wird die RecyclerView heruntergefahren und zeigt mehr Bilder an. Der Code funktioniert einfach nicht.

Ich denke, scrollToPosition ist nicht die Lösung, hat jemand eine Idee?

Ich habe darüber nachgedacht, das enterAlwaysCollapsed-Flag zu verwenden, wie hier im Abschnitt CoordinatorLayout und Appbar mit minHeight erwähnt:

enterAlwaysCollapsed: Wenn Ihre Ansicht eine Mindesthöhe deklariert hat und Sie dieses Flag verwenden, wird Ihre Ansicht nur in ihrer minimalen Höhe (dh "reduziert") eingegeben und erst dann wieder auf ihre volle Höhe erweitert, wenn die Bildlaufansicht ihre Spitze erreicht hat.

Also habe ich das Flag scroll | enterAlwaysCollapsed auf meine Symbolleiste und minHeight in meiner RecyclerView gesetzt, was nicht funktioniert hat. Dann habe ich versucht, die minHeight auf andere Layouts wie AppBarLayout zu verschieben, aber nichts hat funktioniert. Manchmal wurde das Bild nur ohne die gesamte Ansicht verkleinert.

Jjang
quelle
2
Danke @karaokyo, das hat tatsächlich funktioniert. Ich versuche immer noch herauszufinden, ob es auch andere Lösungen gibt.
Jjang
@ Karaokyo Könntest du das bitte überprüfen? stackoverflow.com/questions/33069081/…
Jjang
4
Mögliches Duplikat von Set Anfangshöhe des Parallaxenbildes in CollapsingToolbarLayout
dirceusemighini
Ich würde MotionLayout verwenden, um dieses Zeug zu machen. Siehe Beispiele auf https://github.com/android/views-widgets-samples/tree/master/ConstraintLayoutExamples
Lin Lin

Antworten:

1

Das AppBarComponentbietet eine Methode namens .setExpanded(boolean expanded), mit der Sie Ihre erweitern können AppBarComponent.

Beachten Sie jedoch, dass diese Methode davon abhängt, dass dieses Layout ein direktes Kind von a ist CoordinatorLayout.

Sie können dies für weitere Informationen lesen .

Wenn Sie einen benutzerdefinierten Versatz animieren möchten, verwenden Sie die setTopAndBottomOffset(int)Methode.

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBar.getLayoutParams();
final AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
if (behavior != null) {
    ValueAnimator valueAnimator = ValueAnimator.ofInt();
    valueAnimator.setInterpolator(new DecelerateInterpolator());
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            behavior.setTopAndBottomOffset((Integer) animation.getAnimatedValue());
            appBar.requestLayout();
        }
    });
    valueAnimator.setIntValues(0, -900);
    valueAnimator.setDuration(400);
    valueAnimator.start();
}
Lukas
quelle