下拉刷新个人模糊界面demo

下拉刷新个人模糊界面


最近学习做项目,遇到各种有趣实用的框架demo,今天从中跟大家分享下个人界面实现下拉刷新,图片模糊显示的小界面,具体的代码就不会进行详细的翻译了,主要本人数学太渣,对于一些算法简直就是折磨,虽然一直奋斗着。。。。。。
好啦,开始咱们的代码!

首先实现圆形头像

圆形头像显示大家想必非常熟悉了,实现的方法很多种,小弟今日就献丑奉上我的代码,例如:

public class CircleImageView extends ImageView {

    private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;

    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
    private static final int COLORDRAWABLE_DIMENSION = 2;

    private static final int DEFAULT_BORDER_WIDTH = 0;
    private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
    private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
    private static final boolean DEFAULT_BORDER_OVERLAY = false;

    private final RectF mDrawableRect = new RectF();
    private final RectF mBorderRect = new RectF();

    private final Matrix mShaderMatrix = new Matrix();
    private final Paint mBitmapPaint = new Paint();
    private final Paint mBorderPaint = new Paint();
    private final Paint mFillPaint = new Paint();

    private int mBorderColor = DEFAULT_BORDER_COLOR;
    private int mBorderWidth = DEFAULT_BORDER_WIDTH;
    private int mFillColor = DEFAULT_FILL_COLOR;

    private Bitmap mBitmap;
    private BitmapShader mBitmapShader;
    private int mBitmapWidth;
    private int mBitmapHeight;

    private float mDrawableRadius;
    private float mBorderRadius;

    private ColorFilter mColorFilter;

    private boolean mReady;
    private boolean mSetupPending;
    private boolean mBorderOverlay;
    private boolean mDisableCircularTransformation;

    public CircleImageView(Context context) {
        super(context);

        init();
    }

