GeorgeYang'Blog

my technology blog

android轻松搞定标题随scrollview滑动变色

阅读:985 创建时间:16-02-23 03:45:57 tags:android,widget

要实现某个view的背景透明度跟随scrollview滑动而改变需要重新scrollview的onOverScrolled方法,该方法随着滑动变化(包括手指滑动、手指移开惯性滑动)而响应,所以最适合做变色处理。

step1:设定布局

由于我们要实现的是滑动时标题的背景透明度改变,固定顶部的标题view不能在srcollview里面跟随滑动,所以需要这样布局:

     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent">

         <com.****.ScrollChangeScrollView
             android:id="@+id/scrollView"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:fillViewport="true">

             <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:orientation="vertical">

                     <TextView
                         android:layout_width="0dp"
                         android:layout_height="wrap_content"
                         android:layout_weight="1"
                         android:drawablePadding="5dp"
                         android:drawableTop="@drawable/dicovery_vintner_icon_wine"
                         android:gravity="center"
                         android:text="葡萄酒"
                         android:textColor="@color/hometitlebg" />



             </LinearLayout>

         </com.***.ScrollChangeScrollView>

         <Button
             android:id="@+id/btn_back"
             android:layout_width="match_parent"
             android:layout_height="35dp"
             android:layout_centerVertical="true"
             android:background="@null"
             android:drawableLeft="@drawable/icon_back"
             android:padding="10dp" />

     </FrameLayout>

step2:添加需要用到的方法

滑动时,某个view要变色,重新scrollview后,添加方法让其知道该view需要变色

    private View mTitleView;
     /**
      * 变色标题view
      * @param view
      */
     public void setupTitleView (View view) {
         this.mTitleView = view;
     }

滑动时变色需要参考scrollview里面的某个子view的滑动高度,如果该子view上划完全划出屏幕,则标题view背景透明为0:

    private View mByWhichView;
     /**
      * 跟随的view
      * @param view
      */
     public void setupByWhichView(View view) {
         mByWhichView = view;
     }

再添加一个设置,如果不要背景透明度渐变:

    private boolean shouldSlowlyChange;
     public void setShouldSlowlyChange(boolean slowlyChange) {
         this.shouldSlowlyChange = slowlyChange;
     }

step3:代码实现

 **
  * 滑动时标题变色view
  * Created by george.yang on 16/2/21.
  */
 public class ScrollChangeScrollView extends ScrollView {
     private View mByWhichView;
     private View mTitleView;
     private boolean shouldSlowlyChange = true;

     public ScrollChangeScrollView(Context context) {
         super(context);
     }

     public ScrollChangeScrollView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }

     public ScrollChangeScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
     }

     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public ScrollChangeScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
     }


     @Override
     public void scrollTo(int x, int y) {
        //这是为了修复noScrllListView嵌套在srcollview时就自动滑动到noscrolllistview的顶部的bug,不影响使用
         if (x == 0 && y == 0 || y <= 0) {
             super.scrollTo(x, y);
         }
     }

     public void setListener(OnScrollListener listener){
         this.mListener = listener;
     }

     public void setShouldSlowlyChange(boolean slowlyChange) {
         this.shouldSlowlyChange = slowlyChange;
     }

     /**
      * 设置透明度渐变的标题view
      * @param view
      */
     public void setupTitleView (View view) {
         this.mTitleView = view;
     }

     /**
      * 跟随的view
      * @param view
      */
     public void setupByWhichView(View view) {
         mByWhichView = view;
     }

     @Override
     protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
                                   boolean clampedY) {
         super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);

         if (scrollY >= mByWhichView.getTop() + mByWhichView.getMeasuredHeight()) {
             mTitleView.setBackgroundColor(Color.BLACK);
         } else if (scrollY>=0) {
             if (!shouldSlowlyChange) {
                 mTitleView.setBackgroundColor(Color.TRANSPARENT);
             } else {
                 float persent = scrollY * 1f / (mByWhichView.getTop() + mByWhichView.getMeasuredHeight());
                 int alpha = (int) (255 * persent);
                 int color = Color.argb(alpha,0,0,0);
                 mTitleView.setBackgroundColor(color);
             }
         }

         if (mListener!=null) {
             mListener.onScroll(scrollX, scrollY);
         }
     }
 }

效果如下:

滑动前

滑动变色中

参考的view超出屏幕后