SystenUI statusbar , qspanel 基本加载流程

主要代码:  com.android.systemui.qs 包下

一. 基本布局

1.0 super_status_bar.xml

    包括很多,其中有 include/status_bar.xml
                     include/status_bar_expand.xml  是2个最主要经常修改的
1.1 status_bar.xml

   status_bar.xml

   notification_lights_out                             id/status_bar_contents  
                                              |                                               |
					      |                                               |
		     id/notification_icon_area(左边,通知图标)                         id/system_icon_area(右边) 
	                (CollapsedStatusBarFragment中getView,            |                             |
			  add notification_icon_area.xml)                 |                             |
			                                                  |                          id/clcok (时间)       
							           include/system_icons.xml   
					         |                       |                        |
					         |                       |                        |
					   id/statusicon    include/signal_cluster_view.xml  id/battery(BatteryMeterView)
                          (网速,蓝牙,蓝牙、闹钟、耳机插入等)          (  信号)                   (电量百分比,电池图标)

1.2 status_bar_expand.xml

                                    NotificationPanelView.java    
				   
		 |                              |                                           |                                                   |
		
   include/keyguard_status_view   NotificationsQuickSettingsContainer          之前 include layou/status_bar_expand_header      include/keguard_button_area
                                  (id/notification_container_parent)           8.0 include layout/quick_status_bar_expand_header
    (锁屏时,大时间的显示)      (展开通知栏以后 QS + notification 的父布局)    (下拉状态栏之后, QSpanel顶部的所有部分)                 (锁屏后底部的区块)
     

                                  |               |                        |
			  id/QS_frame  NotificationStackScrollLayout.java  id/keyguard_status_bar   
		  layout/qs_palel.xml  id/notification_stack_scroller         (锁屏后的状态栏)
                                          (通知栏折叠下拉的通知部分)

二.  statusbar,qspanel 界面的加载流程