    public CircleImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);

        mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
        mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
        mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
        mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);

        a.recycle();

        init();
    }

    private void init() {
        super.setScaleType(SCALE_TYPE);
        mReady = true;

        if (mSetupPending) {
            setup();
            mSetupPending = false;
        }
    }

    @Override
    public ScaleType getScaleType() {
        return SCALE_TYPE;
    }

    @Override
    public void setScaleType(ScaleType scaleType) {
        if (scaleType != SCALE_TYPE) {
            throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
        }
    }

    @Override
    public void setAdjustViewBounds(boolean adjustViewBounds) {
        if (adjustViewBounds) {
            throw new IllegalArgumentException("adjustViewBounds not supported.");
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDisableCircularTransformation) {
            super.onDraw(canvas);
            return;
        }

        if (mBitmap == null) {
            return;
        }

        if (mFillColor != Color.TRANSPARENT) {
            canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mFillPaint);
        }
        canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint);
        if (mBorderWidth > 0) {
            canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        setup();
    }

    @Override
    public void setPadding(int left, int top, int right, int bottom) {
        super.setPadding(left, top, right, bottom);
        setup();
    }

    @Override
    public void setPaddingRelative(int start, int top, int end, int bottom) {
        super.setPaddingRelative(start, top, end, bottom);
        setup();
    }

    public int getBorderColor() {
        return mBorderColor;
    }

    public void setBorderColor(@ColorInt int borderColor) {
        if (borderColor == mBorderColor) {
            return;
        }

        mBorderColor = borderColor;
        mBorderPaint.setColor(mBorderColor);
        invalidate();
    }

    /**
     * @deprecated Use {@link #setBorderColor(int)} instead
     */
    @Deprecated
    public void setBorderColorResource(@ColorRes int borderColorRes) {
        setBorderColor(getContext().getResources().getColor(borderColorRes));
    }

    /**
     * Return the color drawn behind the circle-shaped drawable.
     *
     * @return The color drawn behind the drawable
     *
     * @deprecated Fill color support is going to be removed in the future
     */
    @Deprecated
    public int getFillColor() {
        return mFillColor;
    }

    /**
     * Set a color to be drawn behind the circle-shaped drawable. Note that
     * this has no effect if the drawable is opaque or no drawable is set.
     *
     * @param fillColor The color to be drawn behind the drawable
     *
     * @deprecated Fill color support is going to be removed in the future
     */
    @Deprecated
    public void setFillColor(@ColorInt int fillColor) {
        if (fillColor == mFillColor) {
            return;
        }

        mFillColor = fillColor;
        mFillPaint.setColor(fillColor);
        invalidate();
    }

    /**
     * Set a color to be drawn behind the circle-shaped drawable. Note that
     * this has no effect if the drawable is opaque or no drawable is set.
     *
     * @param fillColorRes The color resource to be resolved to a color and
     *                     drawn behind the drawable
     *
     * @deprecated Fill color support is going to be removed in the future
     */
    @Deprecated
    public void setFillColorResource(@ColorRes int fillColorRes) {
        setFillColor(getContext().getResources().getColor(fillColorRes));
    }

    public int getBorderWidth() {
        return mBorderWidth;
    }

    public void setBorderWidth(int borderWidth) {
        if (borderWidth == mBorderWidth) {
            return;
        }

        mBorderWidth = borderWidth;
        setup();
    }

    public boolean isBorderOverlay() {
        return mBorderOverlay;
    }

    public void setBorderOverlay(boolean borderOverlay) {
        if (borderOverlay == mBorderOverlay) {
            return;
        }

        mBorderOverlay = borderOverlay;
        setup();
    }

    public boolean isDisableCircularTransformation() {
        return mDisableCircularTransformation;
    }

    public void setDisableCircularTransformation(boolean disableCircularTransformation) {
        if (mDisableCircularTransformation == disableCircularTransformation) {
            return;
        }

        mDisableCircularTransformation = disableCircularTransformation;
        initializeBitmap();
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        initializeBitmap();
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        initializeBitmap();
    }

    @Override
    public void setImageResource(@DrawableRes int resId) {
        super.setImageResource(resId);
        initializeBitmap();
    }

    @Override
    public void setImageURI(Uri uri) {
        super.setImageURI(uri);
        initializeBitmap();
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        if (cf == mColorFilter) {
            return;
        }

        mColorFilter = cf;
        applyColorFilter();
        invalidate();
    }

    @Override
    public ColorFilter getColorFilter() {
        return mColorFilter;
    }

    private void applyColorFilter() {
        if (mBitmapPaint != null) {
            mBitmapPaint.setColorFilter(mColorFilter);
        }
    }

    private Bitmap getBitmapFromDrawable(Drawable drawable) {
        if (drawable == null) {
            return null;
        }

        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }

        try {
            Bitmap bitmap;

            if (drawable instanceof ColorDrawable) {
                bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
            } else {
                bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
            }

            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private void initializeBitmap() {
        if (mDisableCircularTransformation) {
            mBitmap = null;
        } else {
            mBitmap = getBitmapFromDrawable(getDrawable());
        }
        setup();
    }

    private void setup() {
        if (!mReady) {
            mSetupPending = true;
            return;
        }

        if (getWidth() == 0 && getHeight() == 0) {
            return;
        }

        if (mBitmap == null) {
            invalidate();
            return;
        }

        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

        mBitmapPaint.setAntiAlias(true);
        mBitmapPaint.setShader(mBitmapShader);

        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBorderPaint.setAntiAlias(true);
        mBorderPaint.setColor(mBorderColor);
        mBorderPaint.setStrokeWidth(mBorderWidth);

        mFillPaint.setStyle(Paint.Style.FILL);
        mFillPaint.setAntiAlias(true);
        mFillPaint.setColor(mFillColor);

        mBitmapHeight = mBitmap.getHeight();
        mBitmapWidth = mBitmap.getWidth();

        mBorderRect.set(calculateBounds());
        mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);

        mDrawableRect.set(mBorderRect);
        if (!mBorderOverlay && mBorderWidth > 0) {
            mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);
        }
        mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);

        applyColorFilter();
        updateShaderMatrix();
        invalidate();
    }

    private RectF calculateBounds() {
        int availableWidth  = getWidth() - getPaddingLeft() - getPaddingRight();
        int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();

        int sideLength = Math.min(availableWidth, availableHeight);

        float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;
        float top = getPaddingTop() + (availableHeight - sideLength) / 2f;

        return new RectF(left, top, left + sideLength, top + sideLength);
    }

    private void updateShaderMatrix() {
        float scale;
        float dx = 0;
        float dy = 0;

        mShaderMatrix.set(null);

        if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
            scale = mDrawableRect.height() / (float) mBitmapHeight;
            dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
        } else {
            scale = mDrawableRect.width() / (float) mBitmapWidth;
            dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
        }

        mShaderMatrix.setScale(scale, scale);
        mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);

        mBitmapShader.setLocalMatrix(mShaderMatrix);
    }

}

