2015-10-01 23 views
12

Я пытаюсь реализовать CollapsingToolbarLayout с пользовательской точки зрения, но я не могу это сделать:CollapsingToolbarLayout с пользовательской точки зрения

То, что я хочу сделать (жаль, что я не могу добавлять изображения так что на Imgur):

Expanded, заголовок представляет собой экран профиль с изображением и названием

enter image description here

не расширен (на свиток), изображение и название будет на панели инструментов

enter image description here

Но все, что я видел, не работает, как я ожидал

Я новичок в этом и леденец анимации, так что если кто-то может мне помочь, я буду очень благодарен!

(я не отправляю пример кода, потому что я не то отношение к сообщению)

ответ

8

мое решение

У меня был один и тот же сценарий для реализации, так что я начал с примером собаки и сделал некоторые изменения для того, чтобы работать точно так, как вы описали. Мой код можно найти как разветвление на этом проекте см https://github.com/hanscappelle/CoordinatorBehaviorExample

enter image description here enter image description here

Наиболее важные изменения в макете:

<android.support.design.widget.CoordinatorLayout 
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/main.appbar" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
    > 

    <android.support.design.widget.CollapsingToolbarLayout 
     android:id="@+id/main.collapsing" 
     android:layout_width="match_parent" 
     android:layout_height="@dimen/expanded_toolbar_height" 
     app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" 
     > 

     <FrameLayout 
      android:id="@+id/main.framelayout.title" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_gravity="bottom" 
      > 

      <LinearLayout 
       android:id="@+id/main.linearlayout.title" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_gravity="bottom|center_horizontal" 
       android:orientation="vertical" 
       android:paddingBottom="@dimen/spacing_small" 
       > 

       <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center_horizontal" 
        android:gravity="bottom|center_horizontal" 
        android:text="@string/tequila_name" 
        android:textColor="@android:color/white" 
        android:textSize="@dimen/textsize_xlarge" 
        /> 

       <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center_horizontal" 
        android:layout_marginTop="@dimen/spacing_xxsmall" 
        android:text="@string/tequila_tagline" 
        android:textColor="@android:color/white" 
        /> 

      </LinearLayout> 
     </FrameLayout> 
    </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" 
    android:scrollbars="none" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" 
    > 

    <TextView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:lineSpacingExtra="@dimen/spacing_xsmall" 
     android:padding="@dimen/spacing_normal" 
     android:text="@string/lorem" 
     android:textSize="@dimen/textsize_medium" 
     /> 

</android.support.v4.widget.NestedScrollView> 

<android.support.v7.widget.Toolbar 
    android:id="@+id/main.toolbar" 
    android:layout_width="match_parent" 
    android:layout_height="?attr/actionBarSize" 
    android:background="@color/primary" 
    app:layout_anchor="@id/main.collapsing" 
    app:theme="@style/ThemeOverlay.AppCompat.Dark" 
    app:title="" 
    > 

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

     <Space 
      android:layout_width="@dimen/image_final_width" 
      android:layout_height="@dimen/image_final_width" 
      /> 

     <TextView 
      android:id="@+id/main.textview.title" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:layout_marginLeft="8dp" 
      android:gravity="center_vertical" 
      android:text="@string/tequila_title" 
      android:textColor="@android:color/white" 
      android:textSize="@dimen/textsize_large" 
      /> 

    </LinearLayout> 
</android.support.v7.widget.Toolbar> 

<de.hdodenhof.circleimageview.CircleImageView 
    android:layout_width="@dimen/image_width" 
    android:layout_height="@dimen/image_width" 
    android:layout_gravity="top|center_horizontal" 
    android:layout_marginTop="@dimen/spacing_normal" 
    android:src="@drawable/ninja" 
    app:border_color="@android:color/white" 
    app:border_width="@dimen/border_width" 
    app:finalHeight="@dimen/image_final_width" 
    app:finalXPosition="@dimen/spacing_small" 
    app:finalYPosition="@dimen/spacing_small" 
    app:finalToolbarHeight="?attr/actionBarSize" 
    app:layout_behavior="saulmm.myapplication.AvatarImageBehavior" 
    /> 

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

И в AvatarImageBehaviour классе, который я оптимизированной для только перемещение аватара из исходной позиции в позицию, настроенную в атрибутах. Поэтому, если вы хотите, чтобы изображение перемещалось из другого места, просто переместите его в макет. Когда вы это сделаете, убедитесь, что AppBarLayout по-прежнему является его родным братом или он не будет найден в коде.

package saulmm.myapplication; 

import android.content.Context; 
import android.content.res.TypedArray; 
import android.support.design.widget.AppBarLayout; 
import android.support.design.widget.CoordinatorLayout; 
import android.util.AttributeSet; 
import android.view.View; 
import de.hdodenhof.circleimageview.CircleImageView; 

public class AvatarImageBehavior extends CoordinatorLayout.Behavior<CircleImageView> { 

// calculated from given layout 
private int startXPositionImage; 
private int startYPositionImage; 
private int startHeight; 
private int startToolbarHeight; 

private boolean initialised = false; 

private float amountOfToolbarToMove; 
private float amountOfImageToReduce; 
private float amountToMoveXPosition; 
private float amountToMoveYPosition; 

// user configured params 
private float finalToolbarHeight, finalXPosition, finalYPosition, finalHeight; 

public AvatarImageBehavior(
     final Context context, 
     final AttributeSet attrs) { 

    if (attrs != null) { 
     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AvatarImageBehavior); 
     finalXPosition = a.getDimension(R.styleable.AvatarImageBehavior_finalXPosition, 0); 
     finalYPosition = a.getDimension(R.styleable.AvatarImageBehavior_finalYPosition, 0); 
     finalHeight = a.getDimension(R.styleable.AvatarImageBehavior_finalHeight, 0); 
     finalToolbarHeight = a.getDimension(R.styleable.AvatarImageBehavior_finalToolbarHeight, 0); 
     a.recycle(); 
    } 
} 

