Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩

转载于:Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩 - CSDN博客 http://blog.csdn.net/yanjunhui2011/article/details/55190456
文章内容如下:

闲话不多说,直接上图。

Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩_第1张图片



给大家讲讲我的编程思想吧。

第一部分:沉浸式状态栏(API-Level 19, Android4.4 KitKat 之后加入的东西),而且在Api-Level 21版本中新增了一个属性(下面会说到)。所以,style文件应该声明三份。

values

values-19

values-V21


至于以上属性的含义及使用方式,就不多做解释了。详细可参见 http://blog.csdn.net/fan7983377/article/details/51604657


第二部分:actionBar渐变


因为要实现actionBar渐变,所以我没有使用系统的actionBar。而是自定义了一个继承自LinearLayout的ViewGroup。

直接给各位看代码

[java] view plain copy
print ?
  1. package test.com.widget;  
  2.   
  3. import android.content.Context;  
  4. import android.text.TextUtils;  
  5. import android.util.AttributeSet;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.LinearLayout;  
  9. import android.widget.TextView;  
  10.   
  11. import test.com.R;  
  12. import test.com.impl.ActionBarClickListener;  
  13.   
  14. /** 
  15.  * 支持渐变的 actionBar 
  16.  * Created by 晖仔(Milo) on 2016/12/28. 
  17.  * email:[email protected] 
  18.  */  
  19.   
  20. public final class TranslucentActionBar extends LinearLayout {  
  21.   
  22.     private View layRoot;  
  23.     private View vStatusBar;  
  24.     private View layLeft;  
  25.     private View layRight;  
  26.     public TextView tvTitle;  
  27.     private TextView tvLeft;  
  28.     private TextView tvRight;  
  29.     private View iconLeft;  
  30.     private View iconRight;  
  31.   
  32.     public TranslucentActionBar(Context context) {  
  33.         this(context, null);  
  34.     }  
  35.   
  36.     public TranslucentActionBar(Context context, AttributeSet attrs) {  
  37.         super(context, attrs);  
  38.         init();  
  39.     }  
  40.   
  41.     public TranslucentActionBar(Context context, AttributeSet attrs, int defStyleAttr) {  
  42.         super(context, attrs, defStyleAttr);  
  43.     }  
  44.   
  45.     private void init() {  
  46.         setOrientation(HORIZONTAL);  
  47.         View contentView = inflate(getContext(), R.layout.actionbar_trans, this);  
  48.         layRoot = contentView.findViewById(R.id.lay_transroot);  
  49.         vStatusBar = contentView.findViewById(R.id.v_statusbar);  
  50.         tvTitle = (TextView) contentView.findViewById(R.id.tv_actionbar_title);  
  51.         tvLeft = (TextView) contentView.findViewById(R.id.tv_actionbar_left);  
  52.         tvRight = (TextView) contentView.findViewById(R.id.tv_actionbar_right);  
  53.         iconLeft = contentView.findViewById(R.id.iv_actionbar_left);  
  54.         iconRight = contentView.findViewById(R.id.v_actionbar_right);  
  55.     }  
  56.   
  57.     /** 
  58.      * 设置状态栏高度 
  59.      * 
  60.      * @param statusBarHeight 
  61.      */  
  62.     public void setStatusBarHeight(int statusBarHeight) {  
  63.         ViewGroup.LayoutParams params = vStatusBar.getLayoutParams();  
  64.         params.height = statusBarHeight;  
  65.         vStatusBar.setLayoutParams(params);  
  66.     }  
  67.   
  68.     /** 
  69.      * 设置是否需要渐变 
  70.      */  
  71.     public void setNeedTranslucent() {  
  72.         setNeedTranslucent(truefalse);  
  73.     }  
  74.   
  75.     /** 
  76.      * 设置是否需要渐变,并且隐藏标题 
  77.      * 
  78.      * @param translucent 
  79.      */  
  80.     public void setNeedTranslucent(boolean translucent, boolean titleInitVisibile) {  
  81.         if (translucent) {  
  82.             layRoot.setBackgroundDrawable(null);  
  83.         }  
  84.         if (!titleInitVisibile) {  
  85.             tvTitle.setVisibility(View.GONE);  
  86.         }  
  87.     }  
  88.   
  89.     /** 
  90.      * 设置标题 
  91.      * 
  92.      * @param strTitle 
  93.      */  
  94.     public void setTitle(String strTitle) {  
  95.         if (!TextUtils.isEmpty(strTitle)) {  
  96.             tvTitle.setText(strTitle);  
  97.         } else {  
  98.             tvTitle.setVisibility(View.GONE);  
  99.         }  
  100.     }  
  101.   
  102.     /** 
  103.      * 设置数据 
  104.      * 
  105.      * @param strTitle 
  106.      * @param resIdLeft 
  107.      * @param strLeft 
  108.      * @param resIdRight 
  109.      * @param strRight 
  110.      * @param listener 
  111.      */  
  112.     public void setData(String strTitle, int resIdLeft, String strLeft, int resIdRight, String strRight, final ActionBarClickListener listener) {  
  113.         if (!TextUtils.isEmpty(strTitle)) {  
  114.             tvTitle.setText(strTitle);  
  115.         } else {  
  116.             tvTitle.setVisibility(View.GONE);  
  117.         }  
  118.         if (!TextUtils.isEmpty(strLeft)) {  
  119.             tvLeft.setText(strLeft);  
  120.             tvLeft.setVisibility(View.VISIBLE);  
  121.         } else {  
  122.             tvLeft.setVisibility(View.GONE);  
  123.         }  
  124.         if (!TextUtils.isEmpty(strRight)) {  
  125.             tvRight.setText(strRight);  
  126.             tvRight.setVisibility(View.VISIBLE);  
  127.         } else {  
  128.             tvRight.setVisibility(View.GONE);  
  129.         }  
  130.   
  131.         if (resIdLeft == 0) {  
  132.             iconLeft.setVisibility(View.GONE);  
  133.         } else {  
  134.             iconLeft.setBackgroundResource(resIdLeft);  
  135.             iconLeft.setVisibility(View.VISIBLE);  
  136.         }  
  137.   
  138.         if (resIdRight == 0) {  
  139.             iconRight.setVisibility(View.GONE);  
  140.         } else {  
  141.             iconRight.setBackgroundResource(resIdRight);  
  142.             iconRight.setVisibility(View.VISIBLE);  
  143.         }  
  144.   
  145.         if (listener != null) {  
  146.             layLeft = findViewById(R.id.lay_actionbar_left);  
  147.             layRight = findViewById(R.id.lay_actionbar_right);  
  148.             layLeft.setOnClickListener(new View.OnClickListener() {  
  149.                 @Override  
  150.                 public void onClick(View v) {  
  151.                     listener.onLeftClick();  
  152.                 }  
  153.             });  
  154.             layRight.setOnClickListener(new View.OnClickListener() {  
  155.                 @Override  
  156.                 public void onClick(View v) {  
  157.                     listener.onRightClick();  
  158.                 }  
  159.             });  
  160.         }  
  161.     }  
  162.   
  163. }  
