效果
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" > <com.viewpagerindicator.TabPageIndicator android:id="@+id/indicator" android:layout_width="fill_parent" android:layout_height="50dp" /> <android.support.v4.view.ViewPager android: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}" > <cn.edu.zafu.view.observableview.ObservableListView xmlns: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() { @Override public void run() { height=indicator.getHeight(); Log.d("TAG", "height:"+height); } });
关联listview并设置监听器
listView = (ObservableListView) view.findViewById(R.id.list); listView.setScrollViewCallbacks(this);
fragment实现对应的接口
implements ObservableScrollViewCallbacks
实现的方法如下
@Override public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { } @Override public void onDownMotionEvent() { } @Override public void onUpOrCancelMotionEvent(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(); } }
完成显示和隐藏的函数,使用属性动画完成一个过渡效果
public void showIndicator() { //属性动画translationY ObjectAnimator animator = ObjectAnimator.ofFloat(indicator, "translationY", 0f); //持续时间 animator.setDuration(500); //插值器,减速 animator.setInterpolator(new DecelerateInterpolator(2)); //监听器 animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(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() { @Override public void onAnimationStart(Animator animation) { //动画开始后设置为true isShowing=true; super.onAnimationStart(animation); } @Override public void onAnimationEnd(Animator animation) { //动画结束后设置为false isShowing=false; //显示后设置为已显示 isIndicatorShow = true; super.onAnimationEnd(animation); } }); //开始动画 animator.start(); } public void hideIndicator() { ObjectAnimator animator = ObjectAnimator.ofFloat(indicator, "translationY",-height); animator.setDuration(500); //加速插值器 animator.setInterpolator(new AccelerateInterpolator(2)); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(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() { @Override public void onAnimationStart(Animator animation) { isShowing=true; super.onAnimationStart(animation); } @Override public void onAnimationEnd(Animator animation) { isShowing=false; isIndicatorShow = false; super.onAnimationEnd(animation); } }); animator.start(); }
所有用到的变量
private View view = null;//存储fragemnt的视图 private TabPageIndicator indicator = null;//indicator private ObservableListView listView = null;//listview private int indicatorId;//indicator对应的id值 private int height=0;//indicator高低 private boolean isIndicatorShow = true;//是否显示 private boolean isShowing=false;//动画是否正在进行
源码下载
源码下载