近年来实习的时候需求本身做开辟模块,首若是参预支付宝支出和微信支付的。支付宝支出接入相对来讲比较好做,官方网站文书档案也相比便于懂。不过做微信支付的时候,官方网站文档就有一点点懵逼了,不过稳步读还是能够够开通的。与是抽时间记录一下微信支付接入的历程。这里本身不去表达AppID申请的长河,主要记录一下付出进程。

前言

率先请大家看几张图:

图片 1

上述的作用,一般大家统称为沉浸式状态栏。其实,这种叫法不是很确切,并且也未有沉浸式状态栏这一说,唯有沉浸格局。以上二种处境,能够称呼透明状态栏恐怕状态栏着色。

图片 2

率先分明要清楚微信支付业务流程,那样接下去就经济了。重要官方文档看这:

一、三种情况

扩充Android开辟时,有三种办法都会对景况栏进行安装:Translucent
Bar和Immersive
Mode。两个的界别,相比直观的有些,便是浮以后显示屏中的View可点击区域,如下所示。

  • 沐浴格局隐敝status bar,使荧屏全屏,让Activity接收全体的触摸事件。

  • 气象栏着色设置景况栏颜色,状态栏部分不抽取管理触摸事件。布局侵入状态栏的末端,必需启用fitsSystemWindows品质来调治布局才不至于被状态栏覆盖。如透明状态栏、与titlebar颜色一致的状态栏,即如从前的图所示。

  • Android开垦中,会时时存在 “一键退出App” 的需求
  • 但市情上流传着 太多不可用的“一键退出App”效用完结
  • 正文将周到总计“一键退出App”的落到实处方式,并为你各类实施,希望您们会欣赏。
  • 业务流程
  • 应用软件端开拓步骤
  • Android财富下载
  • API列表

二、如何沉浸

从3.x版本起始, 系统DecorView提供了setSystemUiVisibility方法,
能够经过Flag改更动所谓SystemUI的品质。各类设置的参数含义如下所示:

参数 api版本 含义
View.SYSTEM_UI_FLAG_VISIBLE 14 默认标记
View.SYSTEM_UI_FLAG_LOW_PROFILE 14 低功耗模式, 会隐藏状态栏图标, 在4.0上可以实现全屏
View.SYSTEM_UI_FLAG_LAYOUT_STABLE 16 保持整个View稳定, 常跟bar 悬浮, 隐藏共用, 使View不会因为SystemUI的变化而做layout
View.SYSTEM_UI_FLAG_FULLSCREEN 16 状态栏隐藏
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 16 状态栏上浮于Activity
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 14 隐藏导航栏
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 16 导航栏上浮于Activity
View.SYSTEM_UI_FLAG_IMMERSIVE 19 Kitkat新加入的Flag, 沉浸模式, 可以隐藏掉status跟navigation bar, 并且在第一次会弹泡提醒, 它会覆盖掉之前两个隐藏bar的标记, 并且在bar出现的位置滑动可以呼出bar
View.SYSTEM_UI_FLAG_IMMERSIVE_STIKY 19 与上面唯一的区别是, 呼出隐藏的bar后会自动再隐藏掉

归结,要落实全屏沉浸方式,只需如下设置就能够:

//HidegetWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STIKY);

落到实处沉浸效果如下图所示。左边是掩饰状态栏和导航栏的机能,整个显示屏都能够收起触摸反馈;左边图是滑动展现的状态栏和导航栏的成效,内容映未来系统栏的花花世界,呈现一段时间后会自动隐敝。

图片 3沐浴格局

图片 4示意图

业务流程如下:

三、怎么着着色

对此状态栏着色,有七个相当的重大的系统节点须要关怀,分别是4.4和5.0。基于七个系统节点,我们又有啥不可分成四个等第张开座谈。

  • 4.4在此之前状态栏不协理设置颜色。

  • 4.4 ~
    5.0景况栏帮忙透明效果,不过系统不提供接口进行颜色设置(有一点点子,小说前面会介绍)。

  • 5.0上述系统提供接口对气象栏实行肆意颜色设置。

一键退出 App 其实是 两个须要:

图片 5微信支付业务流程

