返回介绍

2.3 NavigationMenuAdapter

发布于 2024-12-23 21:21:14 字数 4220 浏览 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 是如何做的。

发布评论

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