android listview左右滑动动画效果,Android Animation卡通片实战(一): 从布局动画引入ListView滑动时,每一Item项的显示动画...

Android Animation动画实战(一): 从布局动画引入ListView滑动时,每一Item项的显示动画

前言:

之前,我已经写了两篇博文,给大家介绍了Android的基础动画是如何实现的,如果还不清楚的,可以点击查看:Android Animation动画详解(一): 补间动画 及 Android

Animation动画详解(二): 组合动画特效 。 已经熟悉了基础动画的实现后,便可以试着去实现常见APP中出现过的那些精美的动画。今天我主要给大家引入一个APP的ListView的动画效果: 当展示ListView时,Listview的每一个列表项都按照规定的动画显示出来。

说起来比较抽象,先给大家看一个动画效果,这是APP窝牛装修的ListView显示动画:

102758410.gif

有木有觉得很酷炫?有木有啊!?

一、Layout Animation

所谓的布局动画,其实就是为ViewGroup添加显示动画效果,主要用过LayoutAnimationController来控制实现。LayoutAnimationController用于为一个Layout里面的控件,或者是一个ViewGroup里面的控件设置动画效果,可以在XML文件中设置,亦可以在Java代码中设置。

1.1 在XML文件中设置布局动画

首先,我们在res/anim文件夹下建立一个list_anim_layout.xml文件,该文件就是布局动画控制器。

android:delay="30%"

android:animationOrder="random"

android:animation="@anim/slide_right" />

android:delay  子类动画时间间隔 (延迟)   70% 也可以是一个浮点数 如“1.2”等。

android:animationOrder="random"   子类的显示方式 random表示随机。

android:animationOrder 的取值有

normal0

默认

reverse1 倒序

random2

随机

android:animation="@anim/slide_right" 表示列表项显示时的具体动画是什么!

下面,我们定义每一个列表项显示时的动画效果吧,及slide_right.xml:

android:interpolator="@android:anim/accelerate_interpolator">

android:duration="3000"

android:fromXDelta="100%p"

android:toXDelta="0%p" />

显示的效果为ListView第一次出现的时候为 item随机出现 每个Item都是从右边的区域向左滑动到显示的地方。

接下来,你只需要把这个布局动画,指定到ViewGroup上就好了:

android:id="@+id/listView"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layoutAnimation="@anim/list_anim_layout"

>

就这么简单就完成了,快来看下效果吧:

102758411.gif

1.2 在Java代码中实现布局动画

在Java代码中实现布局动画并无难度,只要熟悉几个API的使用即可。 关于动画的定义和上文一致,只是,你不需要再在把控制动画应用到listview中了,即android:layoutAnimation="@anim/list_anim_layout"这行代码可以删除。

接下来,需要在Java代码中进行配置:

private void startLayoutAnim() {

//通过加载XML动画设置文件来创建一个Animation对象;

Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_right);

//得到一个LayoutAnimationController对象;

LayoutAnimationController lac = new LayoutAnimationController(animation);

//设置控件显示的顺序;

lac.setOrder(LayoutAnimationController.ORDER_REVERSE);

//设置控件显示间隔时间;

lac.setDelay(1);

//为ListView设置LayoutAnimationController属性;

listView.setLayoutAnimation(lac);

}

观察下,效果和之前使用xml文件肯定是一致的了。

介绍到这里,可能有人会有疑问了,博文一开始介绍的“窝牛装修”的那种效果,是每一个列表项显示的时候才会显示动画。我们这个确实所有的列表项的动画一起都显示了,只是显示顺序不同而已。 通过我们这种方法,怎么可能会达到那种效果呢?

确实,通过布局动画,没办法控制每一个Item在加载时才显示动画。那该如何是好呢?

兄弟们,换个思路吧,如果布局动画完成不了,何必不直接用简单的补间动画,再结合每个列表项的显示控制,来实现窝牛装修列表显示的效果呢?