3.2.1 主旨和布局设置
  1. 在values、values-v19、values-v21的style.xml都设置贰个 Translucent
    System Bar 风格的Theme

    • values/style.xml

    <style name="ImageTranslucentTheme" parent="AppTheme"> <!--在Android 4.4之前的版本上运行,直接跟随系统主题--></style>
    
    • values-v19/style.xml

     <style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">true</item></style> 
    
    • values-v21/style.xml

    <style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowTranslucentStatus">false</item> <item name="android:windowTranslucentNavigation">true</item> <item name="android:statusBarColor">@android:color/transparent</item></style>
    
  2. 在AndroidManifest.xml中对钦命Activity的theme举办安装

<activity android:name=".MainActivity" android:theme="@style/ImageTranslucentTheme" ></activity>
  1. 在Activity的布局文件中安装背景图片,同期,须求把android:fitsSystemWindows设置为true

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:andro xmlns:tools="http://schemas.android.com/tools" android: android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/paperscan_guide_step_two_inside" android:fitsSystemWindows="true" > <TextView android:text="透明状态栏~" android:textColor="@android:color/white" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>

那样能够获得效果如下所示

图片 6兑现透明效果的图

那正是说,为何要将android:fitsSystemWindows设置为true呢?要是不设置会什么?我们得以来测量试验下,下图是不安装的功效。可知内容跑到了状态栏的底下,被状态栏覆盖了。所以,最直观的少数大家得以窥见,设置了android:fitsSystemWindows为true,能够让内容不会顶到状态栏的底下。文章Android沉浸式状态栏达成对fitsSystemWindows早就做了详尽的深入分析,大家有意思味能够看看。

图片 7android:fitsSystemWindows为false的图

随即上边的标题,既然大家落到实处透明状态栏效能的页面都必要安装fitsSystemWindows本性,所以大家想到了一种便利的法子,在theme中增进如下的android:fitsSystemWindows设置:

<item name="android:fitsSystemWindows">true</item>

运作开掘确实能够,突显的内容也未曾和气象栏重叠。可是,当大家显示贰个toast的时候,开采难点了。

Toast.makeText(MainActivity.this,"toast sth...",Toast.LENGTH_SHORT).show();

图片 8toast错位的图样

如图所示,Toast打字与印刷出来的文字都发展偏移了。原因是因为大家是在Theme中装置的fitsSystemWindows属性,会潜移暗化使用了该theme的activity或application的行事,产生凭借于Application
Window的Window错位。针对Toast错位的标题,消除措施也简要,就是应用应用等第的上下文

Toast.makeText(getApplicationContext(),"toast sth...",Toast.LENGTH_SHORT).show();

虽说Toast错误难点也可能有主意能够消除,不过一旦这么使用,相当大心间会给大家的使用埋下大多坑。所以小编的建议是:不要滥用,只在有要求的地点增添fitsSystemWindows属性。

  1. 一键截至近期App所有的Activity
  2. 一键甘休近些日子App进程

此间作者差相当的少用本身的明亮把App顾客端的流水生产线分为四步

3.2.2 代码设置

正如前方提到的,唯有4.4之上的连串才支撑透明状态栏设置,5.0上述的系统援助设置境况栏大肆颜色。所以5.0以上的系统装置状态栏的颜色就很简短了,直接调用系统接口就足以了:

// 设置此flag才可对状态栏进行颜色设置activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);// 取消设置透明状态栏,不然颜色设置不生效activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);// 设置状态栏颜色activity.getWindow().setStatusBarColor;

而对此系统是4.4到5.0里头的电话机,要安装状态栏的颜色就多少要麻烦一点了。首先,须求设置页面状态栏为透明;然后,新建三个和气象栏中度一致的view,填充到DecorView上;最终,通过设置这一个填充view的颜料,大家就会落实类似对气象栏颜色举行调整的效应了。

// 设置透明activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);// 生成view填充DecorViewViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);if (fakeStatusBarView != null) { if (fakeStatusBarView.getVisibility() == View.GONE) { fakeStatusBarView.setVisibility(View.VISIBLE); } fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));} else { decorView.addView(createStatusBarView(activity, color, statusBarAlpha));}// 设置fitsSystemWindows属性setRootView;

