博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android -- 仿小米锁屏画报
阅读量:7013 次
发布时间:2019-06-28

本文共 11264 字,大约阅读时间需要 37 分钟。

1,首先看一下我们今天实现的效果,效果图如下:

2,首先说一下大体的实现思路,首先这个视图一共分为三层,最外层是一个RecyclerView,第二层是一个被虚化的ImageView,第三层是一个正常的ImageView。当用户滑动RecyclerView,监听滑动的高度而动态的改变第二层ImageView的透明度,当RecyclerView滑动高度超过某个特定的高度的时候,透明度达到最大值即第二层虚化的ImageView完全展现。当RecyclerView滑动到起始位置的时候,透明度达到最小值即第二层虚化的ImageView完全隐藏从而展示的是第一层的ImageView。,下面看一下具体的实现步骤:

  第一步:了解Renderscript

  这是它的,我们只需要了解它的使用就行了,大致分为一下几个步骤:

① 首先需要通过 Context 创建一个 Renderscript ;② 其次通过创建的 Renderscript 来创建一个自己需要的脚本( ScriptIntrinsic ),比如这里③ 需要模糊,那就是 ScriptIntrinsicBlur ;④ 然后至少创建一个 Allocation 类来创建、分配内存空间;⑤ 接着就是对图像进行一些处理,比如说模糊处理;⑥ 处理完成后,需要刚才的 Allocation 类来填充分配好的内存空间;⑦ 最后可以选择性的对一些资源进行回收。

  这里我们创建一个BlurBitmapUtil来简单的封装一下,注释很详细,就不废话了,代码如下:

  BlurBitmapUtil.java