package test.com.widget;

import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import test.com.R;
import test.com.impl.ActionBarClickListener;

/**
 * 支持渐变的 actionBar
 * Created by 晖仔(Milo) on 2016/12/28.
 * email:[email protected]
 */

public final class TranslucentActionBar extends LinearLayout {

    private View layRoot;
    private View vStatusBar;
    private View layLeft;
    private View layRight;
    public TextView tvTitle;
    private TextView tvLeft;
    private TextView tvRight;
    private View iconLeft;
    private View iconRight;

    public TranslucentActionBar(Context context) {
        this(context, null);
    }

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

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

    private void init() {
        setOrientation(HORIZONTAL);
        View contentView = inflate(getContext(), R.layout.actionbar_trans, this);
        layRoot = contentView.findViewById(R.id.lay_transroot);
        vStatusBar = contentView.findViewById(R.id.v_statusbar);
        tvTitle = (TextView) contentView.findViewById(R.id.tv_actionbar_title);
        tvLeft = (TextView) contentView.findViewById(R.id.tv_actionbar_left);
        tvRight = (TextView) contentView.findViewById(R.id.tv_actionbar_right);
        iconLeft = contentView.findViewById(R.id.iv_actionbar_left);
        iconRight = contentView.findViewById(R.id.v_actionbar_right);
    }