这个其实很容易搞到,因为有万能的某娘,具体方法大家可以参考相应的API,进行更详细的学习,自定义view一直是难点,需要多加练习啊;当中又进行了图片处理,详细请看代码。。。

然后需要自定义一个下拉刷新控件,需要继承ScrollView控件,实现OnGlobalLayoutListener接口,让计算滑动y方向偏移值 让图片向上-50个dp 自己定义,当向下移动时展示所以图片,不是下拉时不处理,松手返回,再进行高斯模糊图片。

原理比较简单下拉源码图片如下:

public class PullScrollView extends ScrollView implements ViewTreeObserver.OnGlobalLayoutListener{
    View view;

    int srcTopMargion;

    float lastY;

    float offsetY;
    public PullScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        ViewTreeObserver observer = getViewTreeObserver();

        if (null != observer)

            observer.addOnGlobalLayoutListener(this);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        view = findViewById(R.id.pull_img);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();

        float y = ev.getY();

        Log.i("onTouchEvent", "action=" + action + ",y=" + y);

        MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();

        switch (action) {

            case MotionEvent.ACTION_DOWN:

                lastY = y;

                break;

            case MotionEvent.ACTION_MOVE:

                //计算滑动y方向偏移值

                offsetY = y - lastY;

                //向下移动

                if (offsetY > 0) {

                    //滑动到看到所有图片展示,交给原来的逻辑处理

                    if (params.topMargin == 0) {

                        return super.onTouchEvent(ev);

                    }

                    //在不是下拉图片的时候,向下移动,交给原来的逻辑处理

                    if (getScrollY() != 0) {

                        return super.onTouchEvent(ev);

                    }

                    //可以下拉图片的情况,offsetY / 10的除以10的阻值,就是防止滑的太快

                    params.topMargin += offsetY / 10;

                    Log.i("onTouchEvent", "topMargin" + params.topMargin + ",lastY=" + lastY + ",y=" + y + ",offsetY" + offsetY);

                    if (params.topMargin >= 0) {

                        params.topMargin = 0;

                    }

                    view.setLayoutParams(params);

                    invalidate();

                }

                lastY = y;

                break;

            case MotionEvent.ACTION_UP:

                //不和原始margion偏移一样的时候

                if (params.topMargin != -srcTopMargion) {

                    Log.d("ACTION_UP", "moveY=" + (srcTopMargion + params.topMargin));

                    //滚动原始偏移值和现在偏移值之间的差值 eg:3~10

                    ObjectAnimator animator = ObjectAnimator.ofInt(this, "moveY", params.topMargin, -srcTopMargion);

                    animator.setDuration(200);

                    animator.setInterpolator(new AccelerateDecelerateInterpolator());

                    animator.start();

                }

                break;

        }

        return super.onTouchEvent(ev);
    }

    /**

     * 设置移动中的Y值

     *

     * @param value

     */

    public void setMoveY(int value) {

        MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();

        params.topMargin = value;

        Log.d("computeScroll", "topMargin=" + params.topMargin);

        view.setLayoutParams(params);

        invalidate();

    }


    @Override
    public void onGlobalLayout() {
        MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
        Log.i("cjj", "params" + params);
        srcTopMargion = -params.topMargin;

        Log.i("cjj", "srcTopMargion" + srcTopMargion);

        getViewTreeObserver()

                .removeGlobalOnLayoutListener(this);
    }
}

ok,然后就是布局啦:

<?xml version="1.0" encoding="utf-8"?>
<cn.tedu.pc.myexedemo.PullScrollView xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/scroll_view"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:background="@color/colorAccent"

    android:scrollbars="none">



   <LinearLayout

       android:layout_width="match_parent"

       android:layout_height="match_parent"

       android:orientation="vertical">

      <RelativeLayout

          android:layout_width="match_parent"

          android:layout_height="match_parent"

          android:background="#ffffffff">

         <ImageView

             android:id="@+id/pull_img"

             android:layout_width="match_parent"

             android:layout_height="220dp"

             android:layout_marginTop="-50dp"

             android:scaleType="fitXY"

             android:src="@mipmap/hd_3200x2000_001" />



         <cn.tedu.pc.myexedemo.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"

             android:id="@+id/profile_image"

             android:layout_width="100dp"

             android:layout_height="100dp"

             android:layout_alignParentTop="true"

             android:layout_centerHorizontal="true"

             android:layout_centerInParent="true"

             android:layout_marginTop="98dp"

             android:src="@mipmap/a003"

             app:civ_border_width="1dp"

             app:civ_border_color="#ffffffff"

             />

         <ImageButton

             android:id="@+id/btn_back"

             android:layout_width="wrap_content"

             android:layout_height="wrap_content"

             android:layout_alignParentLeft="true"

             android:layout_alignParentStart="true"

             android:layout_alignParentTop="true"

             android:layout_marginLeft="16.7dp"

             android:layout_marginStart="16.7dp"

             android:layout_marginTop="25dp"

             android:background="@color/colorAccent" />

      </RelativeLayout>


      <LinearLayout

          android:layout_width="match_parent"

          android:layout_height="match_parent"

          android:background="#ffffffff"

          android:orientation="vertical">

         <TextView

             android:layout_width="wrap_content"

             android:layout_height="match_parent"

             android:layout_alignBottom="@+id/profile_image"

             android:layout_alignParentLeft="true"

             android:layout_alignParentStart="true"

             android:layout_gravity="center"

             android:layout_marginTop="13.3dp"

             android:textColor="#ff333333"

             android:text="昵称:小妞" />

         <TextView

             android:layout_width="wrap_content"

             android:layout_height="wrap_content"

             android:layout_gravity="center"

             android:textColor="#ff333333"

             android:text="ID:58585668" />

         <LinearLayout

             android:layout_width="match_parent"

             android:layout_height="wrap_content"

             android:layout_marginBottom="10dp"

             android:layout_marginTop="15dp"

             android:textColor="#ff333333"

             android:orientation="horizontal">

            <LinearLayout

                android:layout_width="0dp"

                android:layout_height="match_parent"

                android:layout_weight="1"

                android:gravity="center"

                android:orientation="vertical">

            </LinearLayout>



            <LinearLayout

                android:layout_width="0dp"

                android:layout_height="match_parent"

                android:layout_weight="1"

                android:gravity="center"

                android:orientation="vertical">

            </LinearLayout>

            <LinearLayout

                android:id="@+id/id_tab_log"

                android:layout_width="0dp"

                android:layout_height="match_parent"

                android:layout_weight="1"

                android:gravity="center"

                android:orientation="vertical">


            </LinearLayout>


         </LinearLayout>

      </LinearLayout>


      <LinearLayout

          android:layout_width="match_parent"

          android:layout_height="match_parent"

          android:layout_marginTop="6.7dp"

          android:background="#ffffffff"

          android:orientation="vertical">

         <RelativeLayout

             android:id="@+id/tRUpdates"

             android:layout_width="match_parent"

             android:layout_height="52dp"

             android:clickable="true"

             android:focusable="true">

            <TextView

                android:layout_width="wrap_content"

                android:layout_height="match_parent"

                android:drawablePadding="10.0dip"

                android:gravity="center_vertical"

                android:includeFontPadding="false"

                android:paddingLeft="16.7dip"

                android:text="检查更新"

                android:textColor="#ff333333"

                android:textSize="13sp" />

            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="1px"

                android:layout_alignParentBottom="true"

                android:layout_centerHorizontal="true"

                android:layout_marginLeft="13dp"

                android:layout_marginRight="13dp"

                android:background="@color/colorAccent">

            </RelativeLayout>

         </RelativeLayout>


         <RelativeLayout

             android:id="@+id/tRFeedback"

             android:layout_width="match_parent"

             android:layout_height="52dp"

             android:clickable="true"

             android:focusable="true">

            <TextView

                android:layout_width="wrap_content"

                android:layout_height="match_parent"

                android:drawablePadding="10.0dip"

                android:gravity="center_vertical"

                android:includeFontPadding="false"

                android:paddingLeft="16.7dip"

                android:text="意见反馈"

                android:textColor="#ff333333"

                android:textSize="13sp" />

            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="1px"

                android:layout_alignParentBottom="true"

                android:layout_centerHorizontal="true"

                android:layout_marginLeft="13dp"

                android:layout_marginRight="33dp"

                android:background="@color/colorAccent">

            </RelativeLayout>

         </RelativeLayout>


         <RelativeLayout

             android:id="@+id/tROperation"

             android:layout_width="match_parent"

             android:layout_height="52dp"

             android:clickable="true"

             android:focusable="true">

            <TextView

                android:layout_width="wrap_content"

                android:layout_height="match_parent"

                android:drawablePadding="10.0dip"

                android:gravity="center_vertical"

                android:includeFontPadding="false"

                android:paddingLeft="16.7dip"

                android:text="操作说明"

                android:textColor="#ff333333"

                android:textSize="13sp" />

         </RelativeLayout>

         <RelativeLayout

             android:layout_width="match_parent"

             android:layout_height="1px"

             android:layout_alignParentBottom="true"

             android:layout_centerHorizontal="true"

             android:layout_marginLeft="13dp"

             android:layout_marginRight="13dp"

             android:background="@color/colorAccent">

         </RelativeLayout>

      </LinearLayout>


      <LinearLayout

          android:layout_width="match_parent"

          android:layout_height="match_parent"

          android:layout_marginTop="0dp"

          android:background="#ffffffff"

          android:orientation="vertical">

         <RelativeLayout

             android:id="@+id/tRChange"

             android:layout_width="match_parent"

             android:layout_height="52dp"

             android:clickable="true"

             android:focusable="true">

            <TextView

                android:layout_width="wrap_content"

                android:layout_height="match_parent"

                android:drawablePadding="10.0dip"

                android:gravity="center_vertical"

                android:includeFontPadding="false"

                android:paddingLeft="16.7dip"

                android:text="修改密码"

                android:textColor="#ff333333"

                android:textSize="13sp" />


            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="1px"

                android:layout_alignParentBottom="true"

                android:layout_centerHorizontal="true"

                android:layout_marginLeft="13dp"

                android:layout_marginRight="13dp"

                android:background="@color/colorAccent">

            </RelativeLayout>

         </RelativeLayout>
         <RelativeLayout
             android:layout_width="match_parent"
             android:layout_height="6.7dp"
             android:background="@color/colorAccent"></RelativeLayout>
         <RelativeLayout

             android:id="@+id/login"

             android:layout_width="match_parent"

             android:layout_height="52dp"

             android:clickable="true"

             android:focusable="true">

            <Button

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:drawablePadding="10.0dip"

                android:gravity="center"

                android:includeFontPadding="false"

                android:paddingLeft="16.7dip"

                android:text="退出登录"

                android:textColor="#ff333333"

                android:textSize="13sp"

                android:background="@null"/>

         </RelativeLayout>

      </LinearLayout>

   </LinearLayout>