Statusbar.java {

    //比较重要的一些元素
    mBluetoothController, //蓝牙
    mLocationController,  //地址
    mRotationLockController,//自动旋转
    mNetworkController,   //数据开关
    mZenModeController,   //勿扰模式
    mHotspotController,   //热点
    mCastController,      //投射
    mFlashlightController,//手电筒
    mBatteryController,  // 电池管理
    mHotKnotController,  // 热点
    mRingController,    //铃声模式
    mNfcController     //NFC
    ....
    private StatusBarWindowManager mStatusBarWindowManager;   // 对mStatusBarWindow statusbar的管理
    private StatusBarWindowView    mStatusBarWindow;          // R.layout.super_status_bar
    private PhoneStatusBarView     mStatusBarView;
    private int mStatusBarWindowState = WINDOW_STATE_SHOWING; // statusbar 的状态标识符
    private IStatusBarService      mBarService;               // StatusBarManagerService 主要 registerStatusBar

    public void setQsExpand(boolean expand){
       mStatusBarWindowManager.setQsExpand(expand);
       .....
    }
    
    start(){
   
    }

    createAndAddWindows(){
   
    }

    addStatusBarWinodw(){
      makeStatusBarView();
      ...
      ...

      //***实际在 mStatusBarWindowManager 中的 windowManager.add()  ***//
      mStatusBarWindowManager.add( mStatusBarWindow , getStatusBarHeight());
    
    }

    makeStatusBarView(){
     
      // 加载StatusBarWindowView视图,该视图包括Status bar/Quick Settings/Notification Panel
      mStatusBarWindow = (StatusBarWindowView) View.inflate(context,R.layout.super_status_bar, null)
      // 监听OnTouch事件,当下拉时展开Notification Panel
      mStatusBarWindow.setOnTouchListener(......

      // 获取Status bar视图
      //old -- mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
      //8.0
      mStatusBarView = (PhoneStatusBarView)fragment.getView();
      mStatusBarView.setBar(this);

      // 实例化IStatusBarService
      mBarService = IStatusBarService.Stub.asInterface(
                ServiceManager.getService(Context.STATUS_BAR_SERVICE));

      // Connect in to the status bar manager service
      mCommandQueue = new CommandQueue(this); 
      try {
            // register后,
	    // StatusBar通过CommandQuene间接将自己注册到StatusBarManagerService,
	    // 而StatusBarManagerService会把操作状态栏和导航栏的请求通过CommandQuene再转发给StatusBar
	    // 
            mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders,
                    fullscreenStackBounds, dockedStackBounds);
       } catch (RemoteException ex) {
            // If the system process isn't there we're doomed anyway.
       }
       createAndAddWindows();

       .........
       很多其他的system ui 组件创建
       .........
 
   
     //主要就是 mStatusBarWindow(super_status_bar.xml)中的 status_bar_container 加载 CollapsedStatusBarFragment 
     //addTagListener 回调方法
     FragmentHostManager.get(mStatusBarWindow)
                .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
		    //在replace之后回调
                    CollapsedStatusBarFragment statusBarFragment =
                            (CollapsedStatusBarFragment) fragment;
                    statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
                    mStatusBarView = (PhoneStatusBarView) fragment.getView();
                    mStatusBarView.setBar(this);
                    mStatusBarView.setPanel(mNotificationPanel);
                    mStatusBarView.setScrimController(mScrimController);
                    setAreThereNotifications();
                    checkBarModes();
                }).getFragmentManager()
                .beginTransaction()

		//加载 CollapsedStatusBarFragment 
                .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
                        CollapsedStatusBarFragment.TAG)
                .commit();

		//**** 接下来看看CollapsedStatusBarFragment
		CollapsedStatusBarFragment.java{
		    oncreateView(){
			return inflate.inflate(R.layout.status_bar, container , null);
		    }

		    onViewCrewate(){
		       //对状态栏个状态,图标等进行初始化
		    }

		}****//


     .....
     .....

     //set up quick settings tile panel
     //下拉栏的总区域
     View container = mStatusBarWindow.findViewbyID(R.id.qs_frame);
     if (container != null) {
       // (可以搜索关键字 QSHost)获取默认显示的快捷按钮,并添加到qsh对象的mTiles变量中,createQSTileHost 方法
       final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,..
	       //***
	       走到
	       QSTileHost.java{ 的初始化方法中
	       
		  public QSTileHost(){

		    Dependecy.get(TunerService.class).addTunable();

		    //****** 然后走到 TunerServiceImpl addTunable ******//
		    TunerServiceImpl.java{

		       private void addTunable(Tunable tunable, String key) {
		       // 回调到QSTileHost,key = sysui_qs_tiles
		       tunable.onTuningChanged(key, value);
		     }
		   }
		   //****** ****** ******//
		  }


		  @Override
		  public void onTuningChanged(String key, String newValue) {
		     ...
		     // 返回分割好的QSTile名字list
		     final List<String> tileSpecs = loadTileSpecs(mContext, newValue); 
		     ...
		     // 根据名字创建具体的QSTile, 然后回调用QSFactoryI
		     tile = createTile(tileSpec); 
		     //createTile 实际最后走到了  
		     //**********
		     QSFactoryImpl.java{
		      public QSTile<?> createTile(String tileSpec) {
				if (tileSpec.equals("wifi")) return new WifiTile(this);
				else if (tileSpec.equals("bt")) return new BluetoothTile(this);
				else if (tileSpec.equals("cell")) return new CellularTile(this);
				else if (tileSpec.equals("dnd")) return new DndTile(this);
				else if (tileSpec.equals("inversion")) return new ColorInversionTile(this);
				else if (tileSpec.equals("airplane")) return new AirplaneModeTile(this);
				...
				...
		     }
		     *****//
		  }
	         }
	       }

	       ***/
      
       //将对象 qsh 放入,从qsh对象获取mTiles中保存的所有默认显示的快捷按钮并且添加到布局中显示
       //进行具体的add view方法
       ((QSFragment)f).setHost(qsh);
        
	QSFragment //qs_panel.xml

        QSFragment.setHost --> QSPanel: setHost --> setTitles --> addTile   去把所有的 title add上
     }
   }
}

 QSPanel.java

 

