Pau*_*ezM 221 android android-layout android-recyclerview
如何出现时,如何为RecyclerView项目设置动画?
默认项目animator仅在设置回收器数据后添加或删除数据时动画.我是新开发的应用程序,并没有任何线索从哪里开始.
任何想法如何实现这一目标?
Mat*_*ree 307
编辑:
此类定义在对适配器进行更改时对项目进行的动画.
因此,除非您逐个添加项目RecyclerView
并在每次迭代时刷新视图,否则我认为不是ItemAnimator
您需要的解决方案.
以下是RecyclerView
使用CustomAdapter显示项目时的动画:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder>
{
private Context context;
// The items to display in your RecyclerView
private ArrayList<String> items;
// Allows to remember the last item shown on screen
private int lastPosition = -1;
public static class ViewHolder extends RecyclerView.ViewHolder
{
TextView text;
// You need to retrieve the container (ie the root ViewGroup from your custom_item_layout)
// It's the view that will be animated
FrameLayout container;
public ViewHolder(View itemView)
{
super(itemView);
container = (FrameLayout) itemView.findViewById(R.id.item_layout_container);
text = (TextView) itemView.findViewById(R.id.item_layout_text);
}
}
public CustomAdapter(ArrayList<String> items, Context context)
{
this.items = items;
this.context = context;
}
@Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_item_layout, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position)
{
holder.text.setText(items.get(position));
// Here you apply the animation when the view is bound
setAnimation(holder.itemView, position);
}
/**
* Here is the key method to apply the animation
*/
private void setAnimation(View viewToAnimate, int position)
{
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition)
{
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
}
Run Code Online (Sandbox Code Playgroud)
你的custom_item_layout看起来像这样:
<FrameLayout
android:id="@+id/item_layout_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/item_layout_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeightSmall"/>
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)
有关CustomAdapters的更多信息RecyclerView
,请参阅官方文档中的此培训.
快速滚动的问题
使用此方法可能会导致快速滚动问题.在动画发生时,可以重复使用视图.为了避免建议在分离时清除动画.
@Override
public void onViewDetachedFromWindow(final RecyclerView.ViewHolder holder)
{
((CustomViewHolder)holder).clearAnimation();
}
Run Code Online (Sandbox Code Playgroud)
在CustomViewHolder上:
public void clearAnimation()
{
mRootLayout.clearAnimation();
}
Run Code Online (Sandbox Code Playgroud)
老答案:
看看Gabriele Mariotti的回购,我很确定你能找到你需要的东西.他为RecyclerView提供了简单的ItemAnimators,例如SlideInItemAnimator或SlideScaleItemAnimator.
pbm*_*pbm 57
Recyclerview
当项目第一次出现时,我动画淡出其中,如下面的代码所示.也许这对某人有用.
private final static int FADE_DURATION = 1000; //FADE_DURATION in milliseconds
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.getTextView().setText("some text");
// Set the view to fade in
setFadeAnimation(holder.itemView);
}
private void setFadeAnimation(View view) {
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(FADE_DURATION);
view.startAnimation(anim);
}
Run Code Online (Sandbox Code Playgroud)
您还可以setFadeAnimation()
使用以下内容替换setScaleAnimation()
项目的外观,方法是从一个点缩放它们:
private void setScaleAnimation(View view) {
ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(FADE_DURATION);
view.startAnimation(anim);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码有一些瑕疵,当你滚动RecyclerView
项目总是淡出或缩放.如果您希望可以添加代码以仅在RecyclerView
首次创建包含该片段或活动的片段或活动时允许动画发生(例如,在创建时获取系统时间并且仅允许第一个FADE_DURATION毫秒的动画).
Bas*_*ANI 23
我从pbm的答案中创建了动画,但没有modification
让aninmation只运行一次
换句话说 Animation appear with you scroll down only
private int lastPosition = -1;
private void setAnimation(View viewToAnimate, int position) {
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition) {
ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(new Random().nextInt(501));//to make duration random number between [0,501)
viewToAnimate.startAnimation(anim);
lastPosition = position;
}
}
Run Code Online (Sandbox Code Playgroud)
并在onBindViewHolder
调用函数
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.getTextView().setText("some text");
// call Animation function
setAnimation(holder.itemView, position);
}
Run Code Online (Sandbox Code Playgroud)
Pav*_*kov 14
您可以将一个android:layoutAnimation ="@ anim/rv_item_animation"属性添加到RecyclerView,如下所示:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/layout_animation_fall_down"
/>
Run Code Online (Sandbox Code Playgroud)
感谢这里出色的文章:https: //proandroiddev.com/enter-animation-using-recyclerview-and-layoutanimation-part-1-list-75a874a5d213
iam*_*ran 14
仅通过XML变得简单
res / anim / layout_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/item_animation_fall_down"
android:animationOrder="normal"
android:delay="15%" />
Run Code Online (Sandbox Code Playgroud)
res / anim / item_animation_fall_down.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500">
<translate
android:fromYDelta="-20%"
android:toYDelta="0"
android:interpolator="@android:anim/decelerate_interpolator"
/>
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:interpolator="@android:anim/decelerate_interpolator"
/>
<scale
android:fromXScale="105%"
android:fromYScale="105%"
android:toXScale="100%"
android:toYScale="100%"
android:pivotX="50%"
android:pivotY="50%"
android:interpolator="@android:anim/decelerate_interpolator"
/>
</set>
Run Code Online (Sandbox Code Playgroud)
在布局和recylcerview中使用,例如:
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutAnimation="@anim/layout_animation"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
Run Code Online (Sandbox Code Playgroud)
一个好的起点是:https: //github.com/wasabeef/recyclerview-animators/blob/master/animators/src/main/java/jp/wasabeef/recyclerview/adapters/AnimationAdapter.java
你甚至不需要完整的库,那个类就足够了.然后,如果你只是实现你的Adapter类给出这样的动画师:
@Override
protected Animator[] getAnimators(View view) {
return new Animator[]{
ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0)
};
}
@Override
public long getItemId(final int position) {
return getWrappedAdapter().getItemId(position);
}
Run Code Online (Sandbox Code Playgroud)
你会看到当它们滚动时从底部出现的项目,也避免了快速滚动的问题.
当它们绑定在适配器中时,在 recyclerview 中动画项目可能不是最好的主意,因为这可能导致 recyclerview 中的项目以不同的速度动画。在我的情况下,recyclerview 末尾的项目比顶部的项目更快地动画到他们的位置,因为顶部的项目需要走得更远,所以它看起来不整洁。
我用来将每个项目动画化到 recyclerview 的原始代码可以在这里找到:
http://frogermcs.github.io/Instagram-with-Material-Design-concept-is-getting-real/
但我会复制并粘贴代码,以防链接中断。
第 1步:在您的 onCreate 方法中设置它,以确保动画只运行一次:
if (savedInstanceState == null) {
pendingIntroAnimation = true;
}
Run Code Online (Sandbox Code Playgroud)
第 2 步:您需要将此代码放入要启动动画的方法中:
if (pendingIntroAnimation) {
pendingIntroAnimation = false;
startIntroAnimation();
}
Run Code Online (Sandbox Code Playgroud)
在链接中,作者正在为工具栏图标设置动画,因此他将其放入此方法中:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
inboxMenuItem = menu.findItem(R.id.action_inbox);
inboxMenuItem.setActionView(R.layout.menu_item_view);
if (pendingIntroAnimation) {
pendingIntroAnimation = false;
startIntroAnimation();
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
第 3步:现在编写 startIntroAnimation() 的逻辑:
private static final int ANIM_DURATION_TOOLBAR = 300;
private void startIntroAnimation() {
btnCreate.setTranslationY(2 * getResources().getDimensionPixelOffset(R.dimen.btn_fab_size));
int actionbarSize = Utils.dpToPx(56);
toolbar.setTranslationY(-actionbarSize);
ivLogo.setTranslationY(-actionbarSize);
inboxMenuItem.getActionView().setTranslationY(-actionbarSize);
toolbar.animate()
.translationY(0)
.setDuration(ANIM_DURATION_TOOLBAR)
.setStartDelay(300);
ivLogo.animate()
.translationY(0)
.setDuration(ANIM_DURATION_TOOLBAR)
.setStartDelay(400);
inboxMenuItem.getActionView().animate()
.translationY(0)
.setDuration(ANIM_DURATION_TOOLBAR)
.setStartDelay(500)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
startContentAnimation();
}
})
.start();
}
Run Code Online (Sandbox Code Playgroud)
我的首选替代方案:
我宁愿动画整个 recyclerview 而不是 recyclerview 中的项目。
第 1 步和第 2 步保持不变。
在第 3 步中,一旦您的 API 调用返回您的数据,我就会开始动画。
private void startIntroAnimation() {
recyclerview.setTranslationY(latestPostRecyclerview.getHeight());
recyclerview.setAlpha(0f);
recyclerview.animate()
.translationY(0)
.setDuration(400)
.alpha(1f)
.setInterpolator(new AccelerateDecelerateInterpolator())
.start();
}
Run Code Online (Sandbox Code Playgroud)
这将使您的整个 recyclerview 动画化,使其从屏幕底部飞入。
将此方法创建到您的recyclerview适配器中
private void setZoomInAnimation(View view) {
Animation zoomIn = AnimationUtils.loadAnimation(context, R.anim.zoomin);// animation file
view.startAnimation(zoomIn);
}
Run Code Online (Sandbox Code Playgroud)
最后在onBindViewHolder添加这行代码
setZoomInAnimation(holder.itemView);
归档时间: |
|
查看次数: |
221090 次 |
最近记录: |