Android -- 仿小米锁屏画报
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
* <p>
* 模糊图片工具类
*/ 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()方法来控制透明度的改变
自定义的属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="BlurredView">
<attr name="src" format="reference"/>
<attr name="disableBlurred" format="boolean"/>
</declare-styleable>
</resources>
对应的布局文件blurredview.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView
android:id="@+id/blurredview_blurred_img"
android:scaleType="fitXY"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"/> <ImageView
android:id="@+id/blurredview_origin_img"
android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="match_parent"/> </FrameLayout>
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<RecyclerView.ViewHolder> { 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项目地址
Android -- 仿小米锁屏画报的更多相关文章
- Android端恶意锁屏勒索应用分析
一.前言 5月12日,一场全球性互联网灾难悄然而至,一款名为WannaCRY的PC端恶意勒索软件利用NSA泄漏的危险漏洞“永恒之蓝”,给100多个国家和地区10万台电脑造成了巨大的损失.到2017年为 ...
- 【Android】Android 手机忘记锁屏密码的解决办法
对于忘记Android锁屏密码的筒子们,除重新刷包或者wipe data外,还可用adb来删除密码: 方法很简单 1.手机连接电脑,不要打开数据连接,在充电模式下进行. 2.在电脑上,解压adb.zi ...
- Android 监听锁屏、解锁、开屏 操作
1.首先定义 ScreenListener package com.app.lib; import android.content.BroadcastReceiver; import android ...
- 【Android代码片段之八】监听Android屏幕是否锁屏
实现方法:1)通过BroadcastReceiver接收广播Intent.ACTION_SCREEN_ON和Intent.ACTION_SCREEN_OFF可以判断屏幕状态是否锁屏,但是只有屏幕状态发 ...
- Android 开发之锁屏弹窗
尝试利用 WindowManager 添加浮窗的方式实现 想在锁屏上面实现弹窗,第一个想法就是利用 WindowManager 设置 Window 的 Flag,通过设置 Flag 的显示优先级来让窗 ...
- Android判断屏幕锁屏的方法总结
由于做一个项目,需要判断屏幕是否锁屏,发现网上方法很多,但是比较杂,现在进行总结一下: 总共有两类方法: 一.代码直接判定 二.接收广播 现在先说第一类方法(代码直接判定): 1.通过PowerMan ...
- Android推断屏幕锁屏的方法总结
转载请注明:http://blog.csdn.net/heroxuetao/article/details/24639203 因为做一个项目,须要推断屏幕是否锁屏,发现网上方法非常多.可是比較杂.如今 ...
- android 仿小米icon处理,加阴影和边框
本人自己在做一个launcher,所以须要处理icon,加阴影和边框等.这仅仅是一种处理方法,其它的处理方法类似. 源码: https://github.com/com314159/LauncherI ...
- Android框架浅析之锁屏(Keyguard)机制原理
最近终于成功的摆脱了FM收音机,迈向了新的模块:锁屏.状态栏.Launcher---姑且称之为“IDLE”小组,或许叫手机 美容小组,要是能施展下周星星同学的还我漂漂拳,岂不快哉. OK,闲话打住,咱 ...
随机推荐
- ASP.NET MVC 系统过滤器、自定义过滤器
一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration:缓存的时间,以秒为 ...
- 2016年蓝桥杯省赛A组c++第1题
/* 某君新认识一网友. 当问及年龄时,他的网友说: “我的年龄是个2位数,我比儿子大27岁, 如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄” 请你计算:网友的年龄一共有多少种可能情况? 提 ...
- 20165317 学习基础和C语言基础调查
学习基础和C语言基础调查 关于优势技能 说来惭愧,读书多年,爱好不少,但是真的能拿的出手的.能被叫做特长的不多.至今,能在同龄人中处于较领先位置的也只有从四年级开始练起的乒乓球.记得开始练习乒乓球是从 ...
- 《mongoDB》概念-数据类型
一:概念 - mongoDB 是一个面向文档的数据库,而不是关系型数据库. - 摘自<mongoDB 权威指南 第2版>第3页 二:数据类型 - null - 用于表示空值或者不存在的字段 ...
- 洛谷P3602 Koishi Loves Segments 贪心
正解:贪心 解题报告: 传送门! 首先在学习贪心的入门题的时候我们就知道,当x=1的时候,也就是每条线段不能相交的时候的做法——就按右端点排序然后能选就选,也就是会议安排问题,原因显然?就你选右端点更 ...
- MySQL中死锁(转)
add by zhj: 总结一下,MySQL有主动和被动两种方式检测死锁. 主动方式:检查锁等待的图,如果有环,那就有死锁,这种情况下,会回滚事务. 被动方式:等待锁超时(即innodb_lock_w ...
- jquery实现简单的弹出框
弹出框本身是一个div,默认是隐藏不展示的,在需要弹框的时候使其显示,并浮在当前页面之上 弹框样式: .tanchuang { width: 100%; height: 100%; display: ...
- 弱网测试之基于TP-LINK
使用路由器做弱网测试应该是最真实的,网络工程师/运维工程师体会应该最深刻.这种方式测试成本也不高,比较推荐. 设置的方式不在赘述,参见使用手册,高级设置即可. 结束语: 这样测试的时候,测试机器连接该 ...
- android常用函数
package com.cqytjr.util; import java.io.File; import java.net.InetAddress; import java.net.NetworkIn ...
- 报错解决——pytesseract.pytesseract.TesseractError: (1,’Error opening data file /usr/local/share/tessdata/eng.traineddata’)
解决方法:(原文地址http://stackoverflow.com/questions/14800730/tesseract-running-error) $ wget https://tesser ...