1. 程式人生 > >recyclerview下拉重新整理和載入更多

recyclerview下拉重新整理和載入更多

SwipeRefreshLayout是google推薦的支援下拉重新整理的佈局控制元件,但是隻支援下拉重新整理不能上劃載入更多。我觀察知乎的重新整理和載入更多操作,發現他的載入更多是不需要上拉手勢的,當recyclerview滑到最後一個item時自動載入更多資料。所以我通過viewtype在recyclerview最後新增一個不同佈局的item,當這個item顯示到螢幕時自動獲取更多資料。

1. SwipeRefreshLayout

SwipeRefreshLayout包含在v4支援包中,使用很簡單,佈局:

<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiperefresh" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycleview" android:layout_width="match_parent" android:layout_height="match_parent"
> </android.support.v7.widget.RecyclerView> </android.support.v4.widget.SwipeRefreshLayout>

java程式碼中,設定重新整理監聽setOnRefreshListener,通過setRefreshing(false)關閉重新整理動畫:

mSwipeRefreshLayout= (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
        mSwipeRefreshLayout.setOnRefreshListener(new
SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { mList.add(0,"ajkfgamj"); mSwipeRefreshLayout.setRefreshing(false); adapter.notifyDataSetChanged(); } });

效果:

image

2. 通過viewtype使recyclerview顯示不同佈局

1. 定義兩個ViewHolder類來顯示不同佈局:

protected class MyViewHolder extends RecyclerView.ViewHolder {
        TextView mTextView1;

        public MyViewHolder(View itemView) {
            super(itemView);
            mTextView1= (TextView) itemView.findViewById(R.id.text);
        }
    }

    protected class LastViewHolder extends RecyclerView.ViewHolder{
        public LastViewHolder(View itemView) {
        }

    }

2. 重寫getItemCount和getItemViewType方法,要注意的是getItemCount返回的數量要比資料量+1

@Override
    public int getItemCount() {
        return mList.size()+1;
    }
 @Override
    public int getItemViewType(int position) {
        if (position==mList.size()){
            return 2;
        }else {
            return 1;
        }
    }

3. 在onCreateViewHolder和onBindViewHolder中分情況處理:

@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType==1){
            View view = mInflater.inflate(R.layout.item,parent,false);
            MyViewHolder holder= new MyViewHolder(view);
            return holder;
        }else {
            View view = mInflater.inflate(R.layout.last_item,parent,false);
            LastViewHolder holder=new LastViewHolder(view);
            return holder;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof MyViewHolder){
            ((MyViewHolder) holder).mTextView1.setText(mList.get(position)+position);
        }else if (holder instanceof LastViewHolder){
            getMore();
        }

    }

顯示效果:

image

3. 實現當顯示最後item時載入更多

1. 為了能在activity中實現載入更多的操作,需要把adapter設為抽象類,並定義抽象方法

abstract void getMore();

2. 在onBindViewHolder中呼叫getMore();

@Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof MyViewHolder){
            ((MyViewHolder) holder).mTextView1.setText(mList.get(position)+position);
        }else if (holder instanceof LastViewHolder){
            getMore();
        }

    }

3. 在初始化adapter時實現getMore()方法,但是這時候還不能直接呼叫notifyDataSetChanged(),所以使用handl來進行處理:

final Adapter adapter= new Adapter(mList, this) {
            @Override
            void getMore() {
                mHandler.sendMessage(new Message());
            }
        };

        mHandler=new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                mList.add("adfjyagjkjgjkukhuhk");
                adapter.notifyDataSetChanged();
                return false;
            }
        });

效果:

image

完整程式碼:

adapter:

public abstract class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    List<String> mList;
    Context mContext;
    LayoutInflater mInflater;

    public Adapter(List<String> list, Context context) {
        mList = list;
        mContext = context;
        mInflater=LayoutInflater. from(mContext);
    }

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

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType==1){
            View view = mInflater.inflate(R.layout.item,parent,false);
            MyViewHolder holder= new MyViewHolder(view);
            return holder;
        }else {
            View view = mInflater.inflate(R.layout.last_item,parent,false);
            LastViewHolder holder=new LastViewHolder(view);
            return holder;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof MyViewHolder){
            ((MyViewHolder) holder).mTextView1.setText(mList.get(position)+position);
        }else if (holder instanceof LastViewHolder){
            getMore();
        }

    }

    @Override
    public int getItemViewType(int position) {
        if (position==mList.size()){
            return 2;
        }else {
            return 1;
        }
    }

    protected class MyViewHolder extends RecyclerView.ViewHolder {
        TextView mTextView1;

        public MyViewHolder(View itemView) {
            super(itemView);
            mTextView1= (TextView) itemView.findViewById(R.id.text);
        }
    }

    protected class LastViewHolder extends RecyclerView.ViewHolder{
        public LastViewHolder(View itemView) {
            super(itemView);
        }

    }
    abstract void getMore();
}

mainactivity:

public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private SwipeRefreshLayout mSwipeRefreshLayout;
    List<String> mList;
    static private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRecyclerView= (RecyclerView) findViewById(R.id.recycleview);
        mList=new ArrayList<>();

        for (int i = 0; i < 25; i++) {
            mList.add("akudfhakjnk");
        }
        final Adapter adapter= new Adapter(mList, this) {
            @Override
            void getMore() {
                mHandler.sendMessage(new Message());
            }
        };

        mHandler=new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                mList.add("adfjyagjkjgjkukhuhk");
                adapter.notifyDataSetChanged();
                return false;
            }
        });

        mRecyclerView.setAdapter(adapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
        mSwipeRefreshLayout= (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mList.add(0,"ajkfgamj");
                mSwipeRefreshLayout.setRefreshing(false);
                adapter.notifyDataSetChanged();
            }
        });

    }
}