如何Android中自定义Navigationbar

在如何控制android系统中NavigationBar 的显示与隐藏文章里简要地介绍了Navigationbar的背景知识,

NavigationBar的代码是放在... rameworksasepackagesSystemUI路径下面的。该路径下的工程主要负责手机中系统级UI的显示部分,如下图框中选中部分(包含其中的通知栏的显示),USB的连接,截屏等等。

\

NavigationBar的创建

navigationbar 的代码是在SystemUI工程SystemUI/src/com/android/systemui/statusbar/phone的路径下,其中navigationbar是由PhoneStatusBar.java类创建的。在该类的makeStatusBarView()方法下,可以看到创建Navigationbar的过程:

 

01. try {
02. boolean showNav = mWindowManagerService.hasNavigationBar();
03. /// M: Support Smartbook Feature.
04. if (true) Log.v(TAG, "hasNavigationBar=" + showNav);
05. if (showNav) {
06. mNavigationBarView =
07. (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
08.  
09. mNavigationBarView.setDisabledFlags(mDisabled);
10. mNavigationBarView.setBar(this);
11. mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
12. @Override
13. public boolean onTouch(View v, MotionEvent event) {
14. checkUserAutohide(v, event);
15. return false;
16. }});
17. }
18. } catch (RemoteException ex) {
19. // no window manager? good luck with that
20. }
WindowManagerService通过判断是否需要显示NavigationBar来决定是否需要创建NavigationBarView, NavigationBarView即为我们看到视图的view了,navigation_bar即为NavigationBarView实例化的layout,你可以在SystemUI工程下的layout文件夹下找到。

 

通过修改navigation_bar布局的方式来自定义NavigationBar的UI。在该layout文件中有这样一个类。com.android.systemui.statusbar.policy.KeyButtonView,它是系统定义的在NavigationBar上的按钮类(后面会讲到),点击会产生波纹的效果。

NavigationBarView主负责UI的初始化工作,实例化布局,根据屏幕方向先取正确的图片。

NavigationBar按钮的事件绑定

NavigationBar按钮上的事件绑定并不是在NavigationBarView里实现,而是在SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java类中完成的。

通过NavigationBarView对外提供的获取按钮接口来完成按钮的绑定:

Recent, Home, SearchLight按钮事件的绑定

 

01. private void prepareNavigationBarView() {
02. mNavigationBarView.reorient();
03.  
04. mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
05. mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
06. mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
07. mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
08. updateSearchPanel();
09. }

 

Menu, Home, Back按钮事件的绑定:

 

上面三个按钮都是KeyButtonView类,它们的事件响应过程都是在类本身里面完成的。它们通过onTouchEvent()方法来响应点击事件,

 

01. public boolean onTouchEvent(MotionEvent ev) {
02. final int action = ev.getAction();
03. int x, y;
04.  
05. switch (action) {
06. case MotionEvent.ACTION_DOWN:
07. //Slog.d("KeyButtonView", "press");
08. mDownTime = SystemClock.uptimeMillis();
09. setPressed(true);
10. if (mCode != 0) {
11. sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
12. } else {
13. // Provide the same haptic feedback that the system offers for virtual keys.
14. performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
15. }
16. if (mSupportsLongpress) {
17. removeCallbacks(mCheckLongPress);
18. postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
19. }
20. break;
21. case MotionEvent.ACTION_MOVE:
22. x = (int)ev.getX();
23. y = (int)ev.getY();
24. setPressed(x >= -mTouchSlop
25. && x < getWidth() + mTouchSlop
26. && y >= -mTouchSlop
27. && y < getHeight() + mTouchSlop);
28. break;
29. case MotionEvent.ACTION_CANCEL:
30. setPressed(false);
31. if (mCode != 0) {
32. sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
33. }
34. if (mSupportsLongpress) {
35. removeCallbacks(mCheckLongPress);
36. }
37. break;
38. case MotionEvent.ACTION_UP:
39. final boolean doIt = isPressed();
40. setPressed(false);
41. if (mCode != 0) {
42. if (doIt) {
43. sendEvent(KeyEvent.ACTION_UP, 0);
44. sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
45. playSoundEffect(SoundEffectConstants.CLICK);
46. } else {
47. sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
48. }
49. } else {
50. // no key code, just a regular ImageView
51. if (doIt) {
52. performClick();
53. }
54. }
55. if (mSupportsLongpress) {
56. removeCallbacks(mCheckLongPress);
57. }
58. break;
59. }
60.  
61. return true;
62. }

mCode是用来判断该触摸是来自于哪个button,表示不同button的keycode在KeyEvent中类都有定义。该值在布局文件中通过获取navigationbar_view中的systemui:keycode属性来获得,下面是layout布局文件中back相应代码段:

 

 

01. <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
02. android:layout_width="@dimen/navigation_key_width"
03. android:layout_height="match_parent"
04. android:src="@drawable/ic_sysbar_back"
05. systemui:keyCode="4"
06. android:layout_weight="0"
07. android:scaleType="center"
08. systemui:glowBackground="@drawable/ic_sysbar_highlight"
09. android:contentDescription="@string/accessibility_back"
10. />

在onTouch中方法通过sendEvent()方法来执行不同的keycode响应事件,该方法会创建一个包含keycode的KeyEvent对象封装,然后通过injectInputEvent()向InputManager插入一个事件,再发送出去。


http://www.it165.net/pro/html/201503/35530.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在iOS,可以通过以下方式自定义NavigationBar: 1. 设置NavigationBar的背景色和透明度 ```swift // 设置NavigationBar的背景色 navigationController?.navigationBar.barTintColor = UIColor.red // 设置NavigationBar的透明度 navigationController?.navigationBar.isTranslucent = true ``` 2. 设置NavigationBar的标题和字体样式 ```swift // 设置NavigationBar的标题 navigationItem.title = "Custom Title" // 设置NavigationBar的字体样式 navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 18), NSAttributedString.Key.foregroundColor: UIColor.white] ``` 3. 设置NavigationBar的返回按钮和图片 ```swift // 设置NavigationBar的返回按钮 let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) navigationItem.backBarButtonItem = backButton // 设置NavigationBar的返回图片 let backImage = UIImage(named: "back") navigationController?.navigationBar.backIndicatorImage = backImage navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage ``` 4. 隐藏NavigationBar ```swift // 隐藏NavigationBar navigationController?.navigationBar.isHidden = true ``` 5. 自定义NavigationBar的左右按钮 ```swift // 自定义NavigationBar的左按钮 let leftButton = UIBarButtonItem(title: "Left", style: .plain, target: self, action: #selector(leftButtonTapped)) navigationItem.leftBarButtonItem = leftButton // 自定义NavigationBar的右按钮 let rightButton = UIBarButtonItem(title: "Right", style: .plain, target: self, action: #selector(rightButtonTapped)) navigationItem.rightBarButtonItem = rightButton // 左按钮点击事件 @objc func leftButtonTapped() { // do something } // 右按钮点击事件 @objc func rightButtonTapped() { // do something } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值