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

闲话不多说,直接上图。




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

第一部分:沉浸式状态栏(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:303767416@qq.com 
  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:303767416@qq.com */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>  
<?xml version="1.0" encoding="utf-8"?>                                                                                                    

这里我即没有用到 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:303767416@qq.com 
  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:303767416@qq.com */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


更多相关文章

  1. Java乔晓松-android控制显示和隐藏视图或控件的操作
  2. 注册谷歌地图 API 密钥和显示谷歌地图
  3. 深入了解Android图形管道-part1
  4. 8.3facebook分享后不回调结果原因,java标签代码
  5. Android(安卓)LocationManager 使用
  6. Android(安卓)- 代码片段
  7. Android(安卓)UI学习 Linear Layout, RelativeLayout
  8. android,利用layoutParams代码动态布局空间位置
  9. Android(安卓)软键盘使用总结

随机推荐

  1. android 编译自己的sdk
  2. [译] 在 Android 使用协程(part III) -
  3. android导入多个第三方包
  4. 实战技巧:Android异步指南
  5. Android 个别手机导航键覆盖布局解决办法
  6. Android开发中的MVC
  7. NFC:Arduino、Android与PhoneGap近场通信
  8. Android仿iPhone圆角边框
  9. 从零学Android(八)、Android资源类型之Draw
  10. 深入探究Android的WebView下载网络文件的