您的位置:首页 > 移动开发

Android 高斯算法在"在路上"APP 的实现

2015-07-23 12:54 603 查看
            转载请标明出处:http://blog.csdn.net/yianemail/article/details/47019383

一:我们可以看到APP"在路上"上面的 高斯的模糊的处理的效果,在下拉的时候,图像就会变的清晰并且变大 

       松开的时候自动恢复模糊效果 。

                    

                             
  

                    


             效果分析。

            我开始在想直接用高斯模糊处理图片,在图片不断的下拉的过程中也对图片的进行高斯处理达到实时对图片进行高斯模糊处                 理,达到 下拉到最下面的 图片变的clear,在拉动的过程中,图片的模糊度也随之变化。

            但是,高斯模糊处理图片是比较消耗时间的。so 上面这样处理将会是很卡的。然而在“在路上”的这个APP却一点也不存在卡的            现象。

       于是我想的实现思路是:

           1 ,布局有两张重叠的imageView(都不指定src)。(这个布局作为主布局的listview 的头部布局)
           2, 代码实现对图片的高斯处理。并且对布局两个imageView 做setImageBitmap。其中模糊图片覆盖清晰图片之上。 
           3, 对模糊图片做setAlpha并且做放大处理。

二:主代码处理:

package com.roger.listimgdemo;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.roger.listimgdemo.R;

/**
* listview头图片下拉放大, 使用时务必调用方法setImageId或setImageBitmap设置图片 否则报错 Created by Roger
* on 14-4-30.
*/
public class ImgListView extends ListView {

float mLastY;
private static final int BACK_SCALE = 0;
private boolean isHaveHead = false;// 头部是否有图片
private float scaleY = 0;
private boolean isBacking = false;// 是否处在回弹状态
private int displayWidth;
private Context mContext;
private Bitmap bmp;
private View headerView;
private ImageView imageView;
/** 用于记录拖拉图片移动的坐标位置 */
private Matrix matrix = new Matrix();
/** 用于记录图片要进行拖拉时候的坐标位置 */
private Matrix currentMatrix = new Matrix();
private Matrix defaultMatrix = new Matrix();
private float imgHeight, imgWidth;
/** 记录是拖拉照片模式还是放大缩小照片模式 0:拖拉模式,1:放大 */
private int mode = 0;// 初始状态
/** 拖拉照片模式 */
private final int MODE_DRAG = 1;
/** 用于记录开始时候的坐标位置 */
private PointF startPoint = new PointF();

private int mImageId;
private AttributeSet attrs;
private ImageView mohu;
private float alpha;

public ImgListView(Context context) {
super(context);
this.mContext = context;
initView();
}

public ImgListView(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
this.attrs = attrs;
initView();
}

public ImgListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mContext = context;
this.attrs = attrs;
initView();
}

public void setAdapter(ListAdapter adapter) {
super.setAdapter(adapter);
}

public void addHeaderView(View v) {
super.addHeaderView(v);
}

public void setImageId(int id) {
this.mImageId = id;
bmp = BitmapFactory.decodeResource(getResources(), mImageId);
if (isHaveHead)
this.removeHeaderView(headerView);
initHead();
}

public void setImageBitmap(Bitmap bit) {
this.bmp = bit;
if (isHaveHead)
this.removeHeaderView(headerView);
initHead();
}

/**
* 初始化图片
*/
private void initView() {
/* 取得屏幕分辨率大小 */
DisplayMetrics dm = new DisplayMetrics();
WindowManager mWm = (WindowManager) mContext
.getSystemService(Context.WINDOW_SERVICE);
mWm.getDefaultDisplay().getMetrics(dm);
displayWidth = dm.widthPixels;

TypedArray a = mContext.obtainStyledAttributes(attrs,
R.styleable.ImgListView);
mImageId = a.getResourceId(R.styleable.ImgListView_headimage, 0);
a.recycle();
if (null == bmp && mImageId != 0) {
bmp = BitmapFactory.decodeResource(getResources(), mImageId);
initHead();
}
}

private void initHead() {
/**
* 得到头部布局
*/
LayoutInflater inflater = LayoutInflater.from(mContext);
headerView = inflater.inflate(R.layout.top_img, null);
/**
* 找到图片控件
*/
imageView = (ImageView) headerView.findViewById(R.id.qingxi);
mohu = (ImageView) headerView.findViewById(R.id.mohu);
/**
* 把图片做模糊处理
*/
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.c);
Bitmap bit = BlurBitmap.BoxBlurFilter(bitmap);
/**
* 设置图片
*/
imageView.setImageBitmap(bitmap);
mohu.setImageBitmap(bit);

float scale = (float) displayWidth / (float) bmp.getWidth();// 1080/1800
matrix.postScale(scale, scale, 0, 0);
mohu.setImageMatrix(matrix);
defaultMatrix.set(matrix);

/**
* 这边是要设置的子View 的宽和高
*/
imgHeight = scale * bmp.getHeight();
imgWidth = scale * bmp.getWidth();
/**
* RelativeLayout.LayoutParams 指定了子view的高和宽 这边要注意,因为是有两个子View的 设置两次
*/
RelativeLayout.LayoutParams relativeLayouts = new RelativeLayout.LayoutParams(
(int) imgWidth, (int) imgHeight);
imageView.setLayoutParams(relativeLayouts);

RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
(int) imgWidth, (int) imgHeight);
mohu.setLayoutParams(relativeLayout);

this.addHeaderView(headerView);
isHaveHead = true;
}

/**
* 向下滑动让图片变大
*
* @param event
* @return
*/
public boolean onTouchEvent(MotionEvent event) {
if (!isHaveHead) {// 无头部图片
return super.onTouchEvent(event);
}
switch (event.getAction() & MotionEvent.ACTION_MASK) {
// 手指压下屏幕
case MotionEvent.ACTION_DOWN:
if (isBacking) {
return super.onTouchEvent(event);
}

int[] location = new int[2];
mohu.getLocationInWindow(location);
if (location[1] >= 0) {
mode = MODE_DRAG;
// 记录ImageView当前的移动位置
mLastY = event.getY();
currentMatrix.set(imageView.getImageMatrix());
startPoint.set(event.getX(), event.getY());
}
break;
// 手指在屏幕上移动,改事件会被不断触发
case MotionEvent.ACTION_MOVE:
/**
* <=300: 指定了 只有在图片区域才允许滑动
*/
if (event.getY() <= 300) {
float dy = event.getY() - startPoint.y;
if (dy > 0) {

float y = event.getY();
float alphaDelt = (mLastY - y) / 1000;
alpha = mohu.getAlpha() + alphaDelt;
if (alpha > 1.0) {
alpha = 1.0f;
} else if (alpha < 0.0) {
alpha = 0.0f;
}

mohu.setAlpha(alpha);

if (mode == MODE_DRAG) {
float dx = event.getX() - startPoint.x; // 得到x轴的移动距离
if (dy / 2 + imgHeight <= 1.5 * imgHeight) {
matrix.set(currentMatrix);
float scale = (dy / 2 + imgHeight) / (imgHeight);// 得到缩放倍数
if (scale > 1.2) {
scale = (float) 1.2;
scaleY = dy;
RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
(int) (scale * imgWidth),
(int) (scale * imgHeight));
mohu.setLayoutParams(relativeLayout);
matrix.postScale(scale, scale, imgWidth / 2, 0);
mohu.setImageMatrix(matrix);
}
if (scale <= 1.2) {

scaleY = dy;

RelativeLayout.LayoutParams relativeLayouta = new RelativeLayout.LayoutParams(
(int) (scale * imgWidth),
(int) (scale * imgHeight));

imageView.setLayoutParams(relativeLayouta);
matrix.postScale(scale, scale, imgWidth / 2, 0);
/**
* 放大缩小
*/
imageView.setImageMatrix(matrix);

RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
(int) (scale * imgWidth),
(int) (scale * imgHeight));

mohu.setLayoutParams(relativeLayout);
matrix.postScale(scale, scale, imgWidth / 2, 0);
/**
* 放大缩小
*/
mohu.setImageMatrix(matrix);

}
}
}
}
}
break;
// 手指离开屏幕
case MotionEvent.ACTION_UP:
// 当触点离开屏幕,图片还原

mHandler.sendEmptyMessage(BACK_SCALE);
case MotionEvent.ACTION_POINTER_UP:
mode = 0;
break;
}

return super.onTouchEvent(event);
}

private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case BACK_SCALE:
float scale = (scaleY / 2 + imgHeight) / (imgHeight);// 得到缩放倍数
if (scale > 1.2) {
scale = (float) 1.2;
}
if (scaleY > 0) {

// mohu.setAlpha(alpha);
mohu.setAlpha(1.0f);
isBacking = true;

matrix.set(currentMatrix);

RelativeLayout.LayoutParams relativeLayouta = new RelativeLayout.LayoutParams(
(int) (scale * imgWidth), (int) (scale * imgHeight));
imageView.setLayoutParams(relativeLayouta);
matrix.postScale(scale, scale, imgWidth / 2, 0);
imageView.setImageMatrix(matrix);

RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
(int) (scale * imgWidth), (int) (scale * imgHeight));
mohu.setLayoutParams(relativeLayout);
matrix.postScale(scale, scale, imgWidth / 2, 0);
mohu.setImageMatrix(matrix);
scaleY = (float) (scaleY / 2 - 1);
mHandler.sendEmptyMessageDelayed(BACK_SCALE, 20);
} else {
scaleY = 0;

RelativeLayout.LayoutParams relativeLayouta = new RelativeLayout.LayoutParams(
(int) (scale * imgWidth), (int) (scale * imgHeight));
imageView.setLayoutParams(relativeLayouta);
matrix.set(defaultMatrix);
imageView.setImageMatrix(matrix);

RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
(int) imgWidth, (int) imgHeight);
mohu.setLayoutParams(relativeLayout);
matrix.set(defaultMatrix);
mohu.setImageMatrix(matrix);
isBacking = false;
}
break;
default:
break;
}
super.handleMessage(msg);
}
};
}


   三:效果实现

             开始逐渐下拉:清晰且变大

                  

    

                   


             最终变大 清晰。

                   


    资源下载:  项目下载

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息