RecyclerView动态更新多种视图类型

时间:2017-04-11 09:43:10

标签: android android-recyclerview recyclerview-layout

我试图找出Heterogeneous Recyclerview的工作原理,并根据我的需要进行调整。我有3个layouts。第一个是带有BottomBar的标题(在这种情况下不在底部),并且始终显示。其他2个layouts会根据BottomBar中的哪个标签进行切换。 BottomBar中的第一个标签会显示grid layout,第二个标签会显示list layout。我已经成功实现了它,但是有轻微的轻弹和更改列表并不是很顺利。此外,单击第二个选项卡时,仍然会选择第一个选项卡。在第二个选项卡上单击,然后选中它。如何使其更顺畅,并在第一次单击时选择特定选项卡?

Adapter

    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;
    }
}
选项卡点击发生的

Fragment

    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);
    }
}

修改

我添加了notifyDataSetChanged();而不是notifyItemChanged(selectedPosition);,并且更改是即时的,但第二个标签永远不会被选中,我无法在第一个和第二个之间切换。我必须点击第三个才能回到第一个。好像标签位置卡住了。

0 个答案:

没有答案