navigationbar

知识
刘斌老师 2019-07-17 16:56:49

  我们使用的大多数android手机上的Home键,返回键以及menu键都是实体触摸感应按键。如果你用Google的Nexus4或Nexus5话,你会发现它们并没有实体按键或触摸感应按键,取而代之的是在屏幕的下方加了一个小黑条,在这个黑条上有3个按钮控件,这种设置无疑使得手机的外观的设计更加简约。但我遇到身边用Nexus 4手机的人都吐槽这种设计,原因很简单:好端端的屏幕,被划出一块区域用来显示3个按钮(如下图所示):Back, Home, Recent。并且它一直用在那里占用着。

  在android源码中,那一块区域被叫做NavigationBar。同时,google在代码中也预留了标志,用来控制它的显示与隐藏。NavigationBar的显示与隐藏的控制是放在SystemU中的,具体的路径是:\frameworks\base\packages\SystemUI。对android4.0以上的手机而言,SystemUi包含两部分:StatusBar和NavigationBar。在SystemUI的工程下有一个类PhoneStatusBar.java,在该类中可以发现关于控制NavigationBar的相关代码:

  在start()方法里可以看到NavigationBar是在那时候被添加进来,但只是添加,决定它显示还是隐藏是在后面控制的。

  <span style="font-size:18px;">@Override
  public void start() {
  mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
  .getDefaultDisplay();
  updateDisplaySize();

  /// M: Support Smartbook Feature.
  if (SIMHelper.isMediatekSmartBookSupport()) {
  /// M: [ALPS01097705] Query the plug-in state as soon as possible.
  mIsDisplayDevice = SIMHelper.isSmartBookPluggedIn(mContext);
  Log.v(TAG, "start, mIsDisplayDevice=" + mIsDisplayDevice);
  }

  super.start(); // calls createAndAddWindows()

  addNavigationBar();

  // Lastly, call to the icon policy to install/update all the icons.
  mIconPolicy = new PhoneStatusBarPolicy(mContext);

  mHeadsUpObserver.onChange(true); // set up
  if (ENABLE_HEADS_UP) {
  mContext.getContentResolver().registerContentObserver(
  Settings.Global.getUriFor(SETTING_HEADS_UP), true,
  mHeadsUpObserver);
  }
  }</span>
  其中的addNavigationBar()具体的实现方法如下:

  <span style="font-size:18px;"> // For small-screen devices (read: phones) that lack hardware navigation buttons
  private void addNavigationBar() {
  if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
  if (mNavigationBarView == null) return;

  prepareNavigationBarView();

  mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
  }</span>
  可以看到Navigationbar实际上windowmanager向window窗口里添加一个view。在调用addNavigationBar()方法之前会回调start()的父方法super.start()来判断是否要添加NavigationBar。在super.start()的调用父类方法里会调用createAndAddWindows(),该方法内会判断是否需要添加显示NavigationBar,然后决定是否要实例化NavigationBarView.
  <span style="font-size:18px;">try {
  boolean showNav = mWindowManagerService.hasNavigationBar();
  if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav);
  if (showNav) {
  mNavigationBarView =
  (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);

  mNavigationBarView.setDisabledFlags(mDisabled);
  mNavigationBarView.setBar(this);
  }
  } catch (RemoteException ex) {
  // no window manager? good luck with that
  }</span>
  WindowManagerService类实现了WindowManagerPolicy的接口,所以WindowManagerService会回调WindowManagerPolicy 的hasNavigationBar()接口,

  <span style="font-size:18px;"> @Override
  public boolean hasNavigationBar() {
  return mPolicy.hasNavigationBar();
  }</span>

  Policy向下调用实际上调用的是PhoneWindowManager实现的hasNavigationBar方法,下面代码是PhoneWindowManager中的hasNavigationBar()方法。
  <span style="font-size:18px;">// Use this instead of checking config_showNavigationBar so that it can be consistently
  // overridden by qemu.hw.mainkeys in the emulator.
  public boolean hasNavigationBar() {
  return mHasNavigationBar;
  }</span>
  而mHasNavigationBar的赋值可以在PhoneWindowManager中的setInitialDisplaySize(Display display, int width, int height, int density)方法中找到,

  <span style="font-size:18px;"> if (!mHasSystemNavBar) {
  mHasNavigationBar = mContext.getResources().getBoolean(
  com.android.internal.R.bool.config_showNavigationBar);
  // Allow a system property to override this. Used by the emulator.
  // See also hasNavigationBar().
  String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
  if (! "".equals(navBarOverride)) {
  if (navBarOverride.equals("1")) mHasNavigationBar = false;
  else if (navBarOverride.equals("0")) mHasNavigationBar = true;
  }
  } else {
  mHasNavigationBar = false;
  }</span>
  从上面代码可以看到mHasNavigationBar的值的设定是由两处决定的:
  1.首先从系统的资源文件中取设定值config_showNavigationBar, 这个值的设定的文件路径是frameworks/base/core/res/res/values/config.xml
  <!-- Whether a software navigation bar should be shown. NOTE: in the future this may be
  autodetected from the Configuration. -->
  <bool name="config_showNavigationBar">false</bool>
  2.然后系统要获取“qemu.hw.mainkeys”的值,这个值可能会覆盖上面获取到的mHasNavigationBar的值。如果 “qemu.hw.mainkeys”获取的值不为空的话,不管值是true还是false,都要依据后面的情况来设定。
  所以上面的两处设定共同决定了NavigationBar的显示与隐藏。

