Android顶部折叠渐变效果
顶部折叠效果大家一定不陌生,这个效果看起来也让界面的可观赏性增加了几分。废话不多说上效果。
说道顶部折叠有很多种方法,作者才疏学浅没有一尽学会就说说作者自己的方式好了。
这里就不说 CoordinatorLayout 和 AppBarLayout 的这种方式了,因为感觉控制渐变的时候不是那么细腻,以后有机会再重新研究一番。
这里要说的方式是通过判断布局的滚动距离来动态控制布局的透明度的方式来做这个效果。
思路:获取布局滚动的距离顶部的距离。通过滚动距离/规定阈值=透明比例。
首先是布局,这里的布局用的是
PullToRefreshListView 这个滑动控件其实和listview用法是一样的就是多了上拉和下拉
没有用这个的同学其实用scrollview是一样的这里不用担心。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:ptr="http://schemas.android.com/apk/res-auto"
android:background="@color/white">
<com.handmark.pulltorefresh.library.PullToRefreshListView
android:id="@+id/lv_toutiao"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:listSelector="@android:color/transparent"
android:divider="#00000000"
android:dividerHeight="1px"
android:gravity="fill"
android:scrollbars="none"
ptr:ptrAnimationStyle="flip"
ptr:ptrHeaderSubTextColor="@color/bg_full_image"
ptr:ptrHeaderTextColor="@color/bg_full_image"
/>
<TextView
android:id="@+id/tv_hint"
android:textSize="14sp"
android:gravity="center"
android:textColor="#0487ce"
android:layout_width="match_parent"
android:text=""
android:padding="10dp"
android:layout_height="wrap_content"
android:background="#e7edf1"
android:visibility="gone"
/>
<TextView
android:id="@+id/iv_reload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/icon_nothing"
android:drawablePadding="10dp"
android:text="点击加载"
android:background="@color/white"
android:textColor="@color/gray"
android:gravity="center_horizontal"
android:layout_centerInParent="true"
android:visibility="gone"
/>
</RelativeLayout>
有了PullToRefreshListView我们只要获取到 他的滑动距离也就能算出来这个透明度的比例值了。
那么我们如何获取PullToRefreshListView他的滑动呢,这里我们需要一个监听就是。
setOnScrollListener
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
添加如上监听以及其方法。
那我们如何来监听到我们的列表第一个元素的距顶高度呢。
首先我们先定一个方法 来判断是否是第一个元素
/**
* 判断是否是第一行
*
* @return
*/
private boolean isScroll() {
if (lv.getRefreshableView().getFirstVisiblePosition() == 1 || lv.getRefreshableView().getFirstVisiblePosition() == 0) {
return true;
}
return false;
}
这个方法就能让我们来获取到listview滚动时是否是第一个元素在滚动。
那么具体的距离怎么得到呢 我们还要另外一个方法。
/**
* 得到高度比例
*
* @return
*/
private float getScrollY() {
View c = lv.getRefreshableView().getChildAt(0);
if (c == null) {
return 0;
}
int firstVisiblePosition = lv.getRefreshableView().getFirstVisiblePosition();
if (firstVisiblePosition == 1 || firstVisiblePosition == 0) {
//如果可见的是第一行或第二行,那么开始计算距离比例
float top = c.getTop();
//当第一行已经开始消失的时候,top是为负数的,所以取正
top = Math.abs(top);
//48为菜单栏的高度,单位为dp
//得到的高度为ViewPager的高度减去菜单栏高度,即为最大可滑动距离
float height = c.getHeight()- dpTopx(228);
float y = top / height;
return y;
} else {
return 0;
}
}
这里面的228是可以根据个人的需要来填写,比如你希望距离顶部的距离是第一个元素到actionbar的距离那么就把Actionbar的距离在这里减掉。如果写0那么就是元素到手机屏幕顶端的距离。
然后根据手机我们再添加一个密度的换算方法。
/**
* 获取手机屏幕密度,将dp值转换为px
*
* @param dpValue
* @return px
*/
private int dpTopx(float dpValue) {
// 获取手机屏幕密度
final float scale = getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
那么重点来了,如何计算出这个透明比例呢 我们找到setOnScrollListener的onScroll()这个方法。
在onScroll()方法中我们添加如下内容
//判断是否是第一元素
if (isScroll()) {
//获取的滑动值
float scrollY = getScrollY();
Log.e("scrollY", "" + scrollY);
//判断是否到达阈值
if (scrollY <= 1) {
//按比值获取透明度
float alpha = (float) scrollY;
CodeBean bean = new CodeBean(alpha, 2);
//这里利用EventBus动态传值
EventBus.getDefault().post(bean);
}
}
至于透明度值的传值操作就不多说了, 因人而异用在哪里都不固定所以不好说。
好了功能很简单,希望对小伙伴有帮助
这里说明一下有的小伙伴会问onScroll()这个方法中的一个参数也没有用到啊。那是因为这里面的参数这是一当前元素为准。
也就是说当我们第一个元素已经滚动头部隐藏 那么第二个就会成为新的第一个“元素”这样我们的计算就没有意义了。
我是影子,但是光越亮影子就越深,更能显出光的明亮 -----黑子はボクです