QSPanel.java{

   public QSPanel(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		setOrientation(VERTICAL);
		mBrightnessView = LayoutInflater.from(context).inflate(
			R.layout.quick_settings_brightness_dialog, this, false);
		//调节亮度
		addView(mBrightnessView); 
                //加载mTileLayout对应的布局
		setupTileLayout(); 
		mPageIndicator = LayoutInflater.from(context).inflate(
			R.layout.mTileLayoutqs_page_indicator, this, false);
		addView(mPageIndicator);
                // 快捷栏一页显示不全,添加滑动显示的标识圆点
		if (mTileLayout instanceof PagedTileLayout) {
		    ((PagedTileLayout) mTileLayout).setPageIndicator((PageIndicator) mPageIndicator);
		}  

		addDivider();  // 分割线

		mFooter = new QSSecurityFooter(this, context);
		addView(mFooter.getView());  // 底部编辑

		updateResources();
		mBrightnessController = new BrightnessController(getContext(),
			findViewById(R.id.brightness_icon),
			findViewById(R.id.brightness_slider));
   }

  /**
   *  collapsedView = false 展开显示全部快捷键
   *  collapsedView = true 收起 显示5个快捷键
   */
   public void setTiles(Collection> tiles, boolean collapsedView) { }

   protected void addTile(final QSTile<?> tile, boolean collapsedView) {
        final TileRecord r = new TileRecord();
        r.tile = tile;
        r.tileView = createTileView(tile, collapsedView);
        final QSTile.Callback callback = new QSTile.Callback() {
		 //一些 QSTile的回调方法
		 public void onStateChanged(QSTile.State state) 
		 public void onShowDetail(boolean show) 
		 public void onToggleStateChanged(boolean state) 
		 public void onScanStateChanged(boolean state) 
        }
	r.tile.addCallback(callback);
        r.callback = callback;
	//为每个快捷键添加点击+长按
        r.tileView.init(click, longClick);
        r.tile.refreshState();
        mRecords.add(r);

        //将刚创建的快捷键添加到可滑动页面板区,即可显示在下拉通知栏中
        //mTileLayout(PagedTileLayout)是QSPanel的child,
        if (mTileLayout != null) {
            mTileLayout.addTile(r);
        }
	
        PagedTileLayout.java extends ViewPager implements QSTileLayout,TunserService.Tunable{

	    @Override
	    public void addTile(TileRecord tile) {
		mTiles.add(tile);
		postDistributeTiles();
	    }

	    private void postDistributeTiles() {
		removeCallbacks(mDistribute);
		post(mDistribute);
	    }

	    private final Runnable mDistribute = new Runnable() {
		@Override
		public void run() {
		    distributeTiles();
		}
	    };

	    private void distributeTiles() {
		final int NP = mPages.size();
		for (int i = 0; i < NP; i++) {
		    mPages.get(i).removeAllViews();
		}
		int index = 0;
		final int NT = mTiles.size();
		for (int i = 0; i < NT; i++) {
		    TileRecord tile = mTiles.get(i);
		    if (mPages.get(index).isFull()) {
			if (++index == mPages.size()) {
			    if (DEBUG) Log.d(TAG, "Adding page for "
				    + tile.tile.getClass().getSimpleName());
			    // list数据集添加 TilePage
			    mPages.add((TilePage) LayoutInflater.from(mContext)
				    .inflate(R.layout.qs_paged_page, this, false));
		            
				    //******  TilePage.java , PagedTileLayout 的每一页 ******

				    public static class TilePage extends TileLayout {
				      //add 每一个子项
				      public void addTile(TileRecord tile) {
					mRecords.add(tile);
					tile.tile.setListening(this, mListening);
					addView(tile.tileView); // 加载tile视图
				      }
				  
				      public boolean updateResources(){
					 //3 * 3 布局各种修改
					 //4 * 3 布局各种修改
				      }
				    }
				    ****/
			}
		    }
		    // add tile,给adapter的数据mPages 添加数据
		    mPages.get(index).addTile(tile); 
		}
		if (mNumPages != index + 1) {
		    mNumPages = index + 1;
		    while (mPages.size() > mNumPages) {
			mPages.remove(mPages.size() - 1);
		    }
		    mPageIndicator.setNumPages(mNumPages);
		    mDecorGroup.setVisibility(mNumPages > 1 ? View.VISIBLE : View.GONE);
		    //设置adapter
		    setAdapter(mAdapter);
		    //刷新显示
		    mAdapter.notifyDataSetChanged();
		    setCurrentItem(0, false);
		}
	    }
	} 
  }
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空白的泡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值