    /**
     * 设置状态栏高度
     *
     * @param statusBarHeight
     */
    public void setStatusBarHeight(int statusBarHeight) {
        ViewGroup.LayoutParams params = vStatusBar.getLayoutParams();
        params.height = statusBarHeight;
        vStatusBar.setLayoutParams(params);
    }

    /**
     * 设置是否需要渐变
     */
    public void setNeedTranslucent() {
        setNeedTranslucent(true, false);
    }

    /**
     * 设置是否需要渐变,并且隐藏标题
     *
     * @param translucent
     */
    public void setNeedTranslucent(boolean translucent, boolean titleInitVisibile) {
        if (translucent) {
            layRoot.setBackgroundDrawable(null);
        }
        if (!titleInitVisibile) {
            tvTitle.setVisibility(View.GONE);
        }
    }

    /**
     * 设置标题
     *
     * @param strTitle
     */
    public void setTitle(String strTitle) {
        if (!TextUtils.isEmpty(strTitle)) {
            tvTitle.setText(strTitle);
        } else {
            tvTitle.setVisibility(View.GONE);
        }
    }

    /**
     * 设置数据
     *
     * @param strTitle
     * @param resIdLeft
     * @param strLeft
     * @param resIdRight
     * @param strRight
     * @param listener
     */
    public void setData(String strTitle, int resIdLeft, String strLeft, int resIdRight, String strRight, final ActionBarClickListener listener) {
        if (!TextUtils.isEmpty(strTitle)) {
            tvTitle.setText(strTitle);
        } else {
            tvTitle.setVisibility(View.GONE);
        }
        if (!TextUtils.isEmpty(strLeft)) {
            tvLeft.setText(strLeft);
            tvLeft.setVisibility(View.VISIBLE);
        } else {
            tvLeft.setVisibility(View.GONE);
        }
        if (!TextUtils.isEmpty(strRight)) {
            tvRight.setText(strRight);
            tvRight.setVisibility(View.VISIBLE);
        } else {
            tvRight.setVisibility(View.GONE);
        }

        if (resIdLeft == 0) {
            iconLeft.setVisibility(View.GONE);
        } else {
            iconLeft.setBackgroundResource(resIdLeft);
            iconLeft.setVisibility(View.VISIBLE);
        }

        if (resIdRight == 0) {
            iconRight.setVisibility(View.GONE);
        } else {
            iconRight.setBackgroundResource(resIdRight);
            iconRight.setVisibility(View.VISIBLE);
        }

        if (listener != null) {
            layLeft = findViewById(R.id.lay_actionbar_left);
            layRight = findViewById(R.id.lay_actionbar_right);
            layLeft.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    listener.onLeftClick();
                }
            });
            layRight.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    listener.onRightClick();
                }
            });
        }
    }

}


下面是actionbar_trans.xml的代码

