如何为动画连接多个recyclerview或片段,如图所示

哈马德

我的一位客户最近想出了一个奇怪的灵感,我们确实希望将其集成到他的应用程序中

原型动画在这里

我正在努力实现这一目标,但我确实感到困惑。有人可以指导我用动画实现这种过渡的步骤吗?

让我问一个具体的问题,以便您轻松回答

  1. 我们在这里应该使用什么片段或不同的view元素?
  2. 两者如何互动?就像单击沙龙类别时一样,如何将该类别部分带到顶部并保持选中状态?
  3. 如何将它们也转换为寻呼机号码?
瓦杰

gif

Note: Full working code is available at https://github.com/mwajeeh/AnimationsPlayground

More explanation in this post: https://medium.com/p/implementing-complex-animations-in-android-full-working-code-41979cc2369e

The card expand animation can be done using Shared element transition. I am going to give you enough material to start implementation of opening of categories and collapsing of pager indicators.

I am assuming that category headings are in RecyclerView. When a category is tapped, open the detail activity with shared element transitions like this:

int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
List<Pair<View, String>> pairs = new ArrayList<Pair<View, String>>();
for (int i = firstVisibleItemPosition; i <= lastVisibleItemPosition; i++) {
     ViewHolder holderForAdapterPosition = (ViewHolder) list.findViewHolderForAdapterPosition(i);
     View itemView = holderForAdapterPosition.image;
     pairs.add(Pair.create(itemView, "tab_" + i));
}
Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, pairs.toArray(new Pair[]{})).toBundle();
//launch detail activity on tap
Intent intent = new Intent(context, DetailActivity.class);
context.startActivity(intent, bundle);

In the next activity I have modified version of https://github.com/JakeWharton/ViewPagerIndicator/blob/master/library/src/com/viewpagerindicator/IconPageIndicator.java

Only these two methods are modified :

public void notifyDataSetChanged() {
    mIconsLayout.removeAllViews();
    IconPagerAdapter iconAdapter = (IconPagerAdapter) mViewPager.getAdapter();
    int count = iconAdapter.getCount();
    LayoutInflater inflater = LayoutInflater.from(getContext());
    for (int i = 0; i < count; i++) {
        View parent = inflater.inflate(R.layout.indicator, mIconsLayout, false);
        ImageView view = (ImageView) parent.findViewById(R.id.icon);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            // must be same as off previous activity
            view.setTransitionName("tab_" + i);
        }
        view.setImageResource(iconAdapter.getIconResId(i));
        mIconsLayout.addView(parent);
    }
    if (mSelectedIndex > count) {
        mSelectedIndex = count - 1;
    }
    setCurrentItem(mSelectedIndex);
    requestLayout();
}

@Override
public void setCurrentItem(int item) {
    if (mViewPager == null) {
        throw new IllegalStateException("ViewPager has not been bound.");
    }
    mSelectedIndex = item;
    mViewPager.setCurrentItem(item);

    int tabCount = mIconsLayout.getChildCount();
    for (int i = 0; i < tabCount; i++) {
        View child = mIconsLayout.getChildAt(i);
        boolean isSelected = (i == item);
        child.setSelected(isSelected);
        View foreground = child.findViewById(R.id.foreground);
        if (isSelected) {
            animateToIcon(item);
            foreground.setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.fg_white));
        } else {
            foreground.setBackgroundDrawable(ContextCompat.getDrawable(getContext(), R.drawable.fg_gray));
        }
    }
}

并添加了此方法IconPageIndicator以支持指标崩溃:

public void collapse(float top, float total) {
    //do not scale to 0
    float newTop = top / 1.2F;
    float scale = (total - newTop) / (float) total;
    ViewCompat.setScaleX(this, scale);
    ViewCompat.setScaleY(this, scale);
    int tabCount = mIconsLayout.getChildCount();
    float alpha = (total - top) / (float) total;
    for (int i = 0; i < tabCount; i++) {
        View parent = mIconsLayout.getChildAt(i);
        View child = parent.findViewById(R.id.foreground);
        ViewCompat.setAlpha(child, 1 - alpha);
    }
}

onCreate()DetailActivity,推迟过渡直到指示器布置完毕。

