返回介绍

2.3 NavigationMenuAdapter

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

因为我们涉及到多个 item type,所以重点看三个方法,分别为: getItemViewTypeonCreateViewHolder , onBindViewHolder

  • getItemViewType
#NavigationMenuPresenter.NavigationMenuAdapter
@Override
public int getItemViewType(int position) {
  NavigationMenuItem item = mItems.get(position);
  if (item instanceof NavigationMenuSeparatorItem) {
    return VIEW_TYPE_SEPARATOR;
  } else if (item instanceof NavigationMenuHeaderItem) {
    return VIEW_TYPE_HEADER;
  } else if (item instanceof NavigationMenuTextItem) {
    NavigationMenuTextItem textItem = (NavigationMenuTextItem) item;
    if (textItem.getMenuItem().hasSubMenu()) {
      return VIEW_TYPE_SUBHEADER;
    } else {
      return VIEW_TYPE_NORMAL;
    }
  }
  throw new RuntimeException("Unknown item type.");
}

根据 item 的类型去决定 ItemViewType,那么我们上面已经进行了详细的分析,一种有 3 种 item 类型,其中 NavigationMenuTextItem 分为 hasSubMenu() 为 true,false 两种情况。刚好对应上述代码。

  • onCreateViewHolder
#NavigationMenuPresenter.NavigationMenuAdapter
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  switch (viewType) {
    case VIEW_TYPE_NORMAL:
      return new NormalViewHolder(mLayoutInflater, parent, mOnClickListener);
    case VIEW_TYPE_SUBHEADER:
      return new SubheaderViewHolder(mLayoutInflater, parent);
    case VIEW_TYPE_SEPARATOR:
      return new SeparatorViewHolder(mLayoutInflater, parent);
    case VIEW_TYPE_HEADER:
      return new HeaderViewHolder(mHeaderLayout);
  }
  return null;
}

根据不同的 itemViewType,返回不同的 ViewHolder,每个 viewholder 也对应一个布局文件,分别为:

  • SubheaderViewHolder 对应的布局文件为一个 TextView
  • SeparatorViewHolder 对应一个 FrameLayout,其内部是 height=1dp 的 View
  • HeaderViewHolder 对应 mHeaderLayout,其实就是 LinearLayout 包裹我们设置的 headerLayout
  • NormalViewHolder 这个对应于一个 NavigationMenuItemView

那么大概知道每个 itemViewType 对应的布局文件之后,就可以看 onBindViewHolder 了

  • onBindViewHolder
@Override
#NavigationMenuPresenter.NavigationMenuAdapter
public void onBindViewHolder(ViewHolder holder, int position) {
  switch (getItemViewType(position)) {
    case VIEW_TYPE_NORMAL: {
      NavigationMenuItemView itemView = (NavigationMenuItemView) holder.itemView;
      itemView.setIconTintList(mIconTintList);
      if (mTextAppearanceSet) {
        itemView.setTextAppearance(itemView.getContext(), mTextAppearance);
      }
      if (mTextColor != null) {
        itemView.setTextColor(mTextColor);
      }
      itemView.setBackgroundDrawable(mItemBackground != null ?
          mItemBackground.getConstantState().newDrawable() : null);
      NavigationMenuTextItem item = (NavigationMenuTextItem) mItems.get(position);
      itemView.initialize(item.getMenuItem(), 0);
      break;
    }
    case VIEW_TYPE_SUBHEADER: {
      TextView subHeader = (TextView) holder.itemView;
      NavigationMenuTextItem item = (NavigationMenuTextItem) mItems.get(position);
      subHeader.setText(item.getMenuItem().getTitle());
      break;
    }
    case VIEW_TYPE_SEPARATOR: {
      NavigationMenuSeparatorItem item =
          (NavigationMenuSeparatorItem) mItems.get(position);
      holder.itemView.setPadding(0, item.getPaddingTop(), 0,
          item.getPaddingBottom());
      break;
    }
    case VIEW_TYPE_HEADER: {
      break;
    }
  }

}

恩,这里主要就是为 4 中 itemTypeView 所对应的 item 进行控件的赋值了,从简单到难来看:

  • VIEW_TYPE_HEADER 什么都不管,只要把我们设置的 headerLayout 显示即可
  • VIEW_TYPE_SEPARATOR 首先拿到 NavigationMenuSeparatorItem ,主要是为了拿到 padding 的值,然后调用 holder.itemView 设置上下的 padding,这个 padding 默认值为 8dp。
  • VIEW_TYPE_SUBHEADER 拿到 TextView 设置下 title 即可。
  • VIEW_TYPE_NORMAL

最后这个呢,对应 NavigationMenuItemView ,通过它呢去设置字体,图标,字体颜色,图标颜色,以及根据 item.getMenuItem 设置各种状态。

那么到这里呢,我们就学习完成了 NavigationMenuAdapter 它的内部的处理,那么我们的 NavigationView 已经能够正常的显示了。

显示完了之后,还有个问题, NavigationView 的 Item 是可以点击了,如果大家有印象的话, RecyclerView 自身是没有提供 Item 点击的回调的,那么 NavigationView 是如何做的。

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

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

发布评论

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