#navigationbar#

返回顶部

影响力:417

UINavigationBar添加导航栏

描述: 项目中有两个控制器UITabBarController和UINavigationController,其中UITabBarController是跟控制器且有2个子控制器,现在其他页面需要用到UINavigationController的导航栏,但是用UI... 项目中有两个控制器UITabBarController和UINavigationController,其中UITabBarController是跟控制器且有2个子控制器,现在其他页面需要用到UINavigationController的导航栏,但是用UINavigationController就得把它设置为跟控制器,跟控制器只有一个,该怎么做? 展开
这个解答帮助过3353人

你能否达到这个目的的一种方法是使用背景图像并将其使用的 iOS 5.0 中引入的外观代理设置。 如果您创建了一个薄的垂直切片的图像 (例如宽度 1px 的和高度 44px 和增加了一倍了视网膜图像) 并将其添加到您的捆绑,然后您可以在您的应用程序一次

编辑时间 2019-01-13 12:12:02
影响力:553

怎样修改状态栏背景颜色和状态栏的字的

这个解答帮助过996人

  • 修改状态栏的字体颜色 (设置电池电量、时间、网络部分标示的颜色)

    调用[UIApplication sharedApplication]单例 在Info.plist(Build Setting 旁边这个)中添加View controller-based status bar appearance 并设置为NO 步骤二:在需要修改状态栏的ViewController 里面设置(根据需求修改状态栏的样式): [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; 或者 [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]

  • 添加的View controller-based status bar appearance是Bool类型,默认为Yes

  • 方法2:

    不做其它操作,直接设置 步骤一: 根据需求修改状态栏的样式 self.navigationController.navigationBar.barStyle = UIStatusBarStyleLightContent; 或者 self.navigationController.navigationBar.barStyle = UIStatusBarStyleDefault; 步骤二: 重新绘制状态栏 [self setNeedsStatusBarAppearanceUpdate];

  • 隐藏状态栏:

    步骤一: 调用[UIApplication sharedApplication]单例 在Info.plist(Build Setting 旁边这个)中添加View controller-based status bar appearance 并设置为NO 步骤二:设置状态栏的状态 [[UIApplication sharedApplication] setStatusBarHidden:YES]; 或者  [[UIApplication sharedApplication] setStatusBarHidden:NO]

  • 5

    修改状态栏的背景颜色

    /*改变状态栏的背景颜色,因为状态栏的层级比较高,所以按照如下添加就可以出来效果*/ UIView* stateView = [[UIView alloc] initWithFrame:CGRectMake(0, -20, SCREEN_WIDTH, 20)]; [self.navigationController.navigationBar addSubview:stateView]; stateView.backgroundColor = [UIColor redColor]

编辑时间 2019-02-17
影响力:2888

小程序开发有哪些坑

这个解答帮助过2952人

小程序开发有一下两种典型的“坑”

  1. 一键生成的模板小程序,后期无法二次开发,到时业务受阻或需要重新开发小程序

  2. 选择价格过低的开发公司,不提供售后服务,售后无门

希望对大家有帮助!

编辑时间 2019-12-06
影响力:7721

小程序标题的加载效果怎么做?

描述: 下图是美团外卖小程序,求大神解答... 下图是美团外卖小程序,求大神解答

这个解答帮助过4393人

  • 让用户更好的搜索到你的小程序。

  • 最好要包括行业的关键词。

编辑时间 2019-10-31
影响力:7033

微信小程序如何实现消息提示框

这个解答帮助过5735人

微信小程序开发中toast也是重要的消息提示方式.

提示框:
wx.showToast(OBJECT)

显示消息提示框
OBJECT参数说明:
示例代码:
?

12345

wx.showToast({ title:'成功', icon:'success', duration: 2000})

wx.hideToast()

隐藏消息提示框
?

123456789

wx.showToast({ title:'加载中', icon:'loading', duration: 10000}) setTimeout(function(){ wx.hideToast()},2000)

wx.showModal(OBJECT)

显示模态弹窗
OBJECT参数说明:
示例代码:
?

123456789

wx.showModal({ title:'提示', content:'这是一个模态弹窗', success:function(res) { if(res.confirm) { console.log('用户点击确定') } }})

wx.showActionSheet(OBJECT)

显示操作菜单
OBJECT参数说明:
success返回参数说明:
示例代码:
?

12345678

wx.showActionSheet({ itemList: ['A','B', 'C'], success:function(res) { if(!res.cancel) { console.log(res.tapIndex) } }})

设置导航条
<view>提示:{{tip}}</view>
<button type="default" bindtap="showModal">点击我弹出modal对话框</button>
<view>
<modal title="modal对话框" hidden="{{modalHidden}}" confirm-text="确定" cancel-text="取消"
bindconfirm="modalBindaconfirm" bindcancel="modalBindcancel">您好,我是modal对话框</modal>
</view>
Page({
data:{
// text:"这是一个页面"
tip:'',
buttonDisabled:false,
modalHidden:true,
show:false
},
showModal:function(){
this.setData({
modalHidden:!this.data.modalHidden
})
},
modalBindaconfirm:function(){
this.setData({
modalHidden:!this.data.modalHidden,
show:!this.data.show,
tip:'您点击了【确认】按钮!',
buttonDisabled:!this.data.buttonDisabled
})
},
modalBindcancel:function(){
this.setData({
modalHidden:!this.data.modalHidden,
tip:'您点击了【取消】按钮!'
})
}
})
wx.setNavigationBarTitle(OBJECT)

动态设置当前页面的标题。
OBJECT参数说明:
示例代码:
?

123

wx.setNavigationBarTitle({ title:'当前页面'})

wx.showNavigationBarLoading()

在当前页面显示导航条加载动画。
wx.hideNavigationBarLoading()

隐藏导航条加载动画。
页面跳转:
wx.navigateTo(OBJECT)

保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。
OBJECT参数说明:
示例代码:
?

123

wx.navigateTo({ url:'test?id=1'})

?

123456

//test.jsPage({ onLoad:function(option){ console.log(option.query) }})

注意:为了不让用户在使用小程序时造成困扰,我们规定页面路径只能是五层,请尽量避免多层级的交互方式。
wx.redirectTo(OBJECT)

关闭当前页面,跳转到应用内的某个页面。
OBJECT参数说明:
示例代码:
?

123

wx.redirectTo({ url:'test?id=1'})

wx.navigateBack(OBJECT)

关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages()) 获取当前的页面栈,决定需要返回几层。
OBJECT参数说明:
动画:
wx.createAnimation(OBJECT)