supportPostponeEnterTransition();
indicator.post(new Runnable() {
        @Override
        public void run() {
            supportStartPostponedEnterTransition();
        }
});

其他相关重要文件:

activity_detail.xml

<?xml version="1.0" encoding="utf-8"?>
<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/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/black"
        app:elevation="0dp">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:elevation="0dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <!--dummy view-->
            <View
                android:layout_width="match_parent"
                android:layout_height="200dp"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@android:color/transparent"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:elevation="0dp"
                app:layout_collapseMode="pin"/>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <com.example.mwajeeh.animations.IconPageIndicator
        android:id="@+id/indicator"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:centered="true"
        app:layout_behavior="com.example.mwajeeh.animations.CollapsingIndicatorBehaviour"/>

<!--add fragments in this view pager with RecyclerView as root and app:layout_behavior="@string/appbar_scrolling_view_behavior"-->
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

CollapsingIndicatorBehaviour.java

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.WindowInsetsCompat;
import android.util.AttributeSet;
import android.view.View;

public class CollapsingIndicatorBehaviour extends ViewOffsetBehavior<IconPageIndicator> {

    private static final String TAG = "CollapsingIndicatorBehaviour";
    private WindowInsetsCompat lastInsets;

    public CollapsingIndicatorBehaviour() {
    }

    public CollapsingIndicatorBehaviour(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, IconPageIndicator child, View dependency) {
        return dependency instanceof AppBarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, IconPageIndicator child, View dependency) {
        //keep child centered inside dependency respecting android:fitsSystemWindows="true"
        int systemWindowInsetTop = 0;
        if (lastInsets != null) {
            systemWindowInsetTop = lastInsets.getSystemWindowInsetTop();
        }
        int bottom = dependency.getBottom();
        float center = (bottom - systemWindowInsetTop) / 2F;
        float halfChild = child.getHeight() / 2F;
        setTopAndBottomOffset((int) (center + systemWindowInsetTop - halfChild));
        if (dependency instanceof AppBarLayout) {
            float totalScrollRange = ((AppBarLayout) dependency).getTotalScrollRange();
            child.collapse(-dependency.getTop(), totalScrollRange);
        }
        return true;
    }

    @NonNull
    @Override
    public WindowInsetsCompat onApplyWindowInsets(CoordinatorLayout coordinatorLayout, IconPageIndicator child, WindowInsetsCompat insets) {
        lastInsets = insets;
        return super.onApplyWindowInsets(coordinatorLayout, child, insets);
    }
}

android.support.design.widget.ViewOffsetBehavior.javaandroid.support.design.widget.ViewOffsetHelper复制到设计库中的代码中。这些文件不是公开的,但是我们需要它们才能使行为正常工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何创建如图所示的形状背景

SkiaSharp:如何绘制弧形,如图所示

如何使用CSS动画来创建立方体的开口,如图所示?

制作如图所示的按钮

如何在如图所示的矩形上制作梯形阴影?

如图所示,Achartengine如何移动符号(图例)

如何生成如图所示的拼贴图像

如何设置如图所示的 TextView 颜色外观?

r-如何创建如图所示的热图

如图所示,如何将框居中?

如何制作这个有角度的边框(如图所示)?

如何优化网络聊天页面,如图所示

如图所示,如何将标签放在图表的列上

如何添加如图所示的导航栏?(HTML CSS)

加载保存textarea无效,如图所示

如图所示,对Div进行样式设置

如图所示,在CSS中制作菜单

Pandas:向其他数据集添加多个唯一值(如图所示):

您如何在屏幕下方显示UISlider的值,如图所示?

如图所示,如何使用文本视图对齐Imageview和描述

如何创建水平进度指示器(如图所示)

如何在 SF 符号上应用内阴影,使其看起来如图所示?

我如何创建带有后退箭头的android活动,如图所示

如何在离子应用程序中显示如图所示的通知

如图所示,如何在android中为底部导航栏设置顶部边框

如何获得自定义的圆形进度指示器(如图所示)?

如何在按钮小部件中显示进度指示器(如图所示)

如何使切换按钮的边框(如图所示)不可见?

谁能告诉我如何创建如图所示的垂直线