package com.qianmo.xiaomiblue.utils;import android.content.Context;import android.graphics.Bitmap;import android.os.Build;import android.renderscript.Allocation;import android.renderscript.Element;import android.renderscript.RenderScript;import android.renderscript.ScriptIntrinsicBlur;/** * Created by wangjitao on 2017/3/6 0006. * E-Mail:543441727@qq.com * 

* 模糊图片工具类 */public class BlurBitmapUtil { /** * Renderscript 的简单的使用步骤 * 下面简单说一下使用的步骤,这也是官方文档中的说明: * 首先需要通过 Context 创建一个 Renderscript ; * 其次通过创建的 Renderscript 来创建一个自己需要的脚本( ScriptIntrinsic ),比如这里需要模糊,那就是 ScriptIntrinsicBlur ; * 然后至少创建一个 Allocation 类来创建、分配内存空间; * 接着就是对图像进行一些处理,比如说模糊处理; * 处理完成后,需要刚才的 Allocation 类来填充分配好的内存空间; * 最后可以选择性的对一些资源进行回收。 */ //图片等比缩放 private static final float BITMAP_SCALE = 0.4f; /** * 模糊图片工具类 * * @param context * @param image * @param blurRadius * @return */ public static Bitmap blurBitmap(Context context, Bitmap image, float blurRadius) { //设置渲染模糊程度,25f是最大的模糊化度 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { //计算等比缩小的长宽度 int width = Math.round(image.getWidth() * BITMAP_SCALE); int height = Math.round(image.getHeight() * BITMAP_SCALE); //将缩小后的图片作为预渲染的图片 Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false); //创建一张渲染后的输出图片 Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); //创建RenderScript内核对象 RenderScript rs = RenderScript.create(context); //创建模糊效果的RenderScript工具对象 ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); //由于RenderScript并没有使用VM分配内存,所以需要使用Allocation来创建和分配内存空间 //创建Allocation对象的时候其实内存使用的,需要使用copyto将数据填充 Allocation allocationInput = Allocation.createFromBitmap(rs, inputBitmap); Allocation allocationOutput = Allocation.createFromBitmap(rs, outputBitmap); blurScript.setRadius(blurRadius); //设置blurscript对象的输入内存 blurScript.setInput(allocationInput); //将输出数据保存到输入内存中 blurScript.forEach(allocationOutput); //将数据填充到allocation中 allocationOutput.copyTo(outputBitmap); return outputBitmap; } else { return null; } }}

  第二步:自定义BlurredView,具体实现是实现原ImageView和虚化ImageView的组合,继承自Relativelayout,注释很详细,就直接贴代码了,只要是由setBlurredLevel()方法来控制透明度的改变

  自定义的属性:

  对应的布局文件blurredview.xml

  BlurredView.java

package com.qianmo.xiaomiblue.view;import android.annotation.TargetApi;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.drawable.Drawable;import android.os.Build;import android.util.AttributeSet;import android.view.LayoutInflater;import android.widget.ImageView;import android.widget.RelativeLayout;import com.qianmo.xiaomiblue.R;import com.qianmo.xiaomiblue.utils.BitmapUtil;import com.qianmo.xiaomiblue.utils.BlurBitmapUtil;import static android.R.attr.level;/** * Created by wangjitao on 2017/3/6 0006. * E-Mail:543441727@qq.com */public class BlurredView extends RelativeLayout {    private Context mContext;    //最大透明值    private static final int ALPHA_MAX_VALUE = 255;    //最大模糊度    private static final float BLUR_RADIUS = 25f;    //原图片    private ImageView mOriginalImg;    //模糊化后    private ImageView mBlurredImg;    private Bitmap mOriginalBitmap;    private Bitmap mBlurredBitmap;    //是否禁止使用高斯模糊    private boolean isDisableBlurred;    public BlurredView(Context context) {        super(context);        initView(context);    }    public BlurredView(Context context, AttributeSet attrs) {        super(context, attrs);        initView(context);        initAttr(context, attrs);    }    public BlurredView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView(context);        initAttr(context, attrs);    }    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    public BlurredView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        initView(context);        initAttr(context, attrs);    }    /**     * 当所有子View出现后 设置相关内容     */    @Override    protected void onFinishInflate() {        super.onFinishInflate();        setImageView();    }    /**     * 初始化View     *     * @param context     */    private void initView(Context context) {        mContext = context;        LayoutInflater.from(mContext).inflate(R.layout.blurredview, this);        mOriginalImg = (ImageView) findViewById(R.id.blurredview_origin_img);        mBlurredImg = (ImageView) findViewById(R.id.blurredview_blurred_img);    }    /**     * 初始化属性     *     * @param context     * @param attrs     */    private void initAttr(Context context, AttributeSet attrs) {        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BlurredView);        Drawable drawable = typedArray.getDrawable(R.styleable.BlurredView_src);        isDisableBlurred = typedArray.getBoolean(R.styleable.BlurredView_disableBlurred, false);        typedArray.recycle();        //虚化照片        if (null != drawable) {            mOriginalBitmap = BitmapUtil.drawableToBitmap(drawable);            mBlurredBitmap = BlurBitmapUtil.blurBitmap(context, mOriginalBitmap, BLUR_RADIUS);        }        //是否可见        if (!isDisableBlurred) {            mBlurredImg.setVisibility(VISIBLE);        }    }    /**     * 以代码的方式添加待模糊的图片     *     * @param blurredBitmap 待模糊的图片     */    public void setBlurredImg(Bitmap blurredBitmap) {        if (null != blurredBitmap) {            mOriginalBitmap = blurredBitmap;            mBlurredBitmap = BlurBitmapUtil.blurBitmap(mContext, blurredBitmap, BLUR_RADIUS);            setImageView();        }    }    /**     * 以代码的方式添加待模糊的图片     *     * @param blurDrawable 待模糊的图片     */    public void setBlurredImg(Drawable blurDrawable) {        if (null != blurDrawable) {            mOriginalBitmap = BitmapUtil.drawableToBitmap(blurDrawable);            mBlurredBitmap = BlurBitmapUtil.blurBitmap(mContext, mOriginalBitmap, BLUR_RADIUS);            setImageView();        }    }    /**     * 填充ImageView     */    private void setImageView() {        mBlurredImg.setImageBitmap(mBlurredBitmap);        mOriginalImg.setImageBitmap(mOriginalBitmap);    }    /**     * 设置模糊程度     *     * @param level 模糊程度, 数值在 0~100 之间.     */    @SuppressWarnings("deprecation")    public void setBlurredLevel(int level) {        //超过模糊级别范围 直接抛异常        if (level < 0 || level > 100) {            throw new IllegalStateException("No validate level, the value must be 0~100");        }        //禁用模糊直接返回        if (isDisableBlurred) {            return;        }        //设置透明度        mOriginalImg.setAlpha((int) (ALPHA_MAX_VALUE - level * 2.55));    }    /**     * 显示模糊图片     */    public void showBlurredView() {        mBlurredImg.setVisibility(VISIBLE);    }    /**     * 选择是否启动/禁止模糊效果     *     * @param isDisableBlurred 是否禁用模糊效果     */    @SuppressWarnings("deprecation")    public void setBlurredable(boolean isDisableBlurred) {        if (isDisableBlurred) {            mOriginalImg.setAlpha(ALPHA_MAX_VALUE);            mBlurredImg.setVisibility(INVISIBLE);        } else {            mBlurredImg.setVisibility(VISIBLE);        }    }    /**     * 禁用模糊效果     */    @SuppressWarnings("deprecation")    public void disableBlurredView() {        isDisableBlurred = true;        mOriginalImg.setAlpha(ALPHA_MAX_VALUE);        mBlurredImg.setVisibility(INVISIBLE);    }    /**     * 启用模糊效果     */    public void enableBlurredView() {        isDisableBlurred = false;        mBlurredImg.setVisibility(VISIBLE);    }}

  第三步:设置RecyclerView,并监听滑动,改变虚化图片的透明度

  MyAdapter

package com.qianmo.xiaomiblue.adapter;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.qianmo.xiaomiblue.R;/** * Created by Administrator on 2017/3/6 0006. * E-Mail:543441727@qq.com */public class MyAdapter extends RecyclerView.Adapter
{ private Context context; private static final int ITEM_COUNT = 10; private static final int TYPE_HEAD = 0; private static final int TYPE_ITEM = 1; public MyAdapter(Context context) { this.context = context; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == TYPE_HEAD) { return new HeadViewHolder(LayoutInflater.from(context).inflate(R.layout.recyclerview_head, parent, false)); } return new ItemViewHolder(LayoutInflater.from(context).inflate(R.layout.recyclerview_item, parent, false)); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { } @Override public int getItemViewType(int position) { if (position == 0) { return TYPE_HEAD; } else { return TYPE_ITEM; } } @Override public int getItemCount() { return ITEM_COUNT; } public class ItemViewHolder extends RecyclerView.ViewHolder { public ItemViewHolder(View itemView) { super(itemView); } } public class HeadViewHolder extends RecyclerView.ViewHolder { public HeadViewHolder(View itemView) { super(itemView); } }}

  在MainActivity中设置

recyclerView.setLayoutManager(new LinearLayoutManager(this));        recyclerView.setAdapter(new MyAdapter(this));        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                super.onScrollStateChanged(recyclerView, newState);            }            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                mScrollerY += dy;                //根据滚动距离控制模糊程度 滚动距离是模糊程度的十倍                if (Math.abs(mScrollerY) > 1000) {                    mAlpha = 100;                } else {                    mAlpha = Math.abs(mScrollerY) / 10;                }                //设置透明度等级                blurredView.setBlurredLevel(mAlpha);            }        });

  ok,这样我们的功能就实现了  ,很简单有没有,主要是Rederscript的掌握

  github项目

 

转载于:https://www.cnblogs.com/wjtaigwh/p/6510693.html

你可能感兴趣的文章