大佬教程收集整理的这篇文章主要介绍了Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩效果,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
闲话不多说,直接上图。
给大家讲讲我的编程思想吧。
第一部分:沉浸式状态栏(API-Level 19,Android4.4 KitKat 之后加入的东西),而且在Api-Level 21版本中新增了一个属性(下面会说到)。所以,style文件应该声明三份。
values
<style name="TranslucentTheme" parent="@style/AppTheme"> </style>
values-19
<style name="TranslucentTheme" parent="@style/AppTheme"> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">false</item> </style>
values-V21
<style name="TranslucentTheme" parent="@style/AppTheme"> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">false</item> <!-- v-21 中新增的属性 --> <item name="android:statusBarColor">@android:color/transparent</item> </style>
至于以上属性的含义及使用方式,就不多做解释了。详细可参见 https://www.oudahe.com/p/26557/
第二部分:actionBar渐变
因为要实现actionBar渐变,所以我没有使用系统的actionBar。而是自定义了一个继承自LinearLayout的ViewGroup。
直接给各位看代码
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(); } }); } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://scheR_264_11845@as.android.com/apk/res/android" android:id="@+id/lay_transroot" android:layout_width="match_parent" android:layout_height="wrap_content" android:BACkground="@color/colorPriMary" android:orientation="vertical"> <View android:id="@+id/v_statusbar" android:layout_width="match_parent" android:layout_height="1.0dp" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="45dp" android:orientation="vertical"> <RelativeLayout android:id="@+id/lay_actionbar_left" android:layout_width="100dp" android:layout_height="match_parent" android:orientation="horizontal"> <ImageView android:id="@+id/iv_actionbar_left" android:layout_width="20dp" android:layout_height="20dp" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:BACkground="@mipmap/ic_left_light" android:visibility="gone" /> <TextView android:id="@+id/tv_actionbar_left" style="@style/text_white" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:layout_toRightOf="@+id/iv_actionbar_left" android:gravity="center_vertical" android:maxLength="2" android:singleLine="true" android:text="返回" android:visibility="gone" /> </RelativeLayout> <TextView android:id="@+id/tv_actionbar_title" style="@style/text_white" android:layout_centerInParent="true" android:text="标题" android:textSize="16sp" /> <RelativeLayout android:id="@+id/lay_actionbar_right" android:layout_width="100dp" android:layout_height="match_parent" android:layout_alignParentright="true" android:gravity="right" android:orientation="horizontal"> <View android:id="@+id/v_actionbar_right" android:layout_width="20dp" android:layout_height="20dp" android:layout_alignParentright="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:visibility="gone" /> <TextView android:id="@+id/tv_actionbar_right" style="@style/text_white" android:layout_height="match_parent" android:layout_marginRight="10dp" android:layout_toLeftOf="@+id/v_actionbar_right" android:gravity="center_vertical|right" android:singleLine="true" android:visibility="gone" /> </RelativeLayout> </RelativeLayout> </LinearLayout>
这里我即没有用到 android:fitsSystemWindows="true" 属性,也没有用到 StatusBarUtils ,因为我发现使用的时候很容易造成兼容问题。
所以,我的做法是声明了一个高度为0.0dp的 statusbar,背景为透明,然后获取状态栏高度并赋值到它上,来实现兼容。事实证明,这样做的兼容效果最好。
/** * 获取状态栏高度 * * @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高度:
/** * 设置状态栏高度 * * @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); } }
第三步:实现ScrollView顶部伸缩
到了这里,必须得说一下,因为是个人项目中用到,所以并没有把功能做的很强大,本人都是以最简单、有效的方式实现的。所以,代码并不像gitHub上那些被下载很多次的开源项目一样,有很高的扩展性。
时间关系,我直接贴代码吧,代码里我都写了注释的。
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; //渐变开始@L_673_30@认位置,Y轴,50dp private final int DFT_TRANSSTARTY = 50; //渐变结束@L_673_30@认位置,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,attrs); } public TranslucentScrollView(Context context,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),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); } }
总结
以上所述是小编给大家介绍的Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
以上是大佬教程为你收集整理的Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩效果全部内容,希望文章能够帮你解决Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩效果所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。