国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android RecyclerView實現下拉刷新和上拉加載

2019-12-12 06:23:09
字體:
來源:轉載
供稿:網友

RecyclerView已經出來很久了,許許多多的項目都開始從ListView轉戰RecyclerView,那么,上拉加載和下拉刷新是一件很有必要的事情。

在ListView上,我們可以通過自己添加addHeadView和addFootView去添加頭布局和底部局實現自定義的上拉和下拉,或者使用一些第三方庫來簡單的集成,例如Android-pulltorefresh或者android-Ultra-Pull-to-Refresh,后者的自定義更強,但需要自己實現上拉加載。

而在下面我們將用兩種方式來實現上拉加載和下拉刷新

第一種方式:SwipeRefreshLayout+滑動底部自動加載

第二種方式:使用第三方庫SwipeToLoadLayout實現上拉加載和下拉刷新。

第一種方式:SwipeRefreshLayout+滑動底部自動加載

SwipeRefreshLayout實現很簡單,重點是滑動到底部自動加載應該如何實現,其實其實現的方式類似于ListView的實現方式。

看一下activity_recycle_swiperefresh.xml文件:

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/swipe_refresh" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView  android:id="@+id/swipe_target"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:scrollbars="none" /></android.support.v4.widget.SwipeRefreshLayout>

布局文件就兩個控件,SwipeRefreshLayout中嵌套RecyclerView。

在代碼中初始化RecyclerView以及實現adapter等,這不是重點,不再貼代碼。

在RecyclerView中有方法addOnScrollListener,該方法類似于ListView的setOnScrollListener方法,OnScrollListener中有兩個方法的回調

*onScrolled(RecyclerView recyclerView, int dx, int dy) :滾動的回調,dx和dy表示手指滑動水平和垂直的偏移量。

*onScrollStateChanged(RecyclerView recyclerView, int newState):滑動狀態的回調。

那么,我們的著重點就在這個兩個方法上了。

對于向上加載更多,我們需要有如下判斷

--是否是向上滑動

--是否滑動到底部

--當前是否正在加載數據

--當前狀態是否是滑動停止的狀態

實現比較復雜,定義一個類LoadDataScrollController,繼承類RecyclerView.OnScrollListener,

因為onScrollStateChanged實在狀態改變時的回調,無法時時的獲取顯示的條目以及位置,所以我們在onScrolled中獲取相應位置,

 @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  /**   * 獲取布局參數   */  RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();  //如果為null,第一次運行,確定布局類型  if (mLayoutManagerType == null) {   if (layoutManager instanceof LinearLayoutManager) {    mLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT;   } else if (layoutManager instanceof GridLayoutManager) {    mLayoutManagerType = LayoutManagerType.GRID_LAYOUT;   } else if (layoutManager instanceof StaggeredGridLayoutManager) {    mLayoutManagerType = LayoutManagerType.STAGGERED_GRID_LAYOUT;   } else {    throw new RuntimeException("LayoutManager should be LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager");   }  }  //對于不太能夠的布局參數,不同的方法獲取到當前顯示的最后一個條目數  switch (mLayoutManagerType) {   case LINEAR_LAYOUT:    mLastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();    break;   case GRID_LAYOUT:    mLastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();    break;   case STAGGERED_GRID_LAYOUT:    StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;    if (mLastPostions == null) {     mLastPostions = new int[staggeredGridLayoutManager.getSpanCount()];    }    staggeredGridLayoutManager.findLastVisibleItemPositions(mLastPostions);    mLastVisibleItemPosition = findMax(mLastPostions);    break;   default:    break;  } }

首先獲取布局管理器,并判斷是那種類型的,因為有三種類型,定義枚舉來保存布局類型的參數

/** * * RecycleView的布局管理器的類型 * Created by Alex_MaHao on 2016/5/10. */public enum LayoutManagerType { LINEAR_LAYOUT, GRID_LAYOUT, STAGGERED_GRID_LAYOUT}