[html] view plain copy
print ?
  1. xml version=“1.0” encoding=“utf-8”?>  
  2. <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”  
  3.     android:id=“@+id/lay_transroot”  
  4.     android:layout_width=“match_parent”  
  5.     android:layout_height=“wrap_content”  
  6.     android:background=“@color/colorPrimary”  
  7.     android:orientation=“vertical”>  
  8.   
  9.     <View  
  10.         android:id=“@+id/v_statusbar”  
  11.         android:layout_width=“match_parent”  
  12.         android:layout_height=“1.0dp” />  
  13.   
  14.     <RelativeLayout  
  15.         android:layout_width=“match_parent”  
  16.         android:layout_height=“45dp”  
  17.         android:orientation=“vertical”>  
  18.   
  19.         <RelativeLayout  
  20.             android:id=“@+id/lay_actionbar_left”  
  21.             android:layout_width=“100dp”  
  22.             android:layout_height=“match_parent”  
  23.             android:orientation=“horizontal”>  
  24.   
  25.             <ImageView  
  26.                 android:id=“@+id/iv_actionbar_left”  
  27.                 android:layout_width=“20dp”  
  28.                 android:layout_height=“20dp”  
  29.                 android:layout_centerVertical=“true”  
  30.                 android:layout_marginLeft=“10dp”  
  31.                 android:background=“@mipmap/ic_left_light”  
  32.                 android:visibility=“gone” />  
  33.   
  34.             <TextView  
  35.                 android:id=“@+id/tv_actionbar_left”  
  36.                 style=“@style/text_white”  
  37.                 android:layout_height=“match_parent”  
  38.                 android:layout_marginLeft=“10dp”  
  39.                 android:layout_toRightOf=“@+id/iv_actionbar_left”  
  40.                 android:gravity=“center_vertical”  
  41.                 android:maxLength=“2”  
  42.                 android:singleLine=“true”  
  43.                 android:text=“返回”  
  44.                 android:visibility=“gone” />  
  45.         RelativeLayout>  
  46.   
  47.         <TextView  
  48.             android:id=“@+id/tv_actionbar_title”  
  49.             style=“@style/text_white”  
  50.             android:layout_centerInParent=“true”  
  51.             android:text=“标题”  
  52.             android:textSize=“16sp” />  
  53.   
  54.         <RelativeLayout  
  55.             android:id=“@+id/lay_actionbar_right”  
  56.             android:layout_width=“100dp”  
  57.             android:layout_height=“match_parent”  
  58.             android:layout_alignParentRight=“true”  
  59.             android:gravity=“right”  
  60.             android:orientation=“horizontal”>  
  61.   
  62.             <View  
  63.                 android:id=“@+id/v_actionbar_right”  
  64.                 android:layout_width=“20dp”  
  65.                 android:layout_height=“20dp”  
  66.                 android:layout_alignParentRight=“true”  
  67.                 android:layout_centerVertical=“true”  
  68.                 android:layout_marginRight=“10dp”  
  69.                 android:visibility=“gone” />  
  70.   
  71.             <TextView  
  72.                 android:id=“@+id/tv_actionbar_right”  
  73.                 style=“@style/text_white”  
  74.                 android:layout_height=“match_parent”  
  75.                 android:layout_marginRight=“10dp”  
  76.                 android:layout_toLeftOf=“@+id/v_actionbar_right”  
  77.                 android:gravity=“center_vertical|right”  
  78.                 android:singleLine=“true”  
  79.                 android:visibility=“gone” />  
  80.         RelativeLayout>  
  81.   
  82.     RelativeLayout>  
  83. LinearLayout>  



    

    

        

            

            
        

        

        

            

            
        

    

这里我即没有用到 android:fitsSystemWindows=”true” 属性,也没有用到 StatusBarUtils ,因为我发现使用的时候很容易造成兼容问题。

所以,我的做法是声明了一个高度为0.0dp的 statusbar,背景为透明,然后获取状态栏高度并赋值到它上,来实现兼容。事实证明,这样做的兼容效果最好。


获取状态栏高度代码:

[java] view plain copy
print ?
  1. /** 
  2.  * 获取状态栏高度 
  3.  * 
  4.  * @return 
  5.  */  
  6. public int getStatusBarHeight() {  
  7.     //获取status_bar_height资源的ID  
  8.     int resourceId = getResources().getIdentifier(“status_bar_height”“dimen”“android”);  
  9.     if (resourceId > 0) {  
  10.         //根据资源ID获取响应的尺寸值  
  11.         return getResources().getDimensionPixelSize(resourceId);  
  12.     }  
  13.     return 0;  
  14. }  
    /**
     * 获取状态栏高度
     *
     * @return
     */
    public int getStatusBarHeight() {
        //获取status_bar_height资源的ID
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            //根据资源ID获取响应的尺寸值
            return getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }

设置 statusbar高度:

