实际上只需要一个图片的矩阵变换就能做到了
在listview滚动监听setOnScrollListener中设置图片所在的位置,用来改变图片显示的区域。
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
for (int i = 0; i < totalItemCount; i++) {
if (view.getChildAt(i)!=null) {
int[] position = new int[2];
//获取控件在屏幕中位置
view.getChildAt(i).getLocationOnScreen(position);
ViewGroup fl = (ViewGroup) view.getChildAt(i);
//获取自定义控件NewsClassifyImageView
if (fl.getChildCount()!=0) {
ViewGroup vg = (ViewGroup) fl.getChildAt(0);
if (vg.getChildCount()!=0) {
//设置位置信息
((NewsClassifyImageView) (vg.getChildAt(0))).setPicPostion(position[1]);
}
}
}
}
}
接下来是自定义控件NewsClassifyImageView extends ImageView
重写构造方法后,只需加入下面的代码即可
private int maxTop;
private float scale = 1.0f;
private Matrix mMatrix=new Matrix();
private Matrix mCurrentMatrix=new Matrix();
public void setPicPostion(int position){
mCurrentMatrix.set(mMatrix);//初始化Matrix
int left = 0,top = 0;
if (getDrawable()!=null) {
int boundsWidth= 0,boundsHeight=0;
boundsWidth = getDrawable().getBounds().width();
boundsHeight = getDrawable().getBounds().height();
//小图放大
if (boundsWidth<DensityUtil.getWindowWidth(mContext)) {
scale = DensityUtil.getWindowWidth(mContext)*1.0f/boundsWidth;
mCurrentMatrix.postScale(scale , scale ,0,0);
}
maxTop = (int) (getHeight()-boundsHeight*scale);
left = (DensityUtil.getWindowWidth(mContext)-boundsWidth)/2;// 横向显示中心位置
top = -position/5;
left = left<0?left:0;
top = top>maxTop?top:maxTop;
}
mCurrentMatrix.postTranslate(left,top);
setImageMatrix(mCurrentMatrix);
invalidate();
}
由于android屏幕尺寸太多,所以需要对图片先放大或缩小,然后进行上下滚动处理,
项目需要我这里只对小图放大,大图显示的横向中间位置,大图缩小去掉判断条件即可。
图片上下滚动距离由top控制,我这里随便取得值显示效果,top = -position/5应根据需求计算
最后显示的图片放大上移效果,在adapter中写上属性动画
if (position>currentPosition) {
AnimationSet as = new AnimationSet(true);
Animation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0.2f,
Animation.RELATIVE_TO_SELF, 0);
ta.setDuration(500);
as.addAnimation(ta);
final ValueAnimator animator = ValueAnimator.ofFloat(200,0);
animator.setTarget(news_classify_rl);
animator.setDuration(500);
if (position<4) {
news_classify_rl.setVisibility(View.INVISIBLE);
handler.postDelayed(new Runnable() {
@Override
public void run() {
news_classify_rl.setVisibility(View.VISIBLE);
animator.start();
}
}, 500);
}else{
animator.start();
}
animator.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
((View) news_classify_rl.getParent()).setTranslationY((Float) animation.getAnimatedValue());
((View) news_classify_rl.getParent()).setScaleX(1-(Float) animation.getAnimatedValue()/2000);
((View) news_classify_rl.getParent()).setScaleY(1-(Float) animation.getAnimatedValue()/2000);
}
});
currentPosition = position;
}