效果
ViewPager中的内容,,比如ListView手势上下滑动,当内容向下滑动时,即手势上划,隐藏indictor,当内容向上滑动时,即手势下滑,显示indicator,效果如图所示
编码
借用两个库来快速完成 1. ViewPagerIndicator 2. ObservableScrollView
将两个库引入项目中去,快速的搭建一个ViewPager框架后,在ViewPager每页对应的Fragment的布局中增加一个ListView,这个ListView使用ObservableScrollView库中的ListView
主布局代码,使用线性布局,上方放置indicator,下方放置ViewPager<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”android:layout_width=”fill_parent”android:layout_height=”fill_parent”android:orientation=”vertical” ><android:id=”@+id/indicator”android:layout_width=”fill_parent”android:layout_height=”50dp” /><androidandroid:id=”@+id/viewpager”android:layout_width=”match_parent”android:layout_height=”match_parent” /></LinearLayout>
-Fragment代码,放置一个ObservableListView
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”xmlns:tools=”http://schemas.android.com/tools”android:layout_width=”match_parent”android:layout_height=”match_parent”android:orientation=”vertical”tools:context=”${relativePackage}.${activityClass}” ><cnxmlns:android=”http://schemas.android.com/apk/res/android”android:id=”@+id/list”android:layout_width=”match_parent”android:layout_height=”match_parent” /></LinearLayout>业务逻辑代码
在Activity中初始化indicator和viewpager,然后再fragment中处理viewpager中内容即listview手势上下滑动与indicator的联动。在onCreateView中管理indicator,并获取其高度
indicator = (TabPageIndicator) getActivity().findViewById(indicatorId);//获得indicator高度indicator.post(new Runnable() {() {height=indicator.getHeight();Log.d(“TAG”, “height:”+height);}});
关联listview并设置监听器
listView = (ObservableListView) view.findViewById(R.id.list);listView.setScrollViewCallbacks(this);
fragment实现对应的接口
implements ObservableScrollViewCallbacks
实现的方法如下
(int scrollY, boolean firstScroll,boolean dragging) {}() {}(ScrollState scrollState) {}
在onUpOrCancelMotionEvent方法中完成显示和隐藏indicator
//获得高度的另一种方法/*if(height==0){height=indicator.getHeight();Log.d(“TAG”, “height:”+height);}*///如果手势向上则隐藏,手势向下则显示if (scrollState == ScrollState.UP) {//如果显示的并且动画没有在进行,则隐藏if (isIndicatorShow&&!isShowing) {hideIndicator();}} else if (scrollState == ScrollState.DOWN) {//如果没显示的并且动画没有在进行,则显示if (!isIndicatorShow&&!isShowing) {showIndicator();}}
完成显示和隐藏的函数,使用属性动画完成一个过渡效果
() {//属性动画translationYObjectAnimator animator = ObjectAnimator.ofFloat(indicator, “translationY”,0f);//持续时间animator.setDuration(500);//插值器,减速animator.setInterpolator(new DecelerateInterpolator(2));//监听器animator.addUpdateListener(new AnimatorUpdateListener() {(ValueAnimator animation) {//不断增加indicator所在viewgroup的高度LayoutParams layoutParams = indicator.getLayoutParams();float v=(Float) animation.getAnimatedValue();Log.d(“TAG”,”show:”+v);layoutParams.height=height+(int)v;//重新布局indicator.requestLayout();}});animator.addListener(new AnimatorListenerAdapter() {(Animator animation) {//动画开始后设置为trueisShowing=true;super.onAnimationStart(animation);}(Animator animation) {//动画结束后设置为falseisShowing=false;//显示后设置为已显示isIndicatorShow = true;super.onAnimationEnd(animation);}});//开始动画animator.start();}() {ObjectAnimator animator = ObjectAnimator.ofFloat(indicator, “translationY”,-height);animator.setDuration(500);//加速插值器animator.setInterpolator(new AccelerateInterpolator(2));animator.addUpdateListener(new AnimatorUpdateListener() {(ValueAnimator animation) {//不断减小indicator所在viewgroup的高度LayoutParams layoutParams = indicator.getLayoutParams();float v=(Float) animation.getAnimatedValue();Log.d(“TAG”,”hide:”+v);layoutParams.height=height+(int)v;indicator.requestLayout();}});//同显示animator.addListener(new AnimatorListenerAdapter() {(Animator animation) {isShowing=true;super.onAnimationStart(animation);}(Animator animation) {isShowing=false;isIndicatorShow = false;super.onAnimationEnd(animation);}});animator.start();}
所有用到的变量
ObservableListView listView = indicatorId;height=isIndicatorShow = isShowing=false;//动画是否正在进行源码下载
源码下载
如果雨后还是雨,如果忧伤过后还是忧伤,