创建一个动画实例animation。调用实例的方法来描述动画。最后通过动画实例的export方法导出动画数据传递给组件的animation属性。
注意: export 方法每次调用后会清掉之前的动画操作
OBJECT参数说明:
?

123456

var animation = wx.createAnimation({ transformOrigin:"50% 50%", duration: 1000, timingFunction:"ease", delay: 0})

animation

动画实例可以调用以下方法来描述动画,调用结束后会返回自身,支持链式调用的写法。
样式:
旋转:
缩放:
偏移:
倾斜:
矩阵变形:
动画队列

调用动画操作方法后要调用 step() 来表示一组动画完成,可以在一组动画中调用任意多个动画方法,一组动画中的所有动画会同时开始,一组动画完成后才会进行下一组动画。step 可以传入一个跟 wx.createAnimation() 一样的配置参数用于指定当前组动画的配置。
示例:
?

1

<viewanimation="{{animationData}}"style="background:red;height:100rpx;width:100rpx"></view>

?

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

Page({ data: { animationData: {} }, onShow:function(){ varanimation = wx.createAnimation({ duration: 1000, timingFunction:'ease', }) this.animation = animation animation.scale(2,2).rotate(45).step() this.setData({ animationData:animation.export() }) setTimeout(function() { animation.translate(30).step() this.setData({ animationData:animation.export() }) }.bind(this), 1000) }, rotateAndScale:function () { // 旋转同时放大 this.animation.rotate(45).scale(2, 2).step() this.setData({ animationData:this.animation.export() }) }, rotateThenScale:function () { // 先旋转后放大 this.animation.rotate(45).step() this.animation.scale(2, 2).step() this.setData({ animationData:this.animation.export() }) }, rotateAndScaleThenTranslate:function () { // 先旋转同时放大,然后平移 this.animation.rotate(45).scale(2, 2).step() this.animation.translate(100, 100).step({ duration: 1000 }) this.setData({ animationData:this.animation.export() }) }})

wx.hideKeyboard()

收起键盘。

编辑时间 2019-08-16
影响力:7376

开发小程序前,需要注意的几个细节

这个解答帮助过7915人

小程序的开发注意事项:
1、js文件
每个页面对应的js文件可以定义页面onReady,onLoad,onShow,onHide,onUnload,还有页面的数据,自定义的函数要写到一块,内部约定是都写到默认函数的后面。既“页面中先data,再默认函数,再自定义函数”方便review code,提高协作效率。
2、json文件
默认不能为空,即使没有内容也要为空数据{},原先定义在app.json中的内容,如果需要在当前页面中重新定义,那么只要把内容复制过来,直接赋新值即可,用于设置小程序的状态栏、导航条、标题、窗口背景色。常用的是页面的标题
{ "navigationBarTitleText": "我的", "selfdata":"全栈工程师师不靠谱更新", "tabBar": { "list": [{ "pagePath": "pagePath", "text": "text", "iconPath": "iconPath", "selectedIconPath": "selectedIconPath" }], "position":"top" } }
见惯了菜单在底部的,来一个在top吧。
3、wxml文件
页面头部和底部需要封装好,做成模版,分别导入入页面
<import src="/pages/common/head.wxml"/> <import src="/pages/common/foot.wxml"/>
之前HTML编写的好习惯还是要带入进来有head还有foot,当然业务内容就body,每一块就用一个view包装起来,方便控制布局和class
页面加载的时候获取数据,从网络或从缓存中,数据再通过页面的data中定义的内容在页面渲染。具体的呈现列表、条件这些多多的使用。
4、wxss文件
@import "common.wxss";
公共样式、reset样式要根据不同项目提前管理好,不要使用px,不要使用px,不要使用px,重要的事情要说三遍,小程序为了保证兼容和自适应使用了新的单位rpx
5、要提供一个供用户清理本地缓存的按钮。相当于项目的reset开关,缓存数据、文件数据、授权数据这些可能要不同项目中用到。

编辑时间 2019-07-19