在篇章的前尾部分,在系统4.4~5.0的对讲机上,怎样设置景况栏颜色的规律其实已经做了证实。正是在透明的情景栏下放置多个和景色栏大小同等的view,通过退换view的颜料来达成转移状态栏颜色的功力。那么,当在5.0及以上的对讲机,当大家经过如下代码设置意况栏颜色:

getWindow().setStatusBarColor;

实际上,这里调用的是PhoneWindow的setStatusBarColor方法,具体落到实处如下:

@Overridepublic void setStatusBarColor(int color) { mStatusBarColor = color; mForcedStatusBarColor = true; if (mDecor != null) { mDecor.updateColorViews(null, false /* animate */); }}

最终调用的是DecorView的updateColorViews函数,DecorView是属于Activity的PhoneWindow的个中对象,也就说,更新的靶子从所谓的Window进入到了Activity自己的布局视图中,接着看DecorView,这里只关注改动颜色。在措施updateColorViews中,调用了之类代码,代码达成的遵循便是修改意况栏颜色:

updateColorViewInt(mNavigationColorViewState, sysUiVisibility, mWindow.mNavigationBarColor, navBarSize, navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge, 0 /* sideInset */, animate && !disallowAnimate, false /* force */);

此地mStatusColorViewState其实就表示StatusBar的背景颜色对象,主要品质包含彰显的准则以及颜色值:

 private final ColorViewState mStatusColorViewState = new ColorViewState( SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS, Gravity.TOP, Gravity.LEFT, STATUS_BAR_BACKGROUND_TRANSITION_NAME, com.android.internal.R.id.statusBarBackground, FLAG_FULLSCREEN);

再来看updateColorViewInt方法:

