仿网易云音乐日推界面(监听AppBarLayout滑动+动态高斯模糊

效果就不展示了,反正是真的可以用。效率高。

2、Glide自带的

想不到吧?

只要在导入:

api ‘com.github.bumptech.glide:glide:4.9.0’

annotationProcessor ‘com.github.bumptech.glide:compiler:4.9.0’

api ‘jp.wasabeef:glide-transformations:4.0.1’ //高斯模糊api

然后在代码中引入:

Glide.with(this)

.load(coverUrl)

//第一个参数时模糊半径,范围在 0<radius<=25f,第二个参数是放大参数,默认是1仿网易云音乐日推界面(监听AppBarLayout滑动+动态高斯模糊

.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 1)))

.into(ivBg);

思路

上面的Api其实并不是最重要的,不要以为用了这些方法,就能在监听滑动的时候去用这些方法就可以达成效果了。

这是因为 你每次滑动,就要进行这些计算,如果图片精度、分辨率很高,一次计算达到了上百ms,那我们一次滑动至少产生15次以上的计算,这必然会产生卡顿。

所以我们要做的动态模糊,其实是一个幌子,我们不是根据监听滑动进行模糊,而是让视觉效果让它变得模糊,就像是欺骗的感觉

√:我们拿一份已经模糊的图放在低层,再拿一张完全不模糊的放在上层覆盖它,然后随着滑动,上层的透明度逐渐减低,下层逐渐显现出来,这样的视觉效果,正是一个图片逐渐模糊。

设置图片透明度使用 setImageView(alpha),呜呜呜我之前不知道这个方法,结果一直找不到解决方法。

实现


1、监听AppBarLayout滑动

因为AppBarLayou自带的api不太方便,我们需要再封装一层:

/**

  • AppBarLayout的监听类

*/

public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {

private static final String TAG = “AppBarStateChangeListen”;

public enum State {

EXPANDED,

COLLAPSED,

IDLE

}

private State mCurrentState = State.IDLE;

@Override

public void onOffsetChanged(AppBarLayout appBarLayout, int i) {

onOffsetChanged(appBarLayout);

if (i == 0) {

if (mCurrentState != State.EXPANDED) {

onStateChanged(appBarLayout, State.EXPANDED);

}

mCurrentState = State.EXPANDED;

} else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {

if (mCurrentState != State.COLLAPSED) {

onStateChanged(appBarLayout, State.COLLAPSED);

}

mCurrentState = State.COLLAPSED;

} else {

if (mCurrentState != State.IDLE) {

onStateChanged(appBarLayout, State.IDLE);

}

mCurrentState = State.IDLE;

}

}

//状态发生了改变

public abstract void onStateChanged(AppBarLayout appBarLayout, State state);

//发生了偏移

public abstract void onOffsetChanged(AppBarLayout appBarLayout);

}

2、XML文件

说来你们可能不信,我对圆角的处理是这样的:

仿网易云音乐日推界面(监听AppBarLayout滑动+动态高斯模糊

蓝色和天蓝色都是属于AppBarLayout,上滑需要对圆角layout设置layout_collapseMode="parallax"

然后 AppBarLayout最底层仿两个ImageView,模糊的在下面,清晰的在上面。

并且 AppBarLayout的 app:elevation 要设置为 0dp,不然在折叠的时候会产生阴影,影响白色圆角的发挥

而且注意 是 app的elevation而不是 android的 elevation

<android.support.design.widget.AppBarLayout

android:id="@+id/appbar"

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

app:elevation=“0dp”>

<android.support.design.widget.CollapsingToolbarLayout

android:layout_width=“match_parent”

android:layout_height="@dimen/dp_200"

android:fitsSystemWindows=“true”

app:layout_scrollFlags=“scroll|exitUntilCollapsed”>

//低层模糊图片

<ImageView

android:id="@+id/iv_background"

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:scaleType=“centerCrop”

app:layout_collapseMode=“parallax” />

//上层做透明度变化的图片

<ImageView

android:id="@+id/iv_background_cover"

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:scaleType=“centerCrop”

app:layout_collapseMode=“parallax” />

//一些字体

<RelativeLayout

android:layout_width=“match_parent”

android:layout_height=“match_parent”

app:layout_collapseMode=“parallax”>

<TextView

android:id="@+id/tv_day"

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”/>

<TextView

android:id="@+id/tv_month"

android:layout_width=“wrap_content”

android:layout_height=“wrap_content” />

//标题头

<android.support.v7.widget.Toolbar

android:id="@+id/toolbar"

style="@style/ClubToolbar"

android:layout_width=“match_parent”

android:layout_height="@dimen/dp_55"

android:layout_marginTop="@dimen/dp_30"

app:layout_collapseMode=“pin”>

<include

android:id="@+id/title"

layout="@layout/common_title" />

</android.support.v7.widget.Toolbar>

//哈哈哈哈哈这个就是一个圆角矩形

<RelativeLayout

android:layout_width=“match_parent”

android:layout_height="@dimen/dp_10"

android:layout_marginTop="@dimen/dp_290"

android:background="@drawable/bg_dailyrecommend"

app:layout_collapseMode=“pin” />

</android.support.design.widget.CollapsingToolbarLayout>

</android.support.design.widget.AppBarLayout>

<RelativeLayout

android:id="@+id/rl_play"

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:background="#ffffff"

android:paddingBottom="@dimen/dp_40"

app:layout_behavior="@string/appbar_scrolling_view_behavior">

<android.support.v7.widget.RecyclerView

android:layout_width=“match_parent”

android:layout_height=“match_parent”/>

3、根据监听AppBarLayout来改变透明度

AppBarLayout的滑动监听是没有 偏移值 offsetX和offsetY的,所以滑动到一定距离,字体的透明度到一定值怎么弄呢,我这里借助的是包裹着RecyclerView的RelativeLayout距离顶部的距离做判断

该layout的 getTop() 越接近顶部,说明AppBarLayout快要折叠,我根据这个值去计算。

仿网易云音乐日推界面(监听AppBarLayout滑动+动态高斯模糊

从上图可以知道 我们处理getTop()返回在 Toobar高度~AppBarLayout高度.

如果在Toolbar设置了marginTop值,则也要在Toolbar高度里加上,我这里就设置了(因为使用了沉侵状态栏)。

首先在onCreate中初始化这些值:

//计算 getTop移动范围,和初始化图片

protected void initData() {

if (coverUrl != null) {

Glide.with(this)

.load(coverUrl)

.into(ivBgCover);

Glide.with(this)

.load(coverUrl)

.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 1)))
p()返回在 Toobar高度~AppBarLayout高度.

如果在Toolbar设置了marginTop值,则也要在Toolbar高度里加上,我这里就设置了(因为使用了沉侵状态栏)。

首先在onCreate中初始化这些值:

//计算 getTop移动范围,和初始化图片

protected void initData() {

if (coverUrl != null) {

Glide.with(this)

.load(coverUrl)

.into(ivBgCover);

Glide.with(this)

.load(coverUrl)

.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 1)))

上一篇:JUC学习-2


下一篇:三个线程按顺序执行-join实现