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

Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩效果,第1张

概述闲话不多说,直接上图。给大家讲讲我的编程思想吧。第一部分:沉浸状态栏(API-Level19,Android4.4KitKat之后加入的东西),而且在Api-Level21版本中新增了一个属性(下面会说到)。所以,style文件应该声明三份

闲话不多说,直接上图。

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

第一部分:沉浸式状态栏(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:[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的代码

<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.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"          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"        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"          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:[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,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顶部伸缩效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1143423.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存