Java 在扩展RecyclerView.Adapter时使用装饰器模式合适吗?

Java 在扩展RecyclerView.Adapter时使用装饰器模式合适吗?,java,android,android-recyclerview,Java,Android,Android Recyclerview,我已经编写了一个footer适配器,它似乎工作得很好 我意识到,ViewHolder有一个字段mPosition,其中包含每个元素中的状态,这让我怀疑使用Decorator模式无法实现标题,因为它在每个适配器中都会保持不同的位置 也就是说,除非包装器/装饰器适配器没有改变其他元素。也就是说:页脚是可以的,只要数据不需要绑定到页脚 如果包装适配器是可能的,那么我们将需要更多的访问ViewHolder?我不知道这些田地是怎么回事 预期用途: headerView = new View( contex

我已经编写了一个
footer适配器
,它似乎工作得很好

我意识到,
ViewHolder
有一个字段
mPosition
,其中包含每个元素中的状态,这让我怀疑使用Decorator模式无法实现标题,因为它在每个
适配器中都会保持不同的位置

也就是说,除非包装器/装饰器
适配器
没有改变其他元素。也就是说:页脚是可以的,只要数据不需要绑定到页脚

如果包装适配器是可能的,那么我们将需要更多的访问ViewHolder?我不知道这些田地是怎么回事

预期用途:

headerView = new View( context );
footerView = new View( context );

MyAdapter myAdapter = new MyAdapter();
HeaderAdapter headerAdapter = new HeaderAdapter( myAdapter , headerView );
FooterAdapter footerAdapter = new FooterAdapter( headerAdapter , footerView );

RecyclerView recyclerView = new RecyclerView();
recyclerView.setAdapter( footerAdapter );
这将非常酷,因为这样我们就可以向任意
适配器添加页眉和页脚,而不必担心索引和抵消项目计数

FooterAdapter.java

public class FooterAdapter extends RecyclerView.Adapter
{
    private static final String TAG = "FooterAdapter";
    private final RecyclerView.Adapter<RecyclerView.ViewHolder> wrappedAdapter;

    private View footer;

    public static final int FOOTER_TYPE = 0x72846fe;

    public FooterAdapter( RecyclerView.Adapter<RecyclerView.ViewHolder> wrappedAdapter , View footer )
    {
        this.footer = footer;
        this.wrappedAdapter = wrappedAdapter;
        wrappedAdapter.registerAdapterDataObserver(new ThisObserver());
    }

    @Override
    public int getItemViewType(int position)
    {
        if( position == wrappedAdapter.getItemCount() ) return FOOTER_TYPE;
        return wrappedAdapter.getItemViewType(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if( viewType == FOOTER_TYPE )
        {
            return new RecyclerView.ViewHolder( footer ){};
        }else
        {
            return wrappedAdapter.onCreateViewHolder(parent,viewType);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if( holder.getItemViewType() == FOOTER_TYPE ) return;
        return wrappedAdapter.bindViewHolder( holder , position );
    }

    @Override
    public int getItemCount() {
        return wrappedAdapter.getItemCount() + 1;
    }


    private class ThisObserver extends AdapterDataObserver
    {
        public void onChanged() {
            notifyDataSetChanged();
        }

        public void onItemRangeChanged(int positionStart, int itemCount) {
            notifyItemRangeChanged(positionStart,itemCount);
        }

        public void onItemRangeInserted(int positionStart, int itemCount) {
            notifyItemRangeInserted(positionStart,itemCount);
        }

        public void onItemRangeRemoved(int positionStart, int itemCount) {
            notifyItemRangeRemoved(positionStart,itemCount);
        }

        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            int lower = Math.min( fromPosition , toPosition );
            int upper = Math.max( fromPosition , toPosition );
            for( int i = itemCount-1 ; i < itemCount ; i++ )
            {
                notifyItemMoved(upper+i,lower+i+(toPosition-fromPosition));
            }
        }
    }
}
public class HeaderAdapter extends RecyclerView.Adapter
{
    private static final String TAG = "HeaderAdapter";
    private final RecyclerView.Adapter<RecyclerView.ViewHolder> wrappedAdapter;

    private View header;

    public static final int HEADER_TYPE = 0x747efe;

    public HeaderAdapter( RecyclerView.Adapter<RecyclerView.ViewHolder> wrappedAdapter , View header )
    {
        this.header = header;
        this.wrappedAdapter = wrappedAdapter;
        wrappedAdapter.registerAdapterDataObserver(new ThisObserver());
    }

    @Override
    public int getItemViewType(int position)
    {
        return position == 0 ? HEADER_TYPE : wrappedAdapter.getItemViewType(position - 1);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if( viewType == HEADER_TYPE )
        {
            return new RecyclerView.ViewHolder( header ){};
        }else
        {
            return new RecyclerView.ViewHolder( wrappedAdapter.onCreateViewHolder(parent,viewType).itemView ){};
            // I thought some kind of wrapping (hack?) like this might get 
            // around the different indexing in different Adapters, but 
            // it doesn't work, it would probably needs more 
            // information, or to be able to observe changes in 
            // the "child" ViewHolder.
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if( holder.getItemViewType() != HEADER_TYPE ) wrappedAdapter.bindViewHolder( holder , position - 1 );
    }

    @Override
    public int getItemCount() {
        return wrappedAdapter.getItemCount() + 1;
    }


    private class ThisObserver extends RecyclerView.AdapterDataObserver
    {

        public void onChanged() {
            notifyDataSetChanged();
        }

        public void onItemRangeChanged(int positionStart, int itemCount) {
            notifyItemRangeChanged(1+positionStart,itemCount);
        }

        public void onItemRangeInserted(final int positionStart, final int itemCount) {
            notifyItemRangeInserted(1 + positionStart, itemCount);
        }

        public void onItemRangeRemoved(int positionStart, int itemCount) {
            notifyItemRangeRemoved(1 + positionStart, itemCount);
        }

        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            fromPosition++;
            toPosition++;
            int lower = Math.min( fromPosition , toPosition );
            int upper = Math.max( fromPosition , toPosition );
            for( int i = itemCount-1 ; i < itemCount ; i++ ) notifyItemMoved(upper+i,lower+i+(toPosition-fromPosition));
        }
    }
}
公共类FooterAdapter扩展了RecyclerView.Adapter { 私有静态最终字符串TAG=“FooterAdapter”; 专用最终回收视图。适配器wrappedAdapter; 私有视图页脚; 公共静态最终整型页脚类型=0x72846fe; 公共页脚适配器(RecyclerView.Adapter wrappedAdapter,视图页脚) { this.footer=页脚; this.wrappedAdapter=wrappedAdapter; registerAdapterDataObserver(新的ThisObserver()); } @凌驾 public int getItemViewType(int位置) { if(position==wrappedAdapter.getItemCount())返回页脚类型; 返回wrappedAdapter.getItemViewType(位置); } @凌驾 public RecyclerView.ViewHolder onCreateViewHolder(视图组父级,int-viewType){ 如果(视图类型==页脚类型) { 返回新的RecyclerView.ViewHolder(页脚){}; }否则 { 返回wrappedAdapter.onCreateViewHolder(父级,viewType); } } @凌驾 BindViewHolder上的公共无效(RecyclerView.ViewHolder,int位置){ if(holder.getItemViewType()=页脚类型)返回; 返回wrappedAdapter.bindViewHolder(支架,位置); } @凌驾 public int getItemCount(){ 返回wrappedAdapter.getItemCount()+1; } 私有类ThisObserver扩展AdapterDataObserver { 更改后的公共无效(){ notifyDataSetChanged(); } 已更改公共位置(int positionStart、int itemCount){ notifyItemRangeChanged(位置开始,itemCount); } 已插入的公用项目(int positionStart、int itemCount){ notifyItemRangeInserted(positionStart,itemCount); } 已删除的公共void(int positionStart,int itemCount){ notifyItemRangeRemoved(positionStart,itemCount); } 已移动的公用文件夹(int-fromPosition、int-toPosition、int-itemCount){ int lower=数学最小值(起始位置、位置); int upper=数学最大值(起始位置、位置); 对于(int i=itemCount-1;i
HeaderAdapter.java

public class FooterAdapter extends RecyclerView.Adapter
{
    private static final String TAG = "FooterAdapter";
    private final RecyclerView.Adapter<RecyclerView.ViewHolder> wrappedAdapter;

    private View footer;

    public static final int FOOTER_TYPE = 0x72846fe;

    public FooterAdapter( RecyclerView.Adapter<RecyclerView.ViewHolder> wrappedAdapter , View footer )
    {
        this.footer = footer;
        this.wrappedAdapter = wrappedAdapter;
        wrappedAdapter.registerAdapterDataObserver(new ThisObserver());
    }

    @Override
    public int getItemViewType(int position)
    {
        if( position == wrappedAdapter.getItemCount() ) return FOOTER_TYPE;
        return wrappedAdapter.getItemViewType(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if( viewType == FOOTER_TYPE )
        {
            return new RecyclerView.ViewHolder( footer ){};
        }else
        {
            return wrappedAdapter.onCreateViewHolder(parent,viewType);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if( holder.getItemViewType() == FOOTER_TYPE ) return;
        return wrappedAdapter.bindViewHolder( holder , position );
    }

    @Override
    public int getItemCount() {
        return wrappedAdapter.getItemCount() + 1;
    }


    private class ThisObserver extends AdapterDataObserver
    {
        public void onChanged() {
            notifyDataSetChanged();
        }

        public void onItemRangeChanged(int positionStart, int itemCount) {
            notifyItemRangeChanged(positionStart,itemCount);
        }

        public void onItemRangeInserted(int positionStart, int itemCount) {
            notifyItemRangeInserted(positionStart,itemCount);
        }

        public void onItemRangeRemoved(int positionStart, int itemCount) {
            notifyItemRangeRemoved(positionStart,itemCount);
        }

        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            int lower = Math.min( fromPosition , toPosition );
            int upper = Math.max( fromPosition , toPosition );
            for( int i = itemCount-1 ; i < itemCount ; i++ )
            {
                notifyItemMoved(upper+i,lower+i+(toPosition-fromPosition));
            }
        }
    }
}
public class HeaderAdapter extends RecyclerView.Adapter
{
    private static final String TAG = "HeaderAdapter";
    private final RecyclerView.Adapter<RecyclerView.ViewHolder> wrappedAdapter;

    private View header;

    public static final int HEADER_TYPE = 0x747efe;

    public HeaderAdapter( RecyclerView.Adapter<RecyclerView.ViewHolder> wrappedAdapter , View header )
    {
        this.header = header;
        this.wrappedAdapter = wrappedAdapter;
        wrappedAdapter.registerAdapterDataObserver(new ThisObserver());
    }

    @Override
    public int getItemViewType(int position)
    {
        return position == 0 ? HEADER_TYPE : wrappedAdapter.getItemViewType(position - 1);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if( viewType == HEADER_TYPE )
        {
            return new RecyclerView.ViewHolder( header ){};
        }else
        {
            return new RecyclerView.ViewHolder( wrappedAdapter.onCreateViewHolder(parent,viewType).itemView ){};
            // I thought some kind of wrapping (hack?) like this might get 
            // around the different indexing in different Adapters, but 
            // it doesn't work, it would probably needs more 
            // information, or to be able to observe changes in 
            // the "child" ViewHolder.
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if( holder.getItemViewType() != HEADER_TYPE ) wrappedAdapter.bindViewHolder( holder , position - 1 );
    }

    @Override
    public int getItemCount() {
        return wrappedAdapter.getItemCount() + 1;
    }


    private class ThisObserver extends RecyclerView.AdapterDataObserver
    {

        public void onChanged() {
            notifyDataSetChanged();
        }

        public void onItemRangeChanged(int positionStart, int itemCount) {
            notifyItemRangeChanged(1+positionStart,itemCount);
        }

        public void onItemRangeInserted(final int positionStart, final int itemCount) {
            notifyItemRangeInserted(1 + positionStart, itemCount);
        }

        public void onItemRangeRemoved(int positionStart, int itemCount) {
            notifyItemRangeRemoved(1 + positionStart, itemCount);
        }

        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            fromPosition++;
            toPosition++;
            int lower = Math.min( fromPosition , toPosition );
            int upper = Math.max( fromPosition , toPosition );
            for( int i = itemCount-1 ; i < itemCount ; i++ ) notifyItemMoved(upper+i,lower+i+(toPosition-fromPosition));
        }
    }
}
公共类HeaderAdapter扩展了RecyclerView.Adapter
{
私有静态最终字符串标记=“HeaderAdapter”;
专用最终回收视图。适配器wrappedAdapter;
私有视图头;
公共静态最终整数头类型=0x747efe;
公共标头适配器(RecyclerView.Adapter wrappedAdapter,视图标头)
{
this.header=头;
this.wrappedAdapter=wrappedAdapter;
registerAdapterDataObserver(新的ThisObserver());
}
@凌驾
public int getItemViewType(int位置)
{
返回位置==0?标题类型:wrappedAdapter.getItemViewType(位置-1);
}
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
如果(视图类型==标题类型)
{
返回新的RecyclerView.ViewHolder(头){};
}否则
{
返回新的RecyclerView.ViewHolder(wrappedAdapter.onCreateViewHolder(父级,viewType.itemView){};
//我想像这样的包装(黑客?)可能会
//围绕不同适配器中的不同索引,但是
//它不起作用,可能需要更多
//信息,或能够观察到
//“子”视图持有者。
}
}
@凌驾
BindViewHolder上的公共无效(RecyclerView.ViewHolder,int位置){
if(holder.getItemViewType()!=HEADER\u TYPE)wrappedAdapter.bindViewHolder(holder,位置-1);
}
@凌驾
public int getItemCount(){
返回wrappedAdapter.getItemCount()+1;
}
私有类ThisObserver扩展了RecyclerView.AdapterDataObserver
{
更改后的公共无效(){
notifyDataSetChanged();
}
已更改公共位置(int positionStart、int itemCount){
notifyItemRangeChanged(1+positionStart,itemCount);
}
插入的公共无效项(最终整型位置开始,最终整型项目计数){
notifyItemRangeInserted(1+positionStart,itemCount);
}
已删除的公共void(int positionStart,int itemCount){
notifyItemRangeRemoved(1+positionStart,itemCount);
}
已移动的公用文件夹(int-fromPosition、int-toPosition、int-itemCount){
fromPosition++;
拓扑学++;
int lower=数学最小值(起始位置、位置);
int upper=数学最大值(起始位置、位置);
对于(inti=itemCount-1;i