@Override 
public boolean layoutDependsOn(
     final CoordinatorLayout parent, 
     final CircleImageView child, 
     final View dependency) { 

    return dependency instanceof AppBarLayout; // change if you want another sibling to depend on 
} 

@Override 
public boolean onDependentViewChanged(
     final CoordinatorLayout parent, 
     final CircleImageView child, 
     final View dependency) { 

    // make child (avatar) change in relation to dependency (toolbar) in both size and position, init with properties from layout 
    initProperties(child, dependency); 

    // calculate progress of movement of dependency 
    float currentToolbarHeight = startToolbarHeight + dependency.getY(); // current expanded height of toolbar 
    // don't go below configured min height for calculations (it does go passed the toolbar) 
    currentToolbarHeight = currentToolbarHeight < finalToolbarHeight ? finalToolbarHeight : currentToolbarHeight; 
    final float amountAlreadyMoved = startToolbarHeight - currentToolbarHeight; 
    final float progress = 100 * amountAlreadyMoved/amountOfToolbarToMove; // how much % of expand we reached 

    // update image size 
    final float heightToSubtract = progress * amountOfImageToReduce/100; 
    CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams(); 
    lp.width = (int) (startHeight - heightToSubtract); 
    lp.height = (int) (startHeight - heightToSubtract); 
    child.setLayoutParams(lp); 

    // update image position 
    final float distanceXToSubtract = progress * amountToMoveXPosition/100; 
    final float distanceYToSubtract = progress * amountToMoveYPosition/100; 
    float newXPosition = startXPositionImage - distanceXToSubtract; 
    //newXPosition = newXPosition < endXPosition ? endXPosition : newXPosition; // don't go passed end position 
    child.setX(newXPosition); 
    child.setY(startYPositionImage - distanceYToSubtract); 

    return true; 
} 

private void initProperties(
     final CircleImageView child, 
     final View dependency) { 

    if (!initialised) { 
     // form initial layout 
     startHeight = child.getHeight(); 
     startXPositionImage = (int) child.getX(); 
     startYPositionImage = (int) child.getY(); 
     startToolbarHeight = dependency.getHeight(); 
     // some calculated fields 
     amountOfToolbarToMove = startToolbarHeight - finalToolbarHeight; 
     amountOfImageToReduce = startHeight - finalHeight; 
     amountToMoveXPosition = startXPositionImage - finalXPosition; 
     amountToMoveYPosition = startYPositionImage - finalYPosition; 
     initialised = true; 
    } 
} 
} 

Источники

Наиболее распространенным примером является один с собакой, перечисленных в https://github.com/saulmm/CoordinatorBehaviorExample. Это хороший пример, но на самом деле панель инструментов находится в середине расширенного представления с обратным фоном, которое также перемещается. Все, что было удалено в моем примере.

Еще одно объяснение можно найти по адресу http://www.devexchanges.info/2016/03/android-tip-custom-coordinatorlayout.html, но с учетом того, что изображение облачного/морского фона, на которое ссылается, также найдено на примере собаки, очевидно, что оно построено поверх другого.

Я также нашел этот SO вопрос с Баунти присужденной, но не мог узнать, что окончательное решение было Add icon with title in CollapsingToolbarLayout

И, наконец, это должна быть рабочая библиотека, которая делает работу. Я проверил это, но исходное изображение не было сосредоточено, и я скорее работал на примере собаки, на который я раньше смотрел. См https://github.com/datalink747/CollapsingAvatarToolbar

Больше читать

http://saulmm.github.io/mastering-coordinator http://www.androidauthority.com/using-coordinatorlayout-android-apps-703720/ https://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.html https://guides.codepath.com/android/handling-scrolls-with-coordinatorlayout

0

Вы можете использовать эту library, это очень гибкий и у вас есть инструкции на его странице.

+0

Да я уже видел это, но я не нашел, как добавить изображение в центре заголовка и переместить его в панель инструментов – ChargerDukes

+0

Ну, вы можете создать значок меню для своего маленького изображения, и, хотя заголовок не свернут, вы можете скрыть его (заголовок содержит большое изображение по умолчанию). Когда анимация закончилась (заголовок был свернут), вы можете показать его снова. – Lazai

+0

@Lazai, который не дал бы такого же эффекта, это будет похоже на изменение мерцания – AnswerDroid

10

Вы можете использовать этот код, например, https://github.com/saulmm/CoordinatorBehaviorExample от Saul MM для достижения этого эффекта. Код слишком велик для вставки здесь, поэтому не вставляйте какой-либо код. Надеюсь, это вам поможет.

+1

Да, я уже пробовал, но я не смог прикрепить панель к вершине (в примере панель инструментов посередине, когда она не установлена) – ChargerDukes

+0

Какая проблема именно вы сейчас столкнулись? –

+0

Когда я прикрепляю панель инструментов вверху, я не могу центрировать изображение профиля и переместить его в верхний левый – ChargerDukes

Смежные вопросы