[java] view plain copy
print ?
  1. /** 
  2.  * 设置状态栏高度 
  3.  * 
  4.  * @param statusBarHeight 
  5.  */  
  6. public void setStatusBarHeight(int statusBarHeight) {  
  7.     ViewGroup.LayoutParams params = vStatusBar.getLayoutParams();  
  8.     params.height = statusBarHeight;  
  9.     vStatusBar.setLayoutParams(params);  
  10. }  
    /**
     * 设置状态栏高度
     *
     * @param statusBarHeight
     */
    public void setStatusBarHeight(int statusBarHeight) {
        ViewGroup.LayoutParams params = vStatusBar.getLayoutParams();
        params.height = statusBarHeight;
        vStatusBar.setLayoutParams(params);
    }

开启渐变:

[java] view plain copy
print ?
  1. /** 
  2.    * 设置是否需要渐变 
  3.    */  
  4.   public void setNeedTranslucent() {  
  5.       setNeedTranslucent(truefalse);  
  6.   }  
  7.   
  8.   /** 
  9.    * 设置是否需要渐变,并且隐藏标题 
  10.    * 
  11.    * @param translucent 
  12.    */  
  13.   public void setNeedTranslucent(boolean translucent, boolean titleInitVisibile) {  
  14.       if (translucent) {  
  15.           layRoot.setBackgroundDrawable(null);  
  16.       }  
  17.       if (!titleInitVisibile) {  
  18.           tvTitle.setVisibility(View.GONE);  
  19.       }  
  20.   }  
  /**
     * 设置是否需要渐变
     */
    public void setNeedTranslucent() {
        setNeedTranslucent(true, false);
    }

    /**
     * 设置是否需要渐变,并且隐藏标题
     *
     * @param translucent
     */
    public void setNeedTranslucent(boolean translucent, boolean titleInitVisibile) {
        if (translucent) {
            layRoot.setBackgroundDrawable(null);
        }
        if (!titleInitVisibile) {
            tvTitle.setVisibility(View.GONE);
        }
    }


第三步:实现ScrollView顶部伸缩

到了这里,必须得说一下,因为是个人项目中用到,所以并没有把功能做的很强大,本人都是以最简单、有效的方式实现的。所以,代码并不像gitHub上那些被下载很多次的开源项目一样,有很高的扩展性。

时间关系,我直接贴代码吧,代码里我都写了注释的。

