一:实现沉浸式状态栏,头部可以拉伸,头部图片可下拉放大,带有一键置顶功能 

先看看三个步骤:

1:在AndroidManifest.xml中设置Activity的属性为android:theme="@android:style/Theme.NoTitleBar"

2:在Layout的第一个布局中设置与头部的间隔(android:layout_marginTop="25dp",当然具体间隔多少需要根据自己的需求来)

3:在setContentView(R.layout.activity_userguide)之前super.onCreate(savedInstanceState)之后设置
 

if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);    }

 

Android 沉浸式状态栏 头部可拉伸带有一键置顶功能_第1张图片

 

Android 沉浸式状态栏 头部可拉伸带有一键置顶功能_第2张图片

 

Android 沉浸式状态栏 头部可拉伸带有一键置顶功能_第3张图片

 

1.主函数代码:

import android.graphics.Color;import android.os.Build;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.view.WindowManager;import android.widget.Button;import android.widget.ImageView;import android.widget.ListView;import android.widget.RelativeLayout;import android.widget.ScrollView;import android.widget.TextView;public class MainActivity extends AppCompatActivity {    private NotifyingScrollView scrollview;    private RelativeLayout topbar;    private ImageView topimage;    private ImageView iv_back;    private TextView tv_title;    private TextView textdemo;    private Button button;    private ListView listview;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //沉浸式状态栏        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);        }        InfoData();    }    public void InfoData(){        topbar = (RelativeLayout) findViewById(R.id.topbar);        topimage = (ImageView) findViewById(R.id.topimage);        iv_back = (ImageView) findViewById(R.id.iv_back);        tv_title = (TextView) findViewById(R.id.tv_title);        textdemo = (TextView) findViewById(R.id.textdemo);        button = (Button) findViewById(R.id.button);        listview = (ListView) findViewById(R.id.listview);        listview.setAdapter(new MyAdapter(this));        scrollview = (NotifyingScrollView) findViewById(R.id.scrollview);        //始终位于最顶部        scrollview.smoothScrollTo(0,0);        //初始化标题栏相关的色值,为透明        topbar.getBackground().setAlpha(0);        tv_title.setTextColor(Color.argb(0, 255, 255, 255));        textdemo.setBackgroundColor(Color.argb(0, 255, 255, 255));        scrollview.setOnScrollChangedListener(new NotifyingScrollView.OnScrollChangedListener() {            @Override            public void onScrollChanged(ScrollView who, int l, int t, int oldl,                                        int oldt) {                //滑动改变标题栏的透明度和文字透明度,图标                if (topimage == null) {                    return;                }                if(t < 0){                    return;                }                //置顶操作                if (t > scrollview.getHeight()/2){                    button.setVisibility(View.VISIBLE);                    button.setOnClickListener(new View.OnClickListener() {                        @Override                        public void onClick(View v) {                            scrollview.smoothScrollTo(0,0);                        }                    });                }else {                    button.setVisibility(View.GONE);                }                //获取滑动高度,做出对顶部导航栏的操作                int lHeight = 2*(topbar.getHeight());                if (t <= lHeight) {                    int progress = (int) (new Float(t) / new Float(lHeight) * 255);                    topbar.getBackground().setAlpha(progress);                    tv_title.setTextColor(Color.argb(progress, 255, 255, 255));                    textdemo.setBackgroundColor(Color.argb(progress, 240, 240, 240));                    iv_back.setImageResource(R.mipmap.icon_back_normal);                } else {                    topbar.getBackground().setAlpha(255);                    tv_title.setTextColor(Color.argb(255, 255, 255, 255));                    textdemo.setBackgroundColor(Color.argb(255, 232, 232, 232));                    iv_back.setImageResource(R.mipmap.icon_back_pressed);                }            }        });    }}

2.主函数布局:

<?xml version="1.0" encoding="utf-8"?>                                                                                                        

3.自定义Scrollview:

import android.animation.ObjectAnimator;import android.animation.ValueAnimator;import android.content.Context;import android.os.Build;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.ScrollView;/** * 作者: yzp on 2016-10-09. * 邮箱: 15111424807@163.com * QQ: 486492302 * * 重写scrollview,以实现滑动效果 */public class NotifyingScrollView extends ScrollView implements View.OnTouchListener {    // 记录首次按下位置    private float mFirstPosition = 0;    // 是否正在放大    private Boolean mScaling = false;    private View dropZoomView;    private int dropZoomViewWidth;    private int dropZoomViewHeight;    private boolean mDisableEdgeEffects = true;    public interface OnScrollChangedListener {        void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt);    }    private OnScrollChangedListener mOnScrollChangedListener;    public NotifyingScrollView(Context context) {        super(context);    }    public NotifyingScrollView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public NotifyingScrollView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        super.onScrollChanged(l, t, oldl, oldt);        if (mOnScrollChangedListener != null) {            mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt);        }    }    public void setOnScrollChangedListener(OnScrollChangedListener listener) {        mOnScrollChangedListener = listener;    }    @Override    protected float getTopFadingEdgeStrength() {        if (mDisableEdgeEffects && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {            return 0.0f;        }        return super.getTopFadingEdgeStrength();    }    @Override    protected float getBottomFadingEdgeStrength() {        if (mDisableEdgeEffects && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {            return 0.0f;        }        return super.getBottomFadingEdgeStrength();    }    //下拉放大效果处理    @Override    protected void onFinishInflate() {        super.onFinishInflate();        init();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    private void init() {        setOverScrollMode(OVER_SCROLL_NEVER);        if (getChildAt(0) != null) {            ViewGroup vg = (ViewGroup) getChildAt(0);            if (vg.getChildAt(0) != null) {                dropZoomView = vg.getChildAt(0);                setOnTouchListener(this);            }        }    }    /**     * 下拉头部放大效果     * @param v     * @param event     * @return     */    @Override    public boolean onTouch(View v, MotionEvent event) {        if (dropZoomViewWidth <= 0 || dropZoomViewHeight <= 0) {            dropZoomViewWidth = dropZoomView.getMeasuredWidth();            dropZoomViewHeight = dropZoomView.getMeasuredHeight();        }        switch (event.getAction()) {            case MotionEvent.ACTION_UP:                //手指离开后恢复图片                mScaling = false;                replyImage();                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;                setZoom(1 + distance);                return true; // 返回true表示已经完成触摸事件,不再处理        }        return false;    }    // 回弹动画 (使用了属性动画)    public void replyImage() {        final float distance = dropZoomView.getMeasuredWidth() - dropZoomViewWidth;        // 设置动画        ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration((long) (distance * 0.7));        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                float cVal = (Float) animation.getAnimatedValue();                setZoom(distance - ((distance) * cVal));            }        });        anim.start();    }    //缩放    public void setZoom(float s) {        if (dropZoomViewHeight <= 0 || dropZoomViewWidth <= 0) {            return;        }        ViewGroup.LayoutParams lp = dropZoomView.getLayoutParams();        //此处不处理头部某一边变宽//        lp.width = (int) (dropZoomViewWidth + s);        lp.height = (int) (dropZoomViewHeight * ((dropZoomViewWidth + s) / dropZoomViewWidth));        dropZoomView.setLayoutParams(lp);    }}

4.适配器:

import android.content.Context;import android.support.v4.app.FragmentActivity;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;public class MyAdapter extends BaseAdapter {    Context context;    public MyAdapter(Context context) {        // TODO Auto-generated constructor stub        this.context=context;    }    @Override    public int getCount() {        return 15;    }    @Override    public Object getItem(int position) {        return null;    }    @Override    public long getItemId(int position) {        return 0;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        View  vi = convertView;        vi = vi.inflate(context, R.layout.listview_text, null);        return vi;    }}

5.适配器布局:

<?xml version="1.0" encoding="utf-8"?>    

二:Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩(拉伸时上下伸缩,左右不变)

Android 沉浸式状态栏 头部可拉伸带有一键置顶功能_第4张图片

(上图是参考图片,来自yanjunhui) 

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

values:

values-19:

 values-V21

1.自定义TranslucentScrollView类:

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;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 colorRes 渐变的颜色     */    public void setTransColor(@ColorInt int colorRes) {        this.transColor = colorRes;    }    /**     * 设置渐变视图     *     * @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);    }}

 2.主函数布局:

<?xml version="1.0" encoding="utf-8"?>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

3.主函数逻辑:

import android.os.Bundle;import android.support.annotation.Nullable;import android.view.View;import test.com.base.BaseActivity;import test.com.impl.ActionBarClickListener;import test.com.widget.TranslucentActionBar;import test.com.widget.TranslucentScrollView;public class MainActivity extends BaseActivity implements ActionBarClickListener, TranslucentScrollView.TranslucentChangedListener {    private TranslucentScrollView translucentScrollView;    private TranslucentActionBar actionBar;    private View zoomView;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();    }    private void init() {        actionBar = (TranslucentActionBar) findViewById(R.id.actionbar);        //初始actionBar        actionBar.setData("测试", 0, null, 0, null, null);        //开启渐变        actionBar.setNeedTranslucent();        //设置状态栏高度        actionBar.setStatusBarHeight(getStatusBarHeight());        translucentScrollView = (TranslucentScrollView) findViewById(R.id.pullzoom_scrollview);        //设置透明度变化监听        translucentScrollView.setTranslucentChangedListener(this);        //关联需要渐变的视图        translucentScrollView.setTransView(actionBar);        //设置ActionBar键渐变颜色        translucentScrollView.setTransColor(getResources().getColor(R.color.orange_dft));        zoomView = findViewById(R.id.lay_header);        //关联伸缩的视图        translucentScrollView.setPullZoomView(zoomView);    }    @Override    public void onLeftClick() {    }    @Override    public void onRightClick() {    }    @Override    public void onTranslucentChanged(int transAlpha) {        actionBar.tvTitle.setVisibility(transAlpha > 48 ? View.VISIBLE : View.GONE);    }}

4.ActionBarClickListener

public interface ActionBarClickListener {    void onLeftClick();    void onRightClick();}

5.TranslucentActionBar

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 */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();                }            });        }    }}

6.actionbar_trans布局

<?xml version="1.0" encoding="utf-8"?>                                                                                                    

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

更多相关文章

  1. Android自定义Toast的时长、位置、及显示的View
  2. android 6.0锁屏界面时间位置修改
  3. android GridView(网格视图)
  4. android基础控件(4)GridView实现网格视图
  5. android 修改AVD的存放位置
  6. Android的Activity切换动画特效库SwitchLayout,视图切换动画库,媲
  7. Android中水波纹使用之自定义视图实现
  8. android控制显示和隐藏视图或控件的操作

随机推荐

  1. Android实现导航栏的左右滑动效果
  2. Cheatsheet: 2012 06.01 ~ 06.11
  3. Android——摇一摇
  4. 防止滑盖事件造成crash
  5. 【Android】 JNI入门 - NDK从入门到精通
  6. Android(安卓)原生项目集成React Native
  7. 短信监听,自动获短信取验证码
  8. Android(安卓)屏幕适配全攻略
  9. Android实现不同Active页面间的跳转
  10. 【MAC版】Android(安卓)ADB server didn'