问题描述
我试图找出如何展开/折叠动画工具栏完成。如果你看一下在电报应用程序设置,你会看到有一个列表视图和工具栏。当你向下滚动,在工具栏崩溃,当你滚动它扩展。也有轮廓峰和FAB的动画。有没有人有任何线索?你认为他们建立在它上面所有的动画?也许我失去了一些东西在新的API或支持库。
I'm trying to figure out how the expand/collapse animation of the toolbar is done. If you have a look at the Telegram app settings, you will see that there is a listview and the toolbar. When you scroll down, the toolbar collapse, and when you scroll up it expands. There is also the animation of the profile pic and the FAB. Does anyone have any clue on that? Do you think they built all the animations on top of it? Maybe I'm missing something from the new APIs or the support library.
我注意到了谷歌日历应用程序相同的行为,当你打开微调(我不认为这是一个微调,但它看起来像):工具栏扩展,当你向上滚动,它崩溃。
I noticed the same behaviour on the Google calendar app, when you open the Spinner (I don't think it's a spinner, but it looks like): The toolbar expands and when you scroll up, it collapse.
只是为了clearify:我不需要QuickReturn方法。我知道,也许电报应用程序使用类似的东西。我需要的确切方法是谷歌日历应用程序的影响。我试着以
Just to clearify: I don't need the QuickReturn method. I know that probably Telegram app is using something similar. The exact method that I need is the Google Calendar app effect. I've tried with
android:animateLayoutChanges="true"
和展开方法的工作原理pretty的好。但很明显,如果我向上滚动ListView控件时,工具栏不会倒塌。
and the expand method works pretty well. But obviously, If I scroll up the ListView, the toolbar doesn't collapse.
我也想过加入 GestureListener
,但我想知道是否有任何的API或实现这一目标的简单的方法。
I've also thought about adding a GestureListener
but I want to know if there are any APIs or simpler methods of achieving this.
如果有没有,我想我会用 GestureListener
去。希望能有动画的平滑效果。
If there are none, I think I will go with the GestureListener
. Hopefully to have a smooth effect of the Animation.
谢谢!
推荐答案
编辑:
由于Android的设计支持库的发布,有一个简单的解决方案。检查华的回答
Since the release of the Android Design support library, there's an easier solution. Check joaquin's answer
-
下面是我是如何做到的,也许还有许多其他的解决方案,但这个工作对我来说。
Here's how I did it, there probably are many other solutions but this one worked for me.
-
首先,你必须使用一个
工具栏
透明背景。不断扩大的&放大器;折叠工具栏
实际上是一个假一个是在透明工具栏
。 ( - 一个与利润 - 你可以在下面的第一个截图中看到,这也是他们怎么做的电报)。
First of all, you have to use a
Toolbar
with a transparent background. The expanding & collapsingToolbar
is actually a fake one that's under the transparentToolbar
. (you can see on the first screenshot below - the one with the margins - that this is also how they did it in Telegram).
我们只保留实际工具栏
为 NavigationIcon
和溢出菜单项
。
We only keep the actual Toolbar
for the NavigationIcon
and the overflow MenuItem
.
一切,是在第二个屏幕的红色矩形(即假工具栏
和 FloatingActionButton
)实际上是头您添加到设置的ListView
(或滚动型
)。
Everything that's in the red rectangle on the second screenshot (ie the fake Toolbar
and the FloatingActionButton
) is actually a header that you add to the settings ListView
(or ScrollView
).
所以,你必须创建一个布局在一个单独的文件,这个头,可能是这样的:
So you have to create a layout for this header in a separate file that could look like this :
<!-- The headerView layout. Includes the fake Toolbar & the FloatingActionButton -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/header_container"
android:layout_width="match_parent"
android:layout_height="@dimen/header_height"
android:layout_marginBottom="3dp"
android:background="@android:color/holo_blue_dark">
<RelativeLayout
android:id="@+id/header_infos_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:padding="16dp">
<ImageView
android:id="@+id/header_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:src="@android:drawable/ic_dialog_info" />
<TextView
android:id="@+id/header_title"
style="@style/TextAppearance.AppCompat.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/header_picture"
android:text="Toolbar Title"
android:textColor="@android:color/white" />
<TextView
android:id="@+id/header_subtitle"
style="@style/TextAppearance.AppCompat.Subhead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/header_title"
android:layout_toRightOf="@+id/header_picture"
android:text="Toolbar Subtitle"
android:textColor="@android:color/white" />
</RelativeLayout>
</RelativeLayout>
<FloatingActionButton
android:id="@+id/header_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="10dp"
android:src="@drawable/ic_open_in_browser"/>
</FrameLayout>
(请注意,您可以使用负利润率/填充的工厂将跨越2 浏览
)
现在到了有趣的部分。为了动画我们的假工具栏
,我们实行的扩张的ListView
onScrollListener
。
Now comes the interesting part. In order to animate the expansion of our fake Toolbar
, we implement the ListView
onScrollListener
.
// The height of your fully expanded header view (same than in the xml layout)
int headerHeight = getResources().getDimensionPixelSize(R.dimen.header_height);
// The height of your fully collapsed header view. Actually the Toolbar height (56dp)
int minHeaderHeight = getResources().getDimensionPixelSize(R.dimen.action_bar_height);
// The left margin of the Toolbar title (according to specs, 72dp)
int toolbarTitleLeftMargin = getResources().getDimensionPixelSize(R.dimen.toolbar_left_margin);
// Added after edit
int minHeaderTranslation;
private ListView listView;
// Header views
private View headerView;
private RelativeLayout headerContainer;
private TextView headerTitle;
private TextView headerSubtitle;
private FloatingActionButton headerFab;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.listview_fragment, container, false);
listView = rootView.findViewById(R.id.listview);
// Init the headerHeight and minHeaderTranslation values
headerHeight = getResources().getDimensionPixelSize(R.dimen.header_height);
minHeaderTranslation = -headerHeight +
getResources().getDimensionPixelOffset(R.dimen.action_bar_height);
// Inflate your header view
headerView = inflater.inflate(R.layout.header_view, listview, false);
// Retrieve the header views
headerContainer = (RelativeLayout) headerView.findViewById(R.id.header_container);
headerTitle = (TextView) headerView.findViewById(R.id.header_title);
headerSubtitle = (TextView) headerView.findViewById(R.id.header_subtitle);
headerFab = (TextView) headerView.findViewById(R.id.header_fab);;
// Add the headerView to your listView
listView.addHeaderView(headerView, null, false);
// Set the onScrollListener
listView.setOnScrollListener(this);
// ...
return rootView;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
// Do nothing
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
Integer scrollY = getScrollY(view);
// This will collapse the header when scrolling, until its height reaches
// the toolbar height
headerView.setTranslationY(Math.max(0, scrollY + minHeaderTranslation));
// Scroll ratio (0 <= ratio <= 1).
// The ratio value is 0 when the header is completely expanded,
// 1 when it is completely collapsed
float offset = 1 - Math.max(
(float) (-minHeaderTranslation - scrollY) / -minHeaderTranslation, 0f);
// Now that we have this ratio, we only have to apply translations, scales,
// alpha, etc. to the header views
// For instance, this will move the toolbar title & subtitle on the X axis
// from its original position when the ListView will be completely scrolled
// down, to the Toolbar title position when it will be scrolled up.
headerTitle.setTranslationX(toolbarTitleLeftMargin * offset);
headerSubtitle.setTranslationX(toolbarTitleLeftMargin * offset);
// Or we can make the FAB disappear when the ListView is scrolled
headerFab.setAlpha(1 - offset);
}
// Method that allows us to get the scroll Y position of the ListView
public int getScrollY(AbsListView view)
{
View c = view.getChildAt(0);
if (c == null)
return 0;
int firstVisiblePosition = view.getFirstVisiblePosition();
int top = c.getTop();
int headerHeight = 0;
if (firstVisiblePosition >= 1)
headerHeight = this.headerHeight;
return -top + firstVisiblePosition * c.getHeight() + headerHeight;
}
请注意,有这个code我没有测试的某些部分,可以随意突出的错误。但总体而言,我知道,这个解决方案的工作,即使我敢肯定,它可以改进。
Note that there are some parts of this code I didn't test, so feel free to highlight mistakes. But overall, I'm know that this solution works, even though I'm sure it can be improved.
编辑2:
有在code以上的一些错误(我没有测试直到今天......),所以我换了几行,使其工作:
There were some mistakes in the code above (that I didn't test until today...), so I changed a few lines to make it work :
- 在我介绍了另一个变量,minHeaderTranslation,它取代minHeaderHeight;
-
我改变施加在头查看从Y平移值:
- I introduced another variable, minHeaderTranslation, which replaced minHeaderHeight;
I changed the Y translation value applied to the header View from :
headerView.setTranslationY(Math.max(-scrollY, minHeaderTranslation));
到
headerView.setTranslationY(Math.max(0, scrollY + minHeaderTranslation));
previous EX pression是不工作的,我很抱歉......
Previous expression wasn't working at all, I'm sorry about that...
的比率计算也改变,使得它现在演变从底部工具栏(而不是在屏幕的顶部)到全扩展报头
The ratio calculation also changed, so that it now evolves from the bottom the toolbar (instead of the top of the screen) to the full expanded header.
这篇关于展开/折叠棒棒糖工具栏动画(电报应用程序)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!