[java] view plain copy
print ?
  1. package test.com.widget;  
  2.   
  3. import android.animation.ObjectAnimator;  
  4. import android.animation.ValueAnimator;  
  5. import android.content.Context;  
  6. import android.graphics.Color;  
  7. import android.support.annotation.ColorInt;  
  8. import android.support.v4.graphics.ColorUtils;  
  9. import android.util.AttributeSet;  
  10. import android.util.Log;  
  11. import android.view.MotionEvent;  
  12. import android.view.View;  
  13. import android.view.ViewGroup;  
  14. import android.view.WindowManager;  
  15. import android.widget.ScrollView;  
  16.   
  17. import test.com.R;  
  18. import test.com.utils.SizeUtils;  
  19.   
  20. /** 
  21.  * Created by 晖仔(Milo) on 2017/2/13. 
  22.  * email:[email protected] 
  23.  */  
  24.   
  25. public class TranslucentScrollView extends ScrollView {  
  26.   
  27.     static final String TAG = “TranslucentScrollView”;  
  28.   
  29.     //伸缩视图  
  30.     private View zoomView;  
  31.     //伸缩视图初始高度  
  32.     private int zoomViewInitHeight = 0;  
  33.     // 记录首次按下位置  
  34.     private float mFirstPosition = 0;  
  35.     // 是否正在放大  
  36.     private Boolean mScaling = false;  
  37.   
  38.     //渐变的视图  
  39.     private View transView;  
  40.     //渐变颜色  
  41.     private int transColor = Color.WHITE;  
  42.     //渐变开始位置  
  43.     private int transStartY = 50;  
  44.     //渐变结束位置  
  45.     private int transEndY = 300;  
  46.   
  47.     //渐变开始默认位置,Y轴,50dp  
  48.     private final int DFT_TRANSSTARTY = 50;  
  49.     //渐变结束默认位置,Y轴,300dp  
  50.     private final int DFT_TRANSENDY = 300;  
  51.   
  52.     private TranslucentScrollView.TranslucentChangedListener translucentChangedListener;  
  53.   
  54.     public interface TranslucentChangedListener {  
  55.         /** 
  56.          * 透明度变化,取值范围0-255 
  57.          * 
  58.          * @param transAlpha 
  59.          */  
  60.         void onTranslucentChanged(int transAlpha);  
  61.     }  
  62.   
  63.     public TranslucentScrollView(Context context) {  
  64.         super(context);  
  65.     }  
  66.   
  67.     public TranslucentScrollView(Context context, AttributeSet attrs) {  
  68.         super(context, attrs);  
  69.     }  
  70.   
  71.     public TranslucentScrollView(Context context, AttributeSet attrs, int defStyleAttr) {  
  72.         super(context, attrs, defStyleAttr);  
  73.     }  
  74.   
  75.     public void setTranslucentChangedListener(TranslucentScrollView.TranslucentChangedListener translucentChangedListener) {  
  76.         this.translucentChangedListener = translucentChangedListener;  
  77.     }  
  78.   
  79.     /** 
  80.      * 设置伸缩视图 
  81.      * 
  82.      * @param zoomView 
  83.      */  
  84.     public void setPullZoomView(View zoomView) {  
  85.         this.zoomView = zoomView;  
  86.         zoomViewInitHeight = zoomView.getLayoutParams().height;  
  87.         if (zoomViewInitHeight == LayoutParams.MATCH_PARENT || zoomViewInitHeight == WindowManager.LayoutParams.WRAP_CONTENT) {  
  88.             zoomView.post(new Runnable() {  
  89.                 @Override  
  90.                 public void run() {  
  91.                     zoomViewInitHeight = TranslucentScrollView.this.zoomView.getHeight();  
  92.                 }  
  93.             });  
  94.         }  
  95.     }  
  96.   
  97.     /** 
  98.      * 设置渐变视图 
  99.      * 
  100.      * @param transView 渐变的视图 
  101.      */  
  102.     public void setTransView(View transView) {  
  103.         setTransView(transView, getResources().getColor(R.color.colorPrimary), SizeUtils.dip2px(getContext(), DFT_TRANSSTARTY), SizeUtils.dip2px(getContext(), DFT_TRANSENDY));  
  104.     }  
  105.   
  106.     /** 
  107.      * 设置渐变视图 
  108.      * 
  109.      * @param transView  渐变的视图 
  110.      * @param transColor 渐变颜色 
  111.      * @param transEndY  渐变结束位置 
  112.      */  
  113.     public void setTransView(View transView, @ColorInt int transColor, int transStartY, int transEndY) {  
  114.         this.transView = transView;  
  115.         //初始视图-透明  
  116.         this.transView.setBackgroundColor(ColorUtils.setAlphaComponent(transColor, 0));  
  117.         this.transStartY = transStartY;  
  118.         this.transEndY = transEndY;  
  119.         this.transColor = transColor;  
  120.         if (transStartY > transEndY) {  
  121.             throw new IllegalArgumentException(“transStartY 不得大于 transEndY .. ”);  
  122.         }  
  123.     }  
  124.   
  125.     /** 
  126.      * 获取透明度 
  127.      * 
  128.      * @return 
  129.      */  
  130.     private int getTransAlpha() {  
  131.         float scrollY = getScrollY();  
  132.         if (transStartY != 0) {  
  133.             if (scrollY <= transStartY) {  
  134.                 return 0;  
  135.             } else if (scrollY >= transEndY) {  
  136.                 return 255;  
  137.             } else {  
  138.                 return (int) ((scrollY - transStartY) / (transEndY - transStartY) * 255);  
  139.             }  
  140.         } else {  
  141.             if (scrollY >= transEndY) {  
  142.                 return 255;  
  143.             }  
  144.             return (int) ((transEndY - scrollY) / transEndY * 255);  
  145.         }  
  146.     }  
  147.   
  148.     /** 
  149.      * 重置ZoomView 
  150.      */  
  151.     private void resetZoomView() {  
  152.         final ViewGroup.LayoutParams lp = zoomView.getLayoutParams();  
  153.         final float h = zoomView.getLayoutParams().height;// ZoomView当前高度  
  154.   
  155.         // 设置动画  
  156.         ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration(200);  
  157.   
  158.         anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
  159.             @Override  
  160.             public void onAnimationUpdate(ValueAnimator animation) {  
  161.                 float cVal = (Float) animation.getAnimatedValue();  
  162.                 lp.height = (int) (h - (h - zoomViewInitHeight) * cVal);  
  163.                 zoomView.setLayoutParams(lp);  
  164.             }  
  165.         });  
  166.         anim.start();  
  167.     }  
  168.   
  169.     @Override  
  170.     protected void onScrollChanged(int l, int t, int oldl, int oldt) {  
  171.         super.onScrollChanged(l, t, oldl, oldt);  
  172.         int transAlpha = getTransAlpha();  
  173.   
  174.         if (transView != null) {  
  175.             Log.d(TAG, ”[onScrollChanged .. in ], 透明度 == ” + transAlpha);  
  176.             transView.setBackgroundColor(ColorUtils.setAlphaComponent(transColor, transAlpha));  
  177.         }  
  178.         if (translucentChangedListener != null) {  
  179.             translucentChangedListener.onTranslucentChanged(transAlpha);  
  180.         }  
  181.     }  
  182.   
  183.     @Override  
  184.     public boolean onTouchEvent(MotionEvent event) {  
  185.         if (zoomView != null) {  
  186.             ViewGroup.LayoutParams params = zoomView.getLayoutParams();  
  187.             switch (event.getAction()) {  
  188.                 case MotionEvent.ACTION_UP:  
  189.                     //手指离开后恢复图片  
  190.                     mScaling = false;  
  191.                     resetZoomView();  
  192.                     break;  
  193.                 case MotionEvent.ACTION_MOVE:  
  194.                     if (!mScaling) {  
  195.                         if (getScrollY() == 0) {  
  196.                             mFirstPosition = event.getY();  
  197.                         } else {  
  198.                             break;  
  199.                         }  
  200.                     }  
  201.   
  202.                     int distance = (int) ((event.getY() - mFirstPosition) * 0.6);  
  203.                     if (distance < 0) {  
  204.                         break;  
  205.                     }  
  206.                     mScaling = true;  
  207.                     params.height = zoomViewInitHeight + distance;  
  208.   
  209.                     Log.d(TAG, ”params.height == ” + params.height + “, zoomViewInitHeight == ” + zoomViewInitHeight + “, distance == ” + distance);  
  210.                     zoomView.setLayoutParams(params);  
  211.                     return true;  
  212.             }  
  213.         }  
  214.   
  215.         return super.onTouchEvent(event);  
  216.     }  
  217.   
  218. }  
