Add drop-down refresh
SwipeRefreshLayout
1. In the XML file, use SwipeRefreshLayout to layout the package
<? xml version="1.0" encoding="utf-8"? > <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/srl_base"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_base"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
Copy the code
2. Set the refresh callback
mSwpBase.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {// Specific refresh logic onFresh(); }});Copy the code
3. After the refresh, set the refresh status to false
mSwpBase.setRefreshing(false);
Copy the code
4. Other
// Set the background color of the progress circle. setProgressBackgroundColor(int colorRes);
// Set the color of the progress animation. SetColorSchemeResources (int… colorResIds);
// Set the size of the progress circle, with only two values: DEFAULT, LARGE) setSize(int size);
2. Add more pull-up loading (without footView)
1. Use the built-in addOnScrollListener to listen to add:
rcBase.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); // Add(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); }});Copy the code
2. In the onAdd method to determine whether to load the last one
public void onAdd(RecyclerView recyclerView, int newState){
if (newState == RecyclerView.SCROLL_STATE_IDLE && mManager.findLastVisibleItemPosition() == mAdapter.getItemCount()) {
new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(2000);
list.addAll(list);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
Toast.makeText(getActivity(), "Load complete", Toast.LENGTH_SHORT).show(); }}); } }).start(); }}Copy the code
Among them:
Recyclerview. SCROLL_STATE_IDLE: Checks whether a finger leaves the screen
MManager. FindLastVisibleItemPosition () : is the last one (for LinearLayoutManager method, GridLayoutManager inheritance LinearLayoutManager)
Add more pull-up loading (footView included)
Similar to pull-up loading without footiew, but with footView, a little more judgment is needed.
RecyclerView does not have a method like listView addfootView, but there is a getItemViewType method in adapter, so we can create a different holder according to the different position
1. Override getItemViewType in Adapter:
@Override
public int getItemViewType(int position) {
if (position + 1 == getItemCount()) {
return TYPE_FOOTER;
} else {
returnTYPE_ITEM; }}Copy the code
Position +1: the number of footViews added is increased by 1
Likewise in getItemCount return list.size()+1
View private static final int TYPE_ITEM = 0;
FootView private static final int TYPE_FOOTER = 1;
2. On the basis of ViewHolder, make a FootHolder
class FootHolder extends RecyclerView.ViewHolder { private final TextView tvFt; public FootHolder(View itemView) { super(itemView); tvFt = (TextView) itemView.findViewById(R.id.tv_ft); }}Copy the code
Note: Since there are two ViewHolder classes in the inherited recyclerView. Adapter generic class need to be changed to the public parent recyclerView. ViewHolder
3. Create different views based on viewType in onCreateViewHolder and return different holders
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == TYPE_ITEM) {
view = getActivity().getLayoutInflater().inflate(R.layout.fragment_video, parent, false);
return new VideoHolder(view);
} else if (viewType == TYPE_FOOTER) {
view = getActivity().getLayoutInflater().inflate(R.layout.foot_view, parent, false);
return new FootHolder(view);
}
return null;
}
Copy the code
4. Load the unused logic in onBindViewHoder according to the holder type
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof VideoHolder) { VideoBean videoBean = list.get(position); VideoHolder videoHolder = (VideoHolder) holder; videoHolder.fbVideo.setImageURI(videoBean.getImg()); videoHolder.tvTitle.setText(videoBean.getTitle()); / / the data when the tag to the view, it is ok to write a listener videoHolder. LlVideo. SetTag (videoBean); videoHolder.llVideo.setOnClickListener(mListerner); }else if (holder instanceof FootHolder) {
FootHolder footHolder = (FootHolder) holder;
switch (load_more_status) {
case PULLUP_LOAD_MORE:
footHolder.tvFt.setText("Pull up to load more");
break;
case LOADING_MORE:
footHolder.tvFt.setText("Loading more");
break; }}}Copy the code
Use instance to judge, and then force the Holder class
Public static final int PULLUP_LOAD_MORE = 0;
Public static final int LOADING_MORE = 1;
Private int load_more_status = 0; private int load_more_status = 0;
5. OnScrollStateChanged modification
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
load_more_status = LOADING_MORE;
if (newState == RecyclerView.SCROLL_STATE_IDLE && getCount() + 1 == mAdapter.getItemCount()) {
new Thread(new Runnable() {
@Override
public void run() {
load_more_status = PULLUP_LOAD_MORE;
SystemClock.sleep(2000);
list.addAll(list);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
Toast.makeText(getActivity(), "Load complete", Toast.LENGTH_SHORT).show(); }}); } }).start(); }}Copy the code
Iv. Handling of other problems
1. GridLayoutManager adding footView causes layout confusion:
The reason:
GridLayoutManager manager = new GridLayoutManager(getActivity(), 3);
When we were in our new GridLayoutManager, we passed in 3
It’s like dividing a row into 3 parts. By default, each item has 1 part, that is, 3 items in a row, and your footview also has 1 part, so it’s not centered.
Once you know why, it’s easy to change
Public Static Abstract Class SpanSizeLookup (GridLayoutManager package)
The getSpanSize method is overridden when inherited, and returns 1 by default, one layout
class GridSpanSizeLookop extends GridLayoutManager.SpanSizeLookup {
@Override
public int getSpanSize(int position) {
return1; }}Copy the code
So, in this method we can say, when it’s footView, return one line and that’s it.
Modify the return value of the getSpanSize method
class GridSpanSizeLookop extends GridLayoutManager.SpanSizeLookup {
@Override
public int getSpanSize(int position) {
// Log.d(TAG, position + "xx" + list.size() + 1);
if (position == list.size()) {
return mManager.getSpanCount();
}
return1; }}Copy the code
OnAttachedToRecyclerView ();
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
if (mGridSpanSizeLookup == null) {
mGridSpanSizeLookup = new GridSpanSizeLookop();
}
mManager.setSpanSizeLookup(mGridSpanSizeLookup);
}
Copy the code
Alternatively, after new GridLayoutManager we can write:
mManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
returnposition == list.size() ? mManager.getSpanCount() : 1; }});Copy the code
2. Other uses of getSpanSize:
The following layout is implemented by changing the return value
Code:
mManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
returnposition == list.size() ? mManager.getSpanCount() : 3 - position % 3; }});Copy the code
3. The fluid layout processing Due to no setSpanSizeLookup StaggeredGridLayoutManager method, through the load on the way to realize, But StaggeredGridLayoutManager. LayoutParams setFullSpan method can achieve the same effect.
So instead of rewriting the onAttachedToRecyclerView method, we’re rewriting the onViewAttachedToWindow method
@override public void onViewAttachedToWindow(recyclerView.viewholder holder) { super.onViewAttachedToWindow(holder); ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();if(layoutParams ! = null && layoutParams instanceof StaggeredGridLayoutManager. LayoutParams) {/ / is the last oneif (holder.getLayoutPosition() == list.size()) {
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
p.setFullSpan(true); // mIsFresh = can be pulled uptrue; }}}Copy the code