那有人会问了,怎么知道每一个列表项何时才加载么?

你难道忘了BaseAdapter的getView()方法了么?

没错,每当一个列表项显示时,都会主动调用BaseAdaper的getView()方法。

二、仿窝牛装修List列表的动画效果

首先,我们定义一个动画资源,该动画即是列表项显示时的动画:woniu_list_item.xml

android:interpolator="@android:anim/accelerate_interpolator"

>

android:duration="500"

android:fromXDelta="0"

android:fromYDelta="100"

android:toXDelta="0"

android:toYDelta="0" />

该平移动画表示,从下往上,垂直平移100px,时间为500毫秒。

接下来,我们需要在BaseAdapter的getView()方法里,去使用该动画:

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.view.animation.Animation;

import android.view.animation.AnimationUtils;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.TextView;

import java.util.List;

public class WoniuListAdapter extends BaseAdapter {

private Context mContext;

private LayoutInflater mInflater;

private List mDatas;

private Animation animation;

public WoniuListAdapter(Context context, List datas) {

mContext = context;

mInflater = LayoutInflater.from(mContext);

mDatas = datas;

animation = AnimationUtils.loadAnimation(mContext, R.anim.woniu_list_item);

}

@Override

public int getCount() {

return (mDatas != null ? mDatas.size() : 0);

}

@Override

public Object getItem(int position) {

return (mDatas != null ? mDatas.get(position) : null);

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(final int position, View convertView, ViewGroup parent) {

ViewHolder holder = null;

int type = getItemViewType(position);

if (convertView == null) {

// 下拉项布局

convertView = mInflater.inflate(R.layout.list_item_woniu, null);

holder = new ViewHolder();

holder.tem_img = (ImageView) convertView.findViewById(R.id.tem_img);

holder.text_name = (TextView) convertView.findViewById(R.id.text_name);

holder.text_name = (TextView) convertView.findViewById(R.id.text_name);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

convertView.startAnimation(animation);

final WoniuSimple materialSimple = mDatas.get(position);

if (materialSimple != null) {

// holder.tem_img.setImageResource(R.mipmap.assist_default_img);

// holder.text_name.setText(materialSimple.name);

// holder.text_mobile.setText(materialSimple.mobile);

}

return convertView;

}

class ViewHolder {

ImageView tem_img;

TextView text_name;

TextView text_mobile;

}

}

我们来简要分析应用动画的地方: 1、我们Adapter的构造方法里加载了之前定义的动画,活的Animation对象。 2、 我们在getView方法里,为convertView设置并启动Animation,即convertView.startAnimation(animation)。

够简单吧,只是这么两行代码,就可以实现在加载每一个View Item时启动动画效果。

可是,我们发现,这并不是非常完美的实现,为啥这么说呢?

因为你此刻往上滑动列表,会发现,已经加载过的Item的动画还会再次启动执行一次。这个体验太糟糕了。为啥会出现这种情况啊?

因为getVIew方法的调用时机会对动画产生影响。Adapter中的getView方法,会在每一个item处于可见状态时调用,所以无论你上滑还是下滑,都会重复调用getView方法(这也是ListView为啥在使用时要进行优化的地方)。

所以,为了解决刚刚发生的问题,我们可以设置标识,进行判断,已经加载过的view的动画不再进行启动加载。

完整的代码如下:

package com.lnyp.layoutanimation;

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.view.animation.Animation;

import android.view.animation.AnimationUtils;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.TextView;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

public class WoniuListAdapter extends BaseAdapter {

private Context mContext;

private LayoutInflater mInflater;

private List mDatas;

private Animation animation;

private Map isFrist;

public WoniuListAdapter(Context context, List datas) {

mContext = context;

mInflater = LayoutInflater.from(mContext);

mDatas = datas;

animation = AnimationUtils.loadAnimation(mContext, R.anim.woniu_list_item);

isFrist = new HashMap();

}

@Override

public int getCount() {

return (mDatas != null ? mDatas.size() : 0);

}

@Override

public Object getItem(int position) {

return (mDatas != null ? mDatas.get(position) : null);

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(final int position, View convertView, ViewGroup parent) {

ViewHolder holder = null;

int type = getItemViewType(position);

if (convertView == null) {

// 下拉项布局

convertView = mInflater.inflate(R.layout.list_item_woniu, null);

holder = new ViewHolder();

holder.tem_img = (ImageView) convertView.findViewById(R.id.tem_img);

holder.text_name = (TextView) convertView.findViewById(R.id.text_name);

holder.text_name = (TextView) convertView.findViewById(R.id.text_name);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

// 如果是第一次加载该view,则使用动画

if (isFrist.get(position) == null || isFrist.get(position)) {

convertView.startAnimation(animation);

isFrist.put(position, false);

}

final WoniuSimple materialSimple = mDatas.get(position);

if (materialSimple != null) {

// holder.tem_img.setImageResource(R.mipmap.assist_default_img);

// holder.text_name.setText(materialSimple.name);

// holder.text_mobile.setText(materialSimple.mobile);

}

return convertView;

}

class ViewHolder {

ImageView tem_img;

TextView text_name;

TextView text_mobile;

}

}

看到了么,加了一个isFirst进行判断,这样,就可以有效控制动画的显示了。效果如下:

102758412.gif

结束:

本文我主要介绍了两个部分,一个是Layout Animation布局动画,使用布局动画可以控制VIew Groups中的每一个数据的显示动画; 还一个就是实战,仿“窝牛装修”ListView滑动时每一个Item滑动进入可见状态的动画效果。通过这两个动画示例,我相信可以帮助大家更好的处理动画,克服“动画恐惧症”。

源码下载地址(免费):http://download.csdn.net/detail/zuiwuyuan/9051895

版权声明:本文为博主原创文章,未经博主允许不得转载。2楼aj1031689昨天 15:14我自己写的就是出现第二种的情况,会重复执行动画,没有想到用一个集合去保存执行的view,但出现每滑动一次就会像水波一个整体动一次,感觉效果也不错,后来就没改了。哈哈,学习了,有时间改回来1楼sinat_29071599昨天 15:12楼主可以看下。58同城的IOS APP,他的几个页面间的切换也是才有这种layoutAnim做的,很赞!nn还有就是 android:delay是它之下的子View间的动画开启时间差?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio中实现ListView左右滑动可以使用HorizontalListView或ViewPager来实现。下面是使用ViewPager实现的示例代码。 首先,在布局文件中添加ViewPager控件: ```xml <androidx.viewpager.widget.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 然后,在Java代码中初始化ViewPager和PagerAdapter,并将Adapter设置给ViewPager: ```java ViewPager viewPager = findViewById(R.id.view_pager); PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(pagerAdapter); ``` PagerAdapter类是自定义的一个类,继承自FragmentPagerAdapter,并实现getItem和getCount方法: ```java public class PagerAdapter extends FragmentPagerAdapter { public PagerAdapter(FragmentManager fm) { super(fm); } @NonNull @Override public Fragment getItem(int position) { // 根据position创建相应的Fragment并返回 return new MyFragment(); } @Override public int getCount() { // 返回总的页面数 return 3; } } ``` MyFragment类是自定义的一个类,继承自Fragment,并在布局文件中添加一个ListView控件: ```java public class MyFragment extends Fragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_my, container, false); ListView listView = view.findViewById(R.id.list_view); // 设置ListView的适配器和数据 return view; } } ``` 使用这种方式,在ViewPager中创建多个Fragment,每个Fragment内部都包含一个ListView,可以实现左右滑动切换不同的ListView。你可以根据自己的需要自定义Fragment和ListView布局及数据适配器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值