</cn.tedu.pc.myexedemo.PullScrollView>

图片模糊处理:

public class BitmapBlurUtil {
    private static ExecutorService executor;



    private static int POOL_SIZE = 2;// 单个CPU线程池大小



    private static ExecutorService getExecutor() {



        if (executor == null) {



            int cpuNums = Runtime.getRuntime().availableProcessors();



            executor = Executors.newFixedThreadPool(cpuNums * POOL_SIZE);



        }



        return executor;



    }



    public static void addTask(Bitmap bitmap, Handler handler) {



        getExecutor().submit(new BitmapVagueTask(bitmap, handler));



    }



    /**

     * 水平方向模糊度

     */



    private static float hRadius = 3;



    /**

     * 竖直方向模糊度

     */



    private static float vRadius = 3;



    /**

     * 模糊迭代度

     */



    private static int iterations = 5;



    /**

     * 异步

     *

     * @author baiyuliang

     */



    private static class BitmapVagueTask implements Runnable {



        private Bitmap bitmap;



        private Handler handler;



        public BitmapVagueTask(Bitmap bitmap, Handler handler) {



            super();



            this.bitmap = bitmap;



            this.handler = handler;



        }



        @Override



        public void run() {



            boxBlurFilter(bitmap, handler);



        }



    }



    /**

     * 高斯模糊

     *

     * @param bmp

     * @return

     */



    private static void boxBlurFilter(Bitmap bmp, Handler handler) {



        int width = bmp.getWidth();



        int height = bmp.getHeight();



        int[] inPixels = new int[width * height];



        int[] outPixels = new int[width * height];



        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);



        bmp.getPixels(inPixels, 0, width, 0, 0, width, height);



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



            blur(inPixels, outPixels, width, height, hRadius);



