Listview下拉头部View放大效果
This commit is contained in:
parent
adb7b5e09d
commit
0599b7a223
|
@ -0,0 +1,227 @@
|
||||||
|
package com.zftlive.android.view;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.graphics.drawable.NinePatchDrawable;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listview下拉放大效果 ,初始化时需调用方法setHeadView
|
||||||
|
* @author 曾繁添
|
||||||
|
* @version 1.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PullZoomListView extends ListView {
|
||||||
|
|
||||||
|
private final static int BACK_SCALE = 0;
|
||||||
|
private float scaleY = 0;
|
||||||
|
private boolean isBacking = false;// 是否处在回弹状态
|
||||||
|
/** 用于记录拖拉图片移动的坐标位置 */
|
||||||
|
private Matrix matrix = new Matrix();
|
||||||
|
/** 用于记录图片要进行拖拉时候的坐标位置 */
|
||||||
|
private Matrix currentMatrix = new Matrix();
|
||||||
|
private Matrix defaultMatrix = new Matrix();
|
||||||
|
/** 图片宽高 **/
|
||||||
|
private float imgHeight, imgWidth;
|
||||||
|
/** 记录是拖拉照片模式还是放大缩小照片模式 0:拖拉模式,1:放大 */
|
||||||
|
private int MODE_NORMAL = 0;
|
||||||
|
/** 拖拉照片模式 */
|
||||||
|
private final int MODE_DRAG = 1;
|
||||||
|
/** 用于记录开始时候的坐标位置 */
|
||||||
|
private PointF startPoint = new PointF();
|
||||||
|
|
||||||
|
private ImageView mHeadImage;
|
||||||
|
private Bitmap mHeadImageBmp;
|
||||||
|
|
||||||
|
public PullZoomListView(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PullZoomListView(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PullZoomListView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置头部View,并指定缩放目标Imageview
|
||||||
|
* @param mHeadView Listview头部view
|
||||||
|
* @param zoomImageView 需要缩放的Imageview
|
||||||
|
*/
|
||||||
|
public void setHeadView(View mHeadView,ImageView zoomImageView){
|
||||||
|
super.addHeaderView(mHeadView);
|
||||||
|
|
||||||
|
//头部背景图片
|
||||||
|
this.mHeadImage = zoomImageView;
|
||||||
|
mHeadImageBmp = drawableToBitmap(mHeadImage.getDrawable());
|
||||||
|
float scale = (float) getScreenWidth() / (float) mHeadImageBmp.getWidth();
|
||||||
|
matrix.postScale(scale, scale, 0, 0);
|
||||||
|
mHeadImage.setImageMatrix(matrix);
|
||||||
|
defaultMatrix.set(matrix);
|
||||||
|
|
||||||
|
imgHeight = scale * mHeadImageBmp.getHeight();
|
||||||
|
imgWidth = scale * mHeadImageBmp.getWidth();
|
||||||
|
|
||||||
|
RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams((int) imgWidth, (int) imgHeight);
|
||||||
|
mHeadImage.setLayoutParams(relativeLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drawable转成Bitmap
|
||||||
|
* @param drawable
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Bitmap drawableToBitmap(Drawable drawable) {
|
||||||
|
if (drawable instanceof BitmapDrawable) {
|
||||||
|
return ((BitmapDrawable) drawable).getBitmap();
|
||||||
|
} else if (drawable instanceof NinePatchDrawable) {
|
||||||
|
Bitmap bitmap = Bitmap
|
||||||
|
.createBitmap(
|
||||||
|
drawable.getIntrinsicWidth(),
|
||||||
|
drawable.getIntrinsicHeight(),
|
||||||
|
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
|
||||||
|
: Bitmap.Config.RGB_565);
|
||||||
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
|
||||||
|
drawable.getIntrinsicHeight());
|
||||||
|
drawable.draw(canvas);
|
||||||
|
return bitmap;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取屏幕宽度
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int getScreenWidth() {
|
||||||
|
DisplayMetrics displayMetrics = getContext().getResources()
|
||||||
|
.getDisplayMetrics();
|
||||||
|
return displayMetrics.widthPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 慢慢回弹初始状态
|
||||||
|
*/
|
||||||
|
private Handler mHandler = new Handler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case BACK_SCALE:
|
||||||
|
float scale = (scaleY / 2 + imgHeight) / (imgHeight);
|
||||||
|
if (scaleY > 0) {
|
||||||
|
isBacking = true;
|
||||||
|
matrix.set(currentMatrix);
|
||||||
|
RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
|
||||||
|
(int) (scale * imgWidth), (int) (scale * imgHeight));
|
||||||
|
mHeadImage.setLayoutParams(relativeLayout);
|
||||||
|
matrix.postScale(scale, scale, imgWidth / 2, 0);
|
||||||
|
mHeadImage.setImageMatrix(matrix);
|
||||||
|
scaleY = (float) (scaleY / 2 - 1);
|
||||||
|
mHandler.sendEmptyMessageDelayed(BACK_SCALE, 20);
|
||||||
|
} else {
|
||||||
|
scaleY = 0;
|
||||||
|
RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
|
||||||
|
(int) imgWidth, (int) imgHeight);
|
||||||
|
mHeadImage.setLayoutParams(relativeLayout);
|
||||||
|
matrix.set(defaultMatrix);
|
||||||
|
mHeadImage.setImageMatrix(matrix);
|
||||||
|
isBacking = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
super.handleMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向下滑动让图片变大
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
|
||||||
|
// 无Header
|
||||||
|
if (getHeaderViewsCount() == 0) {
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用switch (event.getAction())可以处理ACTION_DOWN和ACTION_UP事件;
|
||||||
|
* 使用switch (event.getAction() & MotionEvent.ACTION_MASK)就可以处理处理多点触摸的ACTION_POINTER_DOWN和ACTION_POINTER_UP事件
|
||||||
|
*/
|
||||||
|
switch (event.getAction() & MotionEvent.ACTION_MASK) {
|
||||||
|
// 手指压下屏幕
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
if (isBacking) {
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
int[] location = new int[2];
|
||||||
|
mHeadImage.getLocationInWindow(location);
|
||||||
|
if (location[1] >= 0) {
|
||||||
|
MODE_NORMAL = MODE_DRAG;
|
||||||
|
// 记录ImageView当前的移动位置
|
||||||
|
currentMatrix.set(mHeadImage.getImageMatrix());
|
||||||
|
startPoint.set(event.getX(), event.getY());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// 手指在屏幕上移动,改事件会被不断触发
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
// 拖拉图片
|
||||||
|
if (MODE_NORMAL == MODE_DRAG) {
|
||||||
|
float dy = event.getY() - startPoint.y; // 得到y轴的移动距离
|
||||||
|
// 在没有移动之前的位置上进行移动
|
||||||
|
if (dy / 2 + imgHeight <= 1.5 * imgHeight) {
|
||||||
|
matrix.set(currentMatrix);
|
||||||
|
float scale = (dy / 2 + imgHeight) / (imgHeight);// 得到缩放倍数
|
||||||
|
if (dy > 0) {
|
||||||
|
scaleY = dy;
|
||||||
|
RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
|
||||||
|
(int) (scale * imgWidth),
|
||||||
|
(int) (scale * imgHeight));
|
||||||
|
mHeadImage.setLayoutParams(relativeLayout);
|
||||||
|
matrix.postScale(scale, scale, imgWidth / 2, 0);
|
||||||
|
mHeadImage.setImageMatrix(matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// 手指离开屏幕
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
// 当触点离开屏幕,图片还原
|
||||||
|
mHandler.sendEmptyMessage(BACK_SCALE);
|
||||||
|
|
||||||
|
//一个非主要的手指抬起
|
||||||
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
|
MODE_NORMAL = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue