Android RecyclerView动态更新多个视图类型
我试图弄清楚异构回收视图是如何工作的,并根据我的需要进行调整。我有3个Android RecyclerView动态更新多个视图类型,android,android-recyclerview,recyclerview-layout,Android,Android Recyclerview,Recyclerview Layout,我试图弄清楚异构回收视图是如何工作的,并根据我的需要进行调整。我有3个布局。第一个是带有底部条的标题(在本例中不在底部),并且始终显示该标题。其他2个布局将根据单击底部栏中的哪个选项卡进行切换。底部栏中的第一个选项卡将显示网格布局,第二个选项卡应显示列表布局。我已经设法实现了它,但有一个轻微的轻弹和列表的变化是不是真的顺利。此外,单击第二个选项卡时,第一个选项卡仍处于选中状态。第二次单击第二个选项卡时,它将被选中。如何使其更平滑,并在第一次单击时选择特定选项卡 适配器 public cl
布局
。第一个是带有底部条的标题(在本例中不在底部),并且始终显示该标题。其他2个布局
将根据单击底部栏
中的哪个选项卡进行切换。底部栏中的第一个选项卡将显示网格布局
,第二个选项卡应显示列表布局
。我已经设法实现了它,但有一个轻微的轻弹和列表的变化是不是真的顺利。此外,单击第二个选项卡时,第一个选项卡仍处于选中状态。第二次单击第二个选项卡时,它将被选中。如何使其更平滑,并在第一次单击时选择特定选项卡
适配器
public class ProfileAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int HEADER_TYPE = 0;
private final int IMAGE_GRID_TYPE = 1;
private final int IMAGE_LIST_TYPE = 2;
private final int cellSize;
private Context mContext;
private List<Home> mHomeList;
private boolean onBind;
private OnHeaderItemClickedListener mListener;
int selectedPosition;
public ProfileAdapter(Context context, List<Home> homeList) {
this.mContext = context;
this.mHomeList = homeList;
this.cellSize = Utils.getScreenWidth(context) / 3;
}
public interface OnHeaderItemClickedListener {
void onTabGridClicked();
void onTabListClicked();
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
switch (viewType) {
case HEADER_TYPE:
View viewHeader = inflater.inflate(R.layout.item_profile_header, parent, false);
StaggeredGridLayoutManager.LayoutParams lp1 = (StaggeredGridLayoutManager.LayoutParams) viewHeader.getLayoutParams();
lp1.setFullSpan(true);
viewHeader.setLayoutParams(lp1);
return new ProfileAdapter.HeaderHolder(viewHeader);
case IMAGE_GRID_TYPE:
View viewGridImage = inflater.inflate(R.layout.item_profile_grid_image, parent, false);
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) viewGridImage.getLayoutParams();
layoutParams.height = cellSize;
layoutParams.width = cellSize;
layoutParams.setFullSpan(false);
viewGridImage.setLayoutParams(layoutParams);
return new ImageGridHolder(viewGridImage);
case IMAGE_LIST_TYPE:
View viewListImage = inflater.inflate(R.layout.item_profile_list_image, parent, false);
StaggeredGridLayoutManager.LayoutParams lp3 = (StaggeredGridLayoutManager.LayoutParams) viewListImage.getLayoutParams();
lp3.setFullSpan(true);
viewListImage.setLayoutParams(lp3);
return new ImageListHolder(viewListImage);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case HEADER_TYPE:
onBind = true;
bindHeader((HeaderHolder) holder, mHomeList.get(position));
onBind = false;
break;
case IMAGE_GRID_TYPE:
onBind = true;
bindGridImage((ImageGridHolder) holder, mHomeList.get(position));
onBind = false;
break;
case IMAGE_LIST_TYPE:
onBind = true;
bindListImage((ImageListHolder) holder, mHomeList.get(position));
onBind = false;
break;
}
}
private void bindHeader(final HeaderHolder holder, Home home) {
holder.getItemProfileHeaderBinding().setHome(home);
holder.getItemProfileHeaderBinding().bottomBar.setOnTabSelectListener(new OnTabSelectListener() {
@Override
public void onTabSelected(@IdRes int tabId) {
switch (tabId) {
case R.id.tab_grid:
if (!onBind) {
mListener.onTabGridClicked();
selectedPosition = holder.getLayoutPosition();
notifyItemChanged(selectedPosition);
}
break;
case R.id.tab_list:
if (!onBind) {
mListener.onTabListClicked();
selectedPosition = holder.getLayoutPosition();
notifyItemChanged(selectedPosition);
}
break;
}
}
});
adjustTabs(holder);
}
private void bindGridImage(ImageGridHolder holder, Home home) {
holder.getItemProfileGridImageBinding().setHome(home);
Uri uri = new Uri.Builder()
.scheme(UriUtil.LOCAL_RESOURCE_SCHEME)
.path(String.valueOf(R.drawable.ap_android_icon))
.build();
holder.getItemProfileGridImageBinding().ivImage.setImageURI(uri);
}
private void bindListImage(ImageListHolder holder, Home home) {
holder.getItemProfileListImageBinding().setHome(home);
}
@Override
public int getItemViewType(int position) {
if (isPositionHeader(position)) {
return HEADER_TYPE;
}
if (mHomeList.get(position).getGridListType() == 2) {
return IMAGE_LIST_TYPE;
} else {
return IMAGE_GRID_TYPE;
}
}
private boolean isPositionHeader(int position) {
return position == 0;
}
@Override
public int getItemCount() {
return mHomeList.size();
}
private void adjustTabs(HeaderHolder holder) {
holder.getItemProfileHeaderBinding().bottomBar.getTabWithId(R.id.tab_grid).setPadding(0, 30, 0, 0);
holder.getItemProfileHeaderBinding().bottomBar.getTabWithId(R.id.tab_list).setPadding(0, 30, 0, 0);
holder.getItemProfileHeaderBinding().bottomBar.getTabWithId(R.id.tab_group).setPadding(0, 30, 0, 0);
holder.getItemProfileHeaderBinding().bottomBar.getTabWithId(R.id.tab_bookmark).setPadding(0, 30, 0, 0);
}
private static class HeaderHolder extends RecyclerView.ViewHolder {
ItemProfileHeaderBinding mItemProfileHeaderBinding;
HeaderHolder(View itemView) {
super(itemView);
mItemProfileHeaderBinding = DataBindingUtil.bind(itemView);
}
ItemProfileHeaderBinding getItemProfileHeaderBinding() {
return mItemProfileHeaderBinding;
}
}
private static class ImageGridHolder extends RecyclerView.ViewHolder {
ItemProfileGridImageBinding mItemProfileGridImageBinding;
ImageGridHolder(View itemView) {
super(itemView);
mItemProfileGridImageBinding = DataBindingUtil.bind(itemView);
}
ItemProfileGridImageBinding getItemProfileGridImageBinding() {
return mItemProfileGridImageBinding;
}
}
private static class ImageListHolder extends RecyclerView.ViewHolder {
ItemProfileListImageBinding mItemProfileListImageBinding;
ImageListHolder(View itemView) {
super(itemView);
mItemProfileListImageBinding = DataBindingUtil.bind(itemView);
}
ItemProfileListImageBinding getItemProfileListImageBinding() {
return mItemProfileListImageBinding;
}
}
public void addOnHeaderItemClickListener(OnHeaderItemClickedListener listener) {
this.mListener = listener;
}
}
编辑
我添加了notifyDataSetChanged()代码>而不是notifyItemChanged(selectedPosition)代码>并且更改是即时的,但是第二个选项卡看起来从未被选中,并且我无法在第一个和第二个选项卡之间切换。我必须点击第三个才能回到第一个。就好像标签的位置被卡住了。如果使用notifyItemRangeChanged(0,yourList.size()),您将获得更平滑的过渡,而不是闪烁。在使用dynamic RecyclerView时,我在使用notifyDatasetChanged时遇到了一些奇怪的渲染问题,切换到notifyItemRangeChanged修复了这个问题。嗯,我尝试了notifyItemRangeChanged
,它在选项卡上实现了这一点,但是我的列表和layoutmanager
被搞砸了notifyDataSetChanged
起到了作用,只是标签混淆了…@Neil我刚刚尝试了notifyItemRangeChanged
,它确实更流畅。但是,选项卡不是第一次切换的。。。
public class ProfileFragment extends BaseFragment implements ProfileAdapter.OnHeaderItemClickedListener {
private static final String ARG_PARAM1 = "param1";
FragmentProfileMultipleBinding mBinder;
FragmentManager mFragmentManager;
Home mHome;
ProfileAdapter mAdapter;
List<Home> mHomeList;
StaggeredGridLayoutManager mManager;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mBinder = DataBindingUtil.inflate(inflater, R.layout.fragment_profile_multiple, container, false);
mFragmentManager = getChildFragmentManager();
mHome = new Home();
populateList();
mManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
mAdapter = new ProfileAdapter(getContext(), mHomeList);
mBinder.rvGrid.setLayoutManager(mManager);
mBinder.rvGrid.setAdapter(mAdapter);
mAdapter.addOnHeaderItemClickListener(this);
setUIListeners();
return mBinder.getRoot();
}
private void populateList() {
for (int i = 0; i < 20; i++) {
mHomeList.add(i, mHome);
}
}
private void populateUpdatedList() {
for (Home home : mHomeList) {
home.setGridListType(2);
}
}
private void populateGridList() {
for (Home home : mHomeList) {
home.setGridListType(5);
}
}
@Override
public void onTabGridClicked() {
populateGridList();
mManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
}
@Override
public void onTabListClicked() {
populateUpdatedList();
mManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
}
}