Material Design Library源码分析--NavigationView
avigationView集成自FrameLayout,就是一样简单的容器,其内部会使用一个listView来显示列表项。
public class NavigationView extends ScrimInsetsFrameLayout
看看NavigationView的几个private field
private final MenuBuilder mMenu;
private final NavigationMenuPresenter mPresenter;
private NavigationView.OnNavigationItemSelectedListener mListener;
MenuBuilder其实是继承自Menu,可以直接从menu资源中加载我们自定义的菜单,用来显示在listView中。可以这么理解,menu这里充当了listView的model,这样我们就可以方便的使用xml来自定义listView中显示的数据和样式,listView的adapter会从menu中读取要显示的数据。下面的代码就是来自NavigationView构造函数,使用LayoutInflator来将xml中的数据读取到menu中。
this.inflateMenu(a.getResourceId(styleable.NavigationView_menu, 0));
this.getMenuInflater().inflate(resId, this.mMenu);
NavigationMenuPresenter,看到presenter是不是很熟悉,没错,就是MVP,看来MVP在Android中势不可挡啊,Google已经开始使用了。 在这里,NavigationView将创建子view的任务完全委托给了presenter。
this.mPresenter = new NavigationMenuPresenter();
this.mPresenter.setId(1);
this.mPresenter.initForMenu(context, this.mMenu);
this.mPresenter.setItemIconTintList(itemIconTint);
this.mPresenter.setItemTextColor(itemTextColor);
this.mPresenter.setItemBackground(itemBackground);
this.mMenu.addMenuPresenter(this.mPresenter);
this.addView((View)this.mPresenter.getMenuView(this));
NavigationMenuPresenter里面所做的事情就是给mMenu这个listView对象创建一个adapter。
public MenuView getMenuView(ViewGroup root) {
if(this.mMenuView == null) {
this.mMenuView = (NavigationMenuView)this.mLayoutInflater.inflate(layout.design_navigation_menu, root, false);
if(this.mAdapter == null) {
this.mAdapter = new NavigationMenuPresenter.NavigationMenuAdapter();
}
this.mHeader = (LinearLayout)this.mLayoutInflater.inflate(layout.design_navigation_item_header, this.mMenuView, false);
this.mMenuView.addHeaderView(this.mHeader);
this.mMenuView.setAdapter(this.mAdapter);
this.mMenuView.setOnItemClickListener(this);
}
return this.mMenuView;
}
NavigationView整体分析下来感觉就是这也忒简单了吧。其实仔细想想还是有两个点很值得我学习的。 1.NavigationView其实和我以前自己写的思路也是差不多,都是使用listView来显示。自己也尝试过做成一个通用的模式,但是每次都要在代码里去生成数据,也尝试使用过xml定义,但是使用普通的string资源很难去定义类似subMenu这种。 Google这里就给出了一个很好的思路,既然Android已经提供了Menu这个类,并且Menu可以使用xml来定义,xml中还可以定义subMenu,为啥不使用Menu来定义我们的侧边栏呢? 2.MVP的确挺适合Android的,使用MVP之后,可以使view变得简单很多。