private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color, int size, boolean verticalBar, boolean seascape, int sideMargin, boolean animate, boolean force) { // 关键点1 state.present = (sysUiVis & state.systemUiHideFlag) == 0 && (mWindow.getAttributes().flags & state.hideWindowFlag) == 0 && ((mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 || force); // 关键点2 boolean show = state.present && (color & Color.BLACK) != 0 && ((mWindow.getAttributes().flags & state.translucentFlag) == 0 || force); boolean showView = show && !isResizing() && size > 0; ... if (view == null) { if  { // 关键3 设置view的颜色 state.view = view = new View; view.setBackgroundColor; view.setTransitionName(state.transitionName); view.setId; visibilityChanged = true; view.setVisibility(INVISIBLE); state.targetVisibility = VISIBLE; LayoutParams lp = new LayoutParams(resolvedWidth, resolvedHeight, resolvedGravity); if  { lp.leftMargin = sideMargin; } else { lp.rightMargin = sideMargin; } addView; updateColorViewTranslations(); } } else { int vis = showView ? VISIBLE : INVISIBLE; visibilityChanged = state.targetVisibility != vis; state.targetVisibility = vis; LayoutParams lp = (LayoutParams) view.getLayoutParams(); int rightMargin = seascape ? 0 : sideMargin; int leftMargin = seascape ? sideMargin : 0; if (lp.height != resolvedHeight || lp.width != resolvedWidth || lp.gravity != resolvedGravity || lp.rightMargin != rightMargin || lp.leftMargin != leftMargin) { lp.height = resolvedHeight; lp.width = resolvedWidth; lp.gravity = resolvedGravity; lp.rightMargin = rightMargin; lp.leftMargin = leftMargin; view.setLayoutParams; } if  { view.setBackgroundColor; } } ...}

先看下关键点1,这里是基于SystemUI的布置决定是不是出示状态栏背景颜色。假诺事态栏都不显得,那就没必要展现背景观了。再看首要点2,假设意况栏显示,但背景是透明色,也没要求加多背景颜色,即不满足(color
& Color.BLACK) !=
0。然后,看一下translucentFlag,暗中认可境况下,状态栏背景观与translucent半透明效果互斥,半晶莹剔透就联合用半晶莹剔透颜色,不会再增多额外颜色。最终,再来看关键点3,其实很轻易,正是往DecorView上增加二个View,理论上DecorView也是一个FrameLayout,所以最终的兑现正是在FrameLayout加多三个有背景观的View。

即 供给2个步骤 才可 完结 一键退出 App
需求
。下边,小编将依附那多个步骤举办职能完结教学。

1、统一下单

四、100分意况栏着色实践

当下互连网封装好的情状栏设置工具备众多,用得比很多的是StatusBarUtil,还应该有已经丢掉的SystemBarTint。不过有个难点,无论哪个工具库,都不敢保障能够百分之百贯彻意况栏着色的效应。由此,包容性难点是平素存在的。通过施行剖判总计,包容性难题首要有两类:

  • 部分ROM(大繁多是4.4~5.0的对讲机)本身就是不帮助状态栏着色效果
  • 5.0上述的对讲机,不帮助常规操作方法,需求动用特别措施管理(4.4~5.0的管理情势)

当出现如上所述的难点时,大家的管理形式一般是这么(不入侵修改第三方库):

  1. 完结三个包容性工具类,获取本机消息,判定相关包容性难点
  2. 在专业代码中剖断包容性条件,分情状决断是还是不是设置情状栏颜色。帮忙状态栏设置的,还索要分情形决断使用哪一种方法设置。

if (RomUtil.isCompactSystemVersionForImmersion { if (RomUtil.isCompactRomForImmersion { StatusBarUtils.setColor(ActivityMain.this, Color.TRANSPARENT); } else { setTranslucentStatus; tintManager = new SystemBarTintManager; tintManager.setStatusBarTintEnabled; tintManager.setStatusBarTintColor(Color.TRANSPARENT);//通知栏所需颜色 }}

看下边实现,会意识代码逻辑很麻烦。况且当三个新的地点必要设置处境栏颜色时,相应的这一批代码都亟需再写三回。显著,这种艺术不是太友好,当然,大家得以将标准剖断都修改到Curry面,间接修改库源码。可是那又推动另贰个主题材料,当库有立异了,晋级库就很麻烦。

设想到上述的一部分难点,所以在我们统一筹算的库中,将包容性推断的相关细节遮盖在库中,使用的时候只需调用相关措施即可。库对外提供了包容性配置接口,客商可以任性安插,决定是还是不是须要安装情形栏颜色。即落实对库无侵入的退换,即便晋级了库,相应的兼容性配置信息也不会放任。整个库设计的UML图如下所示:

图片 9库设计的UML图

要选用库也极度轻便,只须要如下几步:

  • 在build.gradle中程导弹入库

compile 'com.zr.statusbarmanager:library:1.0.0-beta'
  • 年年有余ICompatConfig接口,重写方法完成包容性配置。接口首要提供了八个反省安排的艺术,分别如下所示:

 /** * 检测是否支持状态栏设置 * @return */boolean checkCompatiblity();/** * 检测是否需要特殊设置的Rom * @return */boolean checkSpecialRom();

上述的四个艺术,checkCompatiblity用来判断是不是帮忙设置境况栏颜色。借使回去false,则不会对情形栏设置颜色。checkSpecialRom在实际测验进程中,有一款国产手提式有线电话机,搭载EMUI
3.1系统,对应Android系统版本5.1。大家发掘用健康直接设置境况栏颜色的不二秘技设置是不奏效的,但是用5.0之下系统安装意况栏颜色方式设置就能够生效。所以,该格局正是为了此类特殊ROM而定义的。

当然库也提供了贰个默许的达成DefaultStatusBarCompatConfig,那也是我们在项目支出进度中遵照包容性测量检验开掘的一对主题材料开展的布局,相对很有参考价值。倘诺客户本人实现配置,只须要如下设置:

public class StatusBarCompactConfig implements ICompatConfig { @Override public boolean checkCompatiblity() { if (CompatUtil.checkCompatiblity { // TODO: 17/7/28 自定义的兼容性判断逻辑 } else { return false; } } @Override public boolean checkSpecialRom() { if (CompatUtil.checkSpecialRom { return true; } else { // TODO: 17/7/28 自定义特殊ROM判断逻辑 } }}

其中CompatUtil是库提供的包容性推断工具类,若客商在动用库的时候须要带上库已经提供的有关包容性音信,能够调用工具类的连带办法。借使没有要求,也得以完全自身达成。

  • 在Application中发轫化库的设置

StatusBarManager.getsInstance().init(new DefaultStatusBarCompatConfig;
  • 在页面中调用库方法设置情形栏颜色

StatusBarManager.getsInstance().setColor(MainActivity.this, Color.TRANSPARENT);

2.1 一键结束方今 App 全部 Activity

发表评论

电子邮件地址不会被公开。 必填项已用*标注