package test.com.widget;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.support.annotation.ColorInt;
import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ScrollView;

import test.com.R;
import test.com.utils.SizeUtils;

/**
 * Created by 晖仔(Milo) on 2017/2/13.
 * email:[email protected]
 */

public class TranslucentScrollView extends ScrollView {

    static final String TAG = “TranslucentScrollView”;

    //伸缩视图
    private View zoomView;
    //伸缩视图初始高度
    private int zoomViewInitHeight = 0;
    // 记录首次按下位置
    private float mFirstPosition = 0;
    // 是否正在放大
    private Boolean mScaling = false;

    //渐变的视图
    private View transView;
    //渐变颜色
    private int transColor = Color.WHITE;
    //渐变开始位置
    private int transStartY = 50;
    //渐变结束位置
    private int transEndY = 300;

    //渐变开始默认位置,Y轴,50dp
    private final int DFT_TRANSSTARTY = 50;
    //渐变结束默认位置,Y轴,300dp
    private final int DFT_TRANSENDY = 300;

    private TranslucentScrollView.TranslucentChangedListener translucentChangedListener;

    public interface TranslucentChangedListener {
        /**
         * 透明度变化,取值范围0-255
         *
         * @param transAlpha
         */
        void onTranslucentChanged(int transAlpha);
    }

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

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

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

    public void setTranslucentChangedListener(TranslucentScrollView.TranslucentChangedListener translucentChangedListener) {
        this.translucentChangedListener = translucentChangedListener;
    }