然后根據布局慣例其的類型獲取其當前顯示的最大條目,對于瀑布流來說,他如果是垂直的兩列瀑布的話,我們需要獲取兩列中分別最大條目數,進行比較,選出最大條目數。

 /**  * 當是瀑布流時,獲取到的是每一個瀑布最下方顯示的條目,通過條目進行對比  */ private int findMax(int[] lastPositions) {  int max = lastPositions[0];  for (int value : lastPositions) {   if (value > max) {    max = value;   }  }  return max; }

拿到當前最大的條目數之后,在onScrollStateChange中進行判斷狀態等,

 @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {  RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();  //RecycleView 顯示的條目數  int visibleCount = layoutManager.getChildCount();  //顯示數據總數  int totalCount = layoutManager.getItemCount();  // 四個條件,分別是是否有數據,狀態是否是滑動停止狀態,顯示的最大條目是否大于整個數據(注意偏移量),是否正在加載數據  if(visibleCount>0    &&newState==RecyclerView.SCROLL_STATE_IDLE    &&mLastVisibleItemPosition>=totalCount-1    &&!isLoadData){   //可以加載數據   isLoadData = true;  } }

注釋很清楚,在加載數據的地方,我們將isLoadData設為true,同時利用接口回調加載數據,等數據加載完成,通過setLoadDataStatus方法設置為false

 public void setLoadDataStatus(boolean isLoadData){  this.isLoadData = isLoadData; }

如果這樣就結束了,感覺很麻煩,對于刷新和加載更多,我們需要在調用的地方分別設置監聽,那么我們可以讓LoadDataScrollController實現SwipeRefreshLayout的刷新監聽方法,在利用我們定義的統一的上拉刷新和加載數據接口進行處理

/** * 實現上拉加載的監聽:加載條件:滑動到最后,且是停止狀態,則開始加載數據 * Created by Alex_MaHao on 2016/5/10. */public class LoadDataScrollController extends RecyclerView.OnScrollListener implements SwipeRefreshLayout.OnRefreshListener { /**  * 當前布局管理器的類型  */ private LayoutManagerType mLayoutManagerType; /**  * 當前RecycleView顯示的最大條目  */ private int mLastVisibleItemPosition; /**  * 每列的最后一個條目  */ private int[] mLastPostions; /**  * 是否正在加載數據 包括刷新和向上加載更多  */ private boolean isLoadData = false; /**  * 回調接口  */ private OnRecycleRefreshListener mListener; public LoadDataScrollController(OnRecycleRefreshListener onRecycleRefreshListener) {  this.mListener = onRecycleRefreshListener; } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  /**   * 獲取布局參數   */  RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();  //如果為null,第一次運行,確定布局類型  if (mLayoutManagerType == null) {   if (layoutManager instanceof LinearLayoutManager) {    mLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT;   } else if (layoutManager instanceof GridLayoutManager) {    mLayoutManagerType = LayoutManagerType.GRID_LAYOUT;   } else if (layoutManager instanceof StaggeredGridLayoutManager) {    mLayoutManagerType = LayoutManagerType.STAGGERED_GRID_LAYOUT;   } else {    throw new RuntimeException("LayoutManager should be LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager");   }  }  //對于不太能夠的布局參數,不同的方法獲取到當前顯示的最后一個條目數  switch (mLayoutManagerType) {   case LINEAR_LAYOUT:    mLastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();    break;   case GRID_LAYOUT:    mLastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();    break;   case STAGGERED_GRID_LAYOUT:    StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;    if (mLastPostions == null) {     mLastPostions = new int[staggeredGridLayoutManager.getSpanCount()];    }    staggeredGridLayoutManager.findLastVisibleItemPositions(mLastPostions);    mLastVisibleItemPosition = findMax(mLastPostions);    break;   default:    break;  } } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {  RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();  //RecycleView 顯示的條目數  int visibleCount = layoutManager.getChildCount();  //顯示數據總數  int totalCount = layoutManager.getItemCount();  // 四個條件,分別是是否有數據,狀態是否是滑動停止狀態,顯示的最大條目是否大于整個數據(注意偏移量),是否正在加載數據  if(visibleCount>0    &&newState==RecyclerView.SCROLL_STATE_IDLE    &&mLastVisibleItemPosition>=totalCount-1    &&!isLoadData){   //可以加載數據   if(mListener!=null){    isLoadData = true;    mListener.loadMore();   }  } } /**  * 當是瀑布流時,獲取到的是每一個瀑布最下方顯示的條目,通過條目進行對比  */ private int findMax(int[] lastPositions) {  int max = lastPositions[0];  for (int value : lastPositions) {   if (value > max) {    max = value;   }  }  return max; } public void setLoadDataStatus(boolean isLoadData){  this.isLoadData = isLoadData; } @Override public void onRefresh() {  //刷新數據的方法  if(mListener!=null){   isLoadData = true;   mListener.refresh();  } } /**  * 數據加載接口回調  */ interface OnRecycleRefreshListener{  void refresh();  void loadMore(); }}

最后看一下main的代碼

/** * 使用原生的SwipeRefreshLayout和代碼判斷 *  實現RecyclewView 的刷新和加載更多 * * Created by Alex_MaHao on 2016/5/10. */public class SwipeRefreshActivity extends AppCompatActivity implements LoadDataScrollController.OnRecycleRefreshListener { private SwipeRefreshLayout mSwipeRefresh; private RecyclerView mRecycle; private HomeAdapter mAdapter; private LoadDataScrollController mController; private ProgressDialog pd; @Override protected void onCreate(@Nullable Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_recycle_swiperefresh);  mRecycle = ((RecyclerView) findViewById(R.id.swipe_target));  mSwipeRefresh = ((SwipeRefreshLayout) findViewById(R.id.swipe_refresh));  mSwipeRefresh.setColorSchemeColors(Color.RED,Color.GREEN,Color.BLUE);  /**   * 創建控制器,同時使當前activity實現數據監聽回調接口   */  mController = new LoadDataScrollController(this);  mAdapter = new HomeAdapter();  //設置垂直的線性布局管理器,Orientation --> VERTICAL:垂直 HORIZONTAL:水平  LinearLayoutManager layoutManager = new LinearLayoutManager(this);  layoutManager.setOrientation(LinearLayoutManager.VERTICAL);  //StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);  //添加分割線  mRecycle.addItemDecoration(new DividerItemDecoration(getApplicationContext(), DividerItemDecoration.VERTICAL_LIST));  mRecycle.setLayoutManager(layoutManager);  mRecycle.setItemAnimator(new DefaultItemAnimator());  mRecycle.setAdapter(mAdapter);  mAdapter.refresh();  /**   * 設置監聽   */  mRecycle.addOnScrollListener(mController);  mSwipeRefresh.setOnRefreshListener(mController); } @Override public void refresh() {  //刷新的接口調  mSwipeRefresh.postDelayed(new Runnable() {   @Override   public void run() {    mAdapter.refresh();    mSwipeRefresh.setRefreshing(false);    mController.setLoadDataStatus(false);   }  },2000); } @Override public void loadMore() {  //加載更多的接口回調  pd = new ProgressDialog(this);  pd.show();  mSwipeRefresh.postDelayed(new Runnable() {   @Override   public void run() {    mAdapter.add();    //設置數據加載結束的監聽狀態    mController.setLoadDataStatus(false);    pd.dismiss();   }  },2000); }}

貼個效果圖

第二種方式:SwipeToLoadLayout實現上拉加載和下拉刷新

該刷新控件的方式類似于Ultra-pull-to-refresh的使用方式。

如下方式添加該庫:

 repositories {  maven { url "https://jitpack.io" }   } compile 'com.github.Aspsine:SwipeToLoadLayout:1.0.3'

首先我們需要自定義一個頭視圖和底部視圖,頭部試圖和底部試圖的用法相同,所以我們先定義一個頭部視圖類:

/** * 基礎的refreshHeadView */public class RefreshHeaderView extends TextView implements SwipeRefreshTrigger, SwipeTrigger { public RefreshHeaderView(Context context) {  super(context); } public RefreshHeaderView(Context context, AttributeSet attrs) {  super(context, attrs); } public RefreshHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public RefreshHeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {  super(context, attrs, defStyleAttr, defStyleRes); } @Override public void onRefresh() {  //下拉到一定位置松開之后,調用此方法  setText("refresh");  Log.i("info","onRefresh"); } @Override public void onPrepare() {  //下拉之前調用此方法  Log.i("info","onPrepare"); } @Override public void onMove(int yScrolled, boolean isComplete, boolean automatic) {  if (!isComplete) {   //當前Y軸偏移量大于控件高度時,標識下拉到界限,顯示“松開已刷新”   if (yScrolled >= getHeight()) {   } else {    //未達到偏移量   }  }   Log.i("info","onMove"); } @Override public void onRelease() {  //達到一定滑動距離,松開刷新時調用  setText("onRelease");  Log.i("info","onRelease"); } @Override public void onComplete() {  //加載完成之后調用此方法  setText("complete");  Log.i("info","onComplete"); } @Override public void onReset() {  //重置  setText("onReset");  Log.i("info","onReset"); }}

其需要實現接口SwipeRefreshTrigger和SwipeTrigger。

而底部需要實現SwipeTrigger和SwipeLoadMoreTrigger。

布局文件中如下使用

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ECEDF0" > <com.aspsine.swipetoloadlayout.SwipeToLoadLayout  android:id="@+id/swipeToLoadLayout"  android:layout_width="match_parent"  android:layout_height="match_parent">  <com.mahao.alex.systemwidgetdemo.recycleView.swipetoloadlayout.RefreshHeaderView   android:id="@+id/swipe_refresh_header"   android:layout_width="match_parent"   android:layout_height="wrap_content" />  <android.support.v7.widget.RecyclerView   android:id="@+id/swipe_target"   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:scrollbars="vertical" />  <com.mahao.alex.systemwidgetdemo.recycleView.swipetoloadlayout.LoaderMoreView   android:id="@+id/swipe_load_more_footer"   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:gravity="center"   android:padding="20dp" /> </com.aspsine.swipetoloadlayout.SwipeToLoadLayout></RelativeLayout>

查找控件,設置監聽

        swipeToLoadLayout.setOnRefreshListener(this);
        swipeToLoadLayout.setOnLoadMoreListener(this);

在我們之前的代碼中,加入了log信息,我們可以看一下log信息。…代表多次onMove()方法多次調用。

05-10 10:30:34.396 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onPrepare
05-10 10:30:34.536 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
..........................................................................
05-10 10:30:34.886 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
05-10 10:30:34.896 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onRelease
05-10 10:30:34.906 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
..........................................................................
05-10 10:30:35.086 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
05-10 10:30:35.106 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onRefresh
05-10 10:30:37.116 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onComplete
05-10 10:30:37.416 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
..........................................................................
05-10 10:30:37.516 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onMove
05-10 10:30:37.916 23814-23814/com.mahao.alex.systemwidgetdemo I/info: onReset

首先會調用onPrepare()方法,onMove()方法會一直調用,只要視圖有偏移,就會調用。下拉到一定距離之后,松開調用onRelaease(),回歸到刷新位置時回調onRefresh(),加載完成調用onComplete(),視圖開始縮小,最后隱藏之后調用onReset()

根據需求自定義視圖,

定義我們的橢圓,使用自定義控件

/** * CircleView 圓盤控件,可以旋轉 * Created by Alex_MaHao on 2016/5/10. */public class CircleView extends View { /**  * 控件的半徑  */ private int mRadius; /**  * 繪制弧形的畫筆  */ private Paint mArcPaint; /**  * 繪制弧形的區域  */ private RectF mRange; private int[] colors = {Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN}; public CircleView(Context context) {  this(context, null, 0); } public CircleView(Context context, AttributeSet attrs) {  this(context, attrs, 0); } public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  init(); } private void init() {  mArcPaint = new Paint();  mArcPaint.setAntiAlias(true);  mArcPaint.setDither(true);  mArcPaint.setStyle(Paint.Style.FILL); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  int width = 0;  int height = 0;  int widthSize = MeasureSpec.getSize(widthMeasureSpec);  int widthMode = MeasureSpec.getMode(widthMeasureSpec);  int heightSize = MeasureSpec.getSize(heightMeasureSpec);  int heightMode = MeasureSpec.getMode(heightMeasureSpec);  if (widthMode == MeasureSpec.EXACTLY) {   width = widthSize;  } else {   width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 45, getResources().getDisplayMetrics());  }  if (heightMode == MeasureSpec.EXACTLY) {   height = heightSize;  } else {   height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 45, getResources().getDisplayMetrics());  }  //獲取半徑  mRadius = Math.min(width, height) / 2;  /**   * 設置寬高為固定值   */  setMeasuredDimension(mRadius * 2, mRadius * 2);   mRange = new RectF(0, 0, mRadius * 2, mRadius * 2); } @Override protected void onDraw(Canvas canvas) {  float degree = 360/colors.length/2f;  for (int i = 0; i < 8; i++) {   mArcPaint.setColor(colors[i%4]);   canvas.drawArc(mRange,-90f+degree*i,degree,true,mArcPaint);  } }}

繪制頭部刷新試圖

** * 自定義的下拉刷新控件 頭部 * Created by Alex_MaHao on 2016/5/10. */public class CircleRefreshHeaderView extends RelativeLayout implements SwipeTrigger, SwipeRefreshTrigger { CircleView mCircleView; TextView mDescText; private ObjectAnimator anim; private boolean isRelease; public CircleRefreshHeaderView(Context context) {  this(context, null, 0); } public CircleRefreshHeaderView(Context context, AttributeSet attrs) {  this(context, attrs, 0); } public CircleRefreshHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  initView(); } /**  * 初始化布局  */ private void initView() {  int circlewidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics());  mCircleView = new CircleView(getContext());  LinearLayout.LayoutParams circleParams = new LinearLayout.LayoutParams(circlewidth,circlewidth);  mCircleView.setLayoutParams(circleParams);  mDescText = new TextView(getContext());  LinearLayout.LayoutParams descParams = new LinearLayout.LayoutParams(circlewidth*3, ViewGroup.LayoutParams.WRAP_CONTENT);  descParams.gravity = Gravity.CENTER;  descParams.setMargins(circlewidth/2,0,0,0);  mDescText.setLayoutParams(descParams);  mDescText.setTextSize(12);  mDescText.setTextColor(Color.GRAY);  mDescText.setText("下拉刷新");  //添加線性的父布局  LinearLayout ll = new LinearLayout(getContext());  RelativeLayout.LayoutParams llParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);  llParams.addRule(CENTER_IN_PARENT);  ll.setLayoutParams(llParams);  ll.setPadding(10,10,10,10);  ll.addView(mCircleView);  ll.addView(mDescText);  addView(ll); } @Override public void onRefresh() {  //開始刷新,啟動動畫  anim = ObjectAnimator.ofFloat(mCircleView, "rotation", mCircleView.getRotation(), mCircleView.getRotation()+360f)    .setDuration(500);  anim.setRepeatCount(ValueAnimator.INFINITE);  anim.setRepeatMode(ValueAnimator.RESTART);  anim.start();  mDescText.setText("正在加載數據"); } @Override public void onPrepare() {  isRelease = false; } @Override public void onMove(int yScroll, boolean isComplete, boolean b1) {  if (!isComplete) {   if (yScroll < getHeight()) {    mDescText.setText("下拉刷新");   } else {    mDescText.setText("松開刷新更多");   }   //如果是仍在下拉狀態,則圓環跟隨滑動進行滾動   if (!isRelease)    mCircleView.setRotation(((float) yScroll) / getHeight() * 360f);  } } @Override public void onRelease() {  isRelease = true; } @Override public void onComplete() {  anim.cancel();  mDescText.setText("加載完成"); } @Override public void onReset() {  //重置時,將動畫置為初始狀態  mCircleView.setRotation(0f); }}

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ECEDF0" > <com.aspsine.swipetoloadlayout.SwipeToLoadLayout  android:id="@+id/swipeToLoadLayout"  android:layout_width="match_parent"  android:layout_height="match_parent">  <com.mahao.alex.systemwidgetdemo.recycleView.swipetoloadlayout.CircleRefreshHeaderView   android:id="@+id/swipe_refresh_header"   android:layout_width="match_parent"   android:layout_height="wrap_content" />  <android.support.v7.widget.RecyclerView   android:id="@+id/swipe_target"   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:scrollbars="vertical" />  <com.mahao.alex.systemwidgetdemo.recycleView.swipetoloadlayout.LoaderMoreView   android:id="@+id/swipe_load_more_footer"   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:gravity="center"   android:padding="20dp" /> </com.aspsine.swipetoloadlayout.SwipeToLoadLayout></RelativeLayout>
public class SwipeToLayoutActivity extends AppCompatActivity implements OnRefreshListener, OnLoadMoreListener { private RecyclerView mRecycleView; SwipeToLoadLayout swipeToLoadLayout; private HomeAdapter adapter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_recycle_swipetolayout);  swipeToLoadLayout = ((SwipeToLoadLayout) findViewById(R.id.swipeToLoadLayout));  mRecycleView = ((RecyclerView) findViewById(R.id.swipe_target));  adapter = new HomeAdapter();  //設置垂直的線性布局管理器,Orientation --> VERTICAL:垂直 HORIZONTAL:水平  LinearLayoutManager layoutManager = new LinearLayoutManager(this);  layoutManager.setOrientation(LinearLayoutManager.VERTICAL);//  StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);  //添加分割線  mRecycleView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), DividerItemDecoration.VERTICAL_LIST));  mRecycleView.setLayoutManager(layoutManager);  mRecycleView.setItemAnimator(new DefaultItemAnimator());  mRecycleView.setAdapter(adapter);  adapter.refresh();  /**   * 設置下拉刷新和上拉加載監聽   */  swipeToLoadLayout.setOnRefreshListener(this);  swipeToLoadLayout.setOnLoadMoreListener(this); } @Override public void onRefresh() {  swipeToLoadLayout.postDelayed(new Runnable() {   @Override   public void run() {    adapter.refresh();    swipeToLoadLayout.setRefreshing(false);   }  },2000); } @Override public void onLoadMore() {  swipeToLoadLayout.postDelayed(new Runnable() {   @Override   public void run() {    adapter.add();    swipeToLoadLayout.setLoadingMore(false);   }  },2000); }}

OK。肯定有小伙伴使用該框架時一直報錯,為什么,看框架的源碼,有如下一段

this.mHeaderView = this.findViewById(id.swipe_refresh_header); this.mTargetView = this.findViewById(id.swipe_target); this.mFooterView = this.findViewById(id.swipe_load_more_footer);

可以看出,作者是根據固定的id值獲取的,所以在我們的布局文件中,必須使用固定的三個id。

如有需求,可移步我的github獲取源碼,源碼在systemwidgetdemo中。

以上就是本文的全部內容,希望對大家學習Android軟件編程有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 吴川市| 藁城市| 新晃| 昌平区| 绩溪县| 阳山县| 新晃| 璧山县| 社旗县| 塔河县| 潮州市| 钟山县| 凤山市| 兴宁市| 神木县| 浦县| 鸡东县| 称多县| 招远市| 永清县| 米易县| 长泰县| 双城市| 海南省| 金川县| 武安市| 黑龙江省| 莱阳市| 逊克县| 香港 | 金溪县| 博罗县| 肇庆市| 仁布县| 邓州市| 潜山县| 邯郸市| 衢州市| 陕西省| 西乌珠穆沁旗| 辽阳县|