RecycleView具有不同的视图类型

时间:2017-01-12 12:23:07

标签: android

我有RecycleView,它有两个几乎相同的视图(相同的内容,但订单不同)。他们有不同的ViewHolders所以我可以实现不同的布局,但其余的是相同的。所以我不想重复自己,因为这是一个不好的做法。这是我的代码:

class ViewHolder extends RecyclerView.ViewHolder {

    PostItemBinding mViewDataBinding;

    public ViewHolder(PostItemBinding viewDataBinding) {
        super(viewDataBinding.getRoot());
        mViewDataBinding = viewDataBinding;
        mViewDataBinding.executePendingBindings();
    }

    public PostItemBinding getBinding() {
        return mViewDataBinding;
    }
}

// ------------------------------------------------------------------------------------

class ViewHolderComments extends RecyclerView.ViewHolder {

    PostWithCommentItemBinding mViewDataBinding;

    public ViewHolderComments(PostWithCommentItemBinding viewDataBinding) {
        super(viewDataBinding.getRoot());
        mViewDataBinding = viewDataBinding;
        mViewDataBinding.executePendingBindings();
    }

    public PostWithCommentItemBinding getBinding() {
        return mViewDataBinding;
    }
}


@Override
public void onBindViewHolder(final RecyclerView.ViewHolder base, final int pos) {

    if (base instanceof ViewHolder) {

        position = hideHeader ? pos : pos - 1;
        setUpPostView(base, position);

    } else if (base instanceof ViewHolderComments) {

        position = hideHeader ? pos : pos - 1;
        setUpCommentsView(base, position);

    } else {

        setUpHeader(base);
    }
}

第一个视图设置:

    protected void setUpPostView(RecyclerView.ViewHolder base, final int position) {

                final ViewHolder holder = (ViewHolder) base;

                ..... the same code
}

第二个视图设置:

protected void setUpCommentsView(RecyclerView.ViewHolder base, final int position) {

            final ViewHolderComments holder = (ViewHolderComments) base;

            ..... the same code
}

如果没有我投射ViewHolder的第一行,一切都是一样的。我如何优化/改进它?使用抽象类?

3 个答案:

答案 0 :(得分:1)

您不必为其使用不同的视图,您可以使用不同的源布局启动相同的视图类,只需在持有者中添加一个标记。

class MyViewHolder {
    public static final int TYPE_POST = 1;
    public static final int TYPE_COMMENT = 2;
    public int type;
}

TYPE_POST中返回TYPE_COMMENTgetItemType,将onCreateViewHolder中的变量设置为持有者。 onBindViewHolder您可以简单地转换为MyViewHolder并检查type变量,并根据您可以访问不同的字段或其他内容。

您还可以创建父视图类,并具有两个扩展该视图的子视图。在这种情况下,您不需要类型变量,而是具有继承。

答案 1 :(得分:1)

编辑:您可以尝试使用此代码,我认为PostItemBindingPostWithCommentItemBinding都来自ViewDataBinding

class BaseHolder<T extends ViewDataBinding> extends ViewHolder<T> {
    T mViewDataBinding;

    public BaseHolder(T viewDataBinding) {
        super(viewDataBinding.getRoot());
        mViewDataBinding = viewDataBinding;
        mViewDataBinding.executePendingBindings();
    }

    public T getBinding() {
        return mViewDataBinding;
    }

    public void setupView(int position) {
        // your same code
    }
}

class ViewHolder extends BaseHolder<PostItemBinding> {

    public ViewHolder(PostItemBinding viewDataBinding) {
        super(viewDataBinding);
    }
}

class ViewHolderComments extends BaseHolder<PostWithCommentItemBinding> {

    public ViewHolderComments(PostWithCommentItemBinding viewDataBinding) {
        super(viewDataBinding);
    }
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder base, final int pos) {
    if (base instanceof BaseHolder) {
        position = hideHeader ? pos : pos - 1;
        ((BaseHolder) base).setupView(position);
    }  else {
        setUpHeader(base);
    }
}

使用正确的getItemViewTypeonCreateViewHolder,您可能只需要BaseHolder类,并且可以删除ViewHolder类和ViewHolderComments类,但它基于你剩下的代码。

答案 2 :(得分:0)

您必须在适配器上实现方法:getItemViewType(int position)。

像这样:

@Override
public int getItemViewType(int position) {
    switch(position) {
        case 0:
            return POST;
        default:
            return COMMENT;
    }
}


@Override
public YourViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    switch (viewType) {
        case POST:
            //// create view holder for: R.layout.row_post;
            break;
        case COMMENT:
            //// create view holder for: R.layout.row_comment;
            break;
    }

   ....
}