            blur(outPixels, inPixels, height, width, vRadius);



        }



        blurFractional(inPixels, outPixels, width, height, hRadius);



        blurFractional(outPixels, inPixels, height, width, vRadius);



        bitmap.setPixels(inPixels, 0, width, 0, 0, width, height);



        if (handler != null) {



            @SuppressWarnings("deprecation")


            Drawable drawable = new BitmapDrawable(bitmap);



            Message message = new Message();



            message.obj = drawable;



            handler.sendMessage(message);



        }



    }



    private static void blur(int[] in, int[] out, int width, int height, float radius) {



        int widthMinus1 = width - 1;



        int r = (int) radius;



        int tableSize = 2 * r + 1;



        int divide[] = new int[256 * tableSize];



        for (int i = 0; i < 256 * tableSize; i++)



            divide[i] = i / tableSize;



        int inIndex = 0;



        for (int y = 0; y < height; y++) {



            int outIndex = y;



            int ta = 0, tr = 0, tg = 0, tb = 0;



            for (int i = -r; i <= r; i++) {



                int rgb = in[inIndex + clamp(i, 0, width - 1)];



                ta += (rgb >> 24) & 0xff;



                tr += (rgb >> 16) & 0xff;



                tg += (rgb >> 8) & 0xff;



                tb += rgb & 0xff;



            }



            for (int x = 0; x < width; x++) {



                out[outIndex] = (divide[ta] << 24) | (divide[tr] << 16)



                        | (divide[tg] << 8) | divide[tb];



                int i1 = x + r + 1;



                if (i1 > widthMinus1)



                    i1 = widthMinus1;



                int i2 = x - r;



                if (i2 < 0)



                    i2 = 0;



                int rgb1 = in[inIndex + i1];



                int rgb2 = in[inIndex + i2];



                ta += ((rgb1 >> 24) & 0xff) - ((rgb2 >> 24) & 0xff);



                tr += ((rgb1 & 0xff0000) - (rgb2 & 0xff0000)) >> 16;



                tg += ((rgb1 & 0xff00) - (rgb2 & 0xff00)) >> 8;



                tb += (rgb1 & 0xff) - (rgb2 & 0xff);



                outIndex += height;



            }



            inIndex += width;



        }



    }



    private static void blurFractional(int[] in, int[] out, int width,



                                       int height, float radius) {



        radius -= (int) radius;



        float f = 1.0f / (1 + 2 * radius);



        int inIndex = 0;



        for (int y = 0; y < height; y++) {



            int outIndex = y;



            out[outIndex] = in[0];



            outIndex += height;



            for (int x = 1; x < width - 1; x++) {



                int i = inIndex + x;



                int rgb1 = in[i - 1];



                int rgb2 = in[i];



                int rgb3 = in[i + 1];



                int a1 = (rgb1 >> 24) & 0xff;



                int r1 = (rgb1 >> 16) & 0xff;



                int g1 = (rgb1 >> 8) & 0xff;



                int b1 = rgb1 & 0xff;



                int a2 = (rgb2 >> 24) & 0xff;



                int r2 = (rgb2 >> 16) & 0xff;



                int g2 = (rgb2 >> 8) & 0xff;



                int b2 = rgb2 & 0xff;



                int a3 = (rgb3 >> 24) & 0xff;



                int r3 = (rgb3 >> 16) & 0xff;



                int g3 = (rgb3 >> 8) & 0xff;



                int b3 = rgb3 & 0xff;



                a1 = a2 + (int) ((a1 + a3) * radius);



                r1 = r2 + (int) ((r1 + r3) * radius);



                g1 = g2 + (int) ((g1 + g3) * radius);



                b1 = b2 + (int) ((b1 + b3) * radius);



                a1 *= f;



                r1 *= f;



                g1 *= f;



                b1 *= f;



                out[outIndex] = (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;



                outIndex += height;



            }



            out[outIndex] = in[width - 1];



            inIndex += width;



        }



    }



    public static int clamp(int x, int a, int b) {



        return (x < a) ? a : (x > b) ? b : x;



    }
}

布局根据自身需要进行设计即可!

主要activity代码:

“`
public class PersonActivity extends AppCompatActivity {
private ImageView pull_img;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_person);
    pull_img = (ImageView) findViewById(R.id.pull_img);

    Resources res = getResources();

    Bitmap bmp = BitmapFactory.decodeResource(res, R.mipmap.hd_3200x2000_001);



    BitmapBlurUtil.addTask(bmp, new Handler() {

        @Override

        public void handleMessage(Message msg) {

            super.handleMessage(msg);

            Drawable drawable = (Drawable) msg.obj;

            pull_img.setImageDrawable(drawable);



        }

    });

}

}
“`这里写图片描述

至于效果吗。。。。。。哈哈 ,大家自己去体验吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值