返回介绍

2.1 寻找 RecyclerView

发布于 2024-12-23 21:21:14 字数 2961 浏览 0 评论 0 收藏 0

那么,既然我们已经清楚 NavigationView 内部其实就是 RecyclerView 实现了,那么接下来看源码的过程,就可以有针对有目的的去阅读了。

首先看 NavigationView 的构造方法:

#NavigationView
public class NavigationView extends ScrimInsetsFrameLayout {
  private final NavigationMenu mMenu;
  private final NavigationMenuPresenter mPresenter = new NavigationMenuPresenter();

  private OnNavigationItemSelectedListener mListener;
  private int mMaxWidth;

  private MenuInflater mMenuInflater;

  
  public NavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    ThemeUtils.checkAppCompatTheme(context);

    // Create the menu
    mMenu = new NavigationMenu(context);

    //省略了获取部分自定义属性的代码
    
    mMenu.setCallback(new MenuBuilder.Callback() {
      @Override
      public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
        return mListener != null && mListener.onNavigationItemSelected(item);
      }

      @Override
      public void onMenuModeChange(MenuBuilder menu) {}
    });
    mPresenter.setId(PRESENTER_NAVIGATION_VIEW_ID);
    mPresenter.initForMenu(context, mMenu);
    mPresenter.setItemIconTintList(itemIconTint);
    if (textAppearanceSet) {
      mPresenter.setItemTextAppearance(textAppearance);
    }
    mPresenter.setItemTextColor(itemTextColor);
    mPresenter.setItemBackground(itemBackground);
    mMenu.addMenuPresenter(mPresenter);
    addView((View) mPresenter.getMenuView(this));

    if (a.hasValue(R.styleable.NavigationView_menu)) {
      inflateMenu(a.getResourceId(R.styleable.NavigationView_menu, 0));
    }

    if (a.hasValue(R.styleable.NavigationView_headerLayout)) {
      inflateHeaderView(a.getResourceId(R.styleable.NavigationView_headerLayout, 0));
    }

    a.recycle();
  }

NavigationView 是继承自 FrameLayout 的,首先我们看起构造方法,因为我们刚才已经预先说明其内部是 RecyclerView 实现的,那么我们首先定位在哪里加入的 RecyclerView .

关注到上述代码的 39 行:

addView((View) mPresenter.getMenuView(this));

这里添加了一个 view,调用是 mPresenter.getMenuView ,源码更进去,可以看到

#NavigationMenuPresenter
@Override
public MenuView getMenuView(ViewGroup root) {
  if (mMenuView == null) {
    mMenuView = (NavigationMenuView) mLayoutInflater.inflate(
        R.layout.design_navigation_menu, root, false);
    if (mAdapter == null) {
      mAdapter = new NavigationMenuAdapter();
    }
    mHeaderLayout = (LinearLayout) mLayoutInflater
        .inflate(R.layout.design_navigation_item_header,
            mMenuView, false);
    mMenuView.setAdapter(mAdapter);
  }
  return mMenuView;
}

这个方法返回值是 NavigationMenuView ,而这个类实际上继承自 RecyclerView 。除此以外呢,可以看到这里还初始化了 NavigationMenuAdapter ,并且调用了 setAdapter() ;以及初始化了 mHeaderLayout 。顾名思义,adapter 肯定是为 RecyclerView 准备的,而 mHeaderLayout 肯定是用于放置我们设置的 app:headerLayout .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文