    /**
     * 设置伸缩视图
     *
     * @param zoomView
     */
    public void setPullZoomView(View zoomView) {
        this.zoomView = zoomView;
        zoomViewInitHeight = zoomView.getLayoutParams().height;
        if (zoomViewInitHeight == LayoutParams.MATCH_PARENT || zoomViewInitHeight == WindowManager.LayoutParams.WRAP_CONTENT) {
            zoomView.post(new Runnable() {
                @Override
                public void run() {
                    zoomViewInitHeight = TranslucentScrollView.this.zoomView.getHeight();
                }
            });
        }
    }

    /**
     * 设置渐变视图
     *
     * @param transView 渐变的视图
     */
    public void setTransView(View transView) {
        setTransView(transView, getResources().getColor(R.color.colorPrimary), SizeUtils.dip2px(getContext(), DFT_TRANSSTARTY), SizeUtils.dip2px(getContext(), DFT_TRANSENDY));
    }

    /**
     * 设置渐变视图
     *
     * @param transView  渐变的视图
     * @param transColor 渐变颜色
     * @param transEndY  渐变结束位置
     */
    public void setTransView(View transView, @ColorInt int transColor, int transStartY, int transEndY) {
        this.transView = transView;
        //初始视图-透明
        this.transView.setBackgroundColor(ColorUtils.setAlphaComponent(transColor, 0));
        this.transStartY = transStartY;
        this.transEndY = transEndY;
        this.transColor = transColor;
        if (transStartY > transEndY) {
            throw new IllegalArgumentException(“transStartY 不得大于 transEndY .. “);
        }
    }

    /**
     * 获取透明度
     *
     * @return
     */
    private int getTransAlpha() {
        float scrollY = getScrollY();
        if (transStartY != 0) {
            if (scrollY <= transStartY) {
                return 0;
            } else if (scrollY >= transEndY) {
                return 255;
            } else {
                return (int) ((scrollY - transStartY) / (transEndY - transStartY) * 255);
            }
        } else {
            if (scrollY >= transEndY) {
                return 255;
            }
            return (int) ((transEndY - scrollY) / transEndY * 255);
        }
    }

    /**
     * 重置ZoomView
     */
    private void resetZoomView() {
        final ViewGroup.LayoutParams lp = zoomView.getLayoutParams();
        final float h = zoomView.getLayoutParams().height;// ZoomView当前高度

        // 设置动画
        ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration(200);

        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float cVal = (Float) animation.getAnimatedValue();
                lp.height = (int) (h - (h - zoomViewInitHeight) * cVal);
                zoomView.setLayoutParams(lp);
            }
        });
        anim.start();
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        int transAlpha = getTransAlpha();

        if (transView != null) {
            Log.d(TAG, “[onScrollChanged .. in ], 透明度 == ” + transAlpha);
            transView.setBackgroundColor(ColorUtils.setAlphaComponent(transColor, transAlpha));
        }
        if (translucentChangedListener != null) {
            translucentChangedListener.onTranslucentChanged(transAlpha);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (zoomView != null) {
            ViewGroup.LayoutParams params = zoomView.getLayoutParams();
            switch (event.getAction()) {
                case MotionEvent.ACTION_UP:
                    //手指离开后恢复图片
                    mScaling = false;
                    resetZoomView();
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (!mScaling) {
                        if (getScrollY() == 0) {
                            mFirstPosition = event.getY();
                        } else {
                            break;
                        }
                    }

                    int distance = (int) ((event.getY() - mFirstPosition) * 0.6);
                    if (distance < 0) {
                        break;
                    }
                    mScaling = true;
                    params.height = zoomViewInitHeight + distance;

                    Log.d(TAG, “params.height == ” + params.height + “, zoomViewInitHeight == ” + zoomViewInitHeight + “, distance == ” + distance);
                    zoomView.setLayoutParams(params);
                    return true;
            }
        }

        return super.onTouchEvent(event);
    }

}

 

资源GitHub下载地址:https://github.com/yanjunhui2014/TranslucentScrollView


你可能感兴趣的:(Android之路)