android listview 滚动 动画,Android使用ListView实现滚轮的动画效果实例

之前收到一个需求,需要把一个数据展示列表页面做成像滚轮那样的动画效果:中间最大然后向上下两端逐渐缩小。我想了想iOS那边自带滚轮组件,安卓得自己去实现,目前网上仿ios的滚轮组件的也有一些,但是感觉不适合我,我的要求没那么复杂,于是决定自己动手去实现一下。

动手前先分析一下应该怎么做,归根到底只是要实现缩放效果,由中间向两边变小,当一个item越接近中间就放大,越远离中间就缩小。那么可以通过先获取ListView的中点,然后获取当前可视的所有item跟ListView的中点的垂直距离计算出一个比例,然后将item的大小根据这个比例进行缩放,各个item跟ListView的中点的垂直距离不同,计算出来的比例也就不同,然后每次滚动的时候都计算比例然后进行缩放,这样应该就能实现我们想要的效果了。

因为一开始我的列表展示就是用ListView做的,有其他效果在里面,也不方便换其他组件,所以依然还是用ListView实现就好了。由于我们是每次一滚动都要进行缩放,ListView有提供一个OnScrollListener,它的onScroll方法每次一开始滚动就会调用,所以我们选择重写它。当它被调用的时候,我们就开始获取ListView中点,然后开始计算每个item的距离进行缩放.

/**

* 中点的Y坐标

*/

private float centerY = 0f;

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

//计算中点

centerY = getHeight()/2;

//判断中点的有效性

if(centerY <= 0){

return;

}

//开始对当前显示的View进行缩放

for(int i = 0; i < visibleItemCount; i++){

//获取item

View temp_view = getChildAt(i);

//计算item的中点Y坐标

float itemY = temp_view.getBottom()-(temp_view.getHeight()/2);

//计算离中点的距离

float distance = centerY;

if(itemY > centerY){

distance = itemY - centerY;

}else{

distance = centerY - itemY;

}

//根据距离进行缩放

temp_view.setScaleY(1.1f - (distance / centerY) < 0 ? 0 : 1.1f - (distance / centerY));

temp_view.setScaleX(1.1f - (distance / centerY) < 0 ? 0 : 1.1f - (distance / centerY));

//根据距离改变透明度

temp_view.setAlpha(1.1f - (distance / centerY) < 0 ? 0 : 1.1f - (distance / centerY));

}

}

后面不想加demo了,所以直接上整个ListView的代码吧

/**

* 模仿滚轮动画缩放的ListView

* Created by xu on 2017/3/3.

*/

public class XuListView extends ListView implements AbsListView.OnScrollListener {

private static final String TAG = "XuListView";

/**

* 中点的Y坐标

*/

private float centerY = 0f;

public XuListView(Context context, AttributeSet attrs) {

super(context, attrs);

//设置一个滚动监听

setOnScrollListener(this);

}

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

}

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

//计算中点

centerY = getHeight()/2;

//判断中点的有效性

if(centerY <= 0){

return;

}

//开始对当前显示的View进行缩放

for(int i = 0; i < visibleItemCount; i++){

//获取item

View temp_view = getChildAt(i);

//计算item的中点Y坐标

float itemY = temp_view.getBottom()-(temp_view.getHeight()/2);

//计算离中点的距离

float distance = centerY;

if(itemY > centerY){

distance = itemY - centerY;

}else{

distance = centerY - itemY;

}

//根据距离进行缩放

temp_view.setScaleY(1.1f - (distance / centerY) < 0 ? 0 : 1.1f - (distance / centerY));

temp_view.setScaleX(1.1f - (distance / centerY) < 0 ? 0 : 1.1f - (distance / centerY));

//根据距离改变透明度

temp_view.setAlpha(1.1f - (distance / centerY) < 0 ? 0 : 1.1f - (distance / centerY));

}

}

}

这样基本就实现了我们想要的效果了

但是现在有一个问题,就是第一个item和最后一个item无法滚动到中间从而放大突出显示。对此我暂时想了两个方法去解决:1、在头尾各种添加一些空白的item,使我们需要显示的数据都可以滚动到最中间。(我现在就是这么做的);2、使整个列表实现循环滚动。

添加空白的item的话,我是通过修改adapter去实现的。数据源是一个数组,我在数组前面和后面各加一些特殊的数据,adapter实现getview的时候,如果发现当前item的数据是特殊数据,那么item就变透明,从而实现了我们原本要显示的数据都可以被滚动最中间

你可能感兴趣的:(android,listview,滚动,动画)