您的位置:首页 > 其它

SwipeRefreshLayout和RecyclerView整合实现下拉刷新

2016-05-27 10:52 417 查看
SwipeRefreshLayout是google提供的一个下拉刷新组件,其实是一个布局,此布局内只有有一个直接子View。使用此组件需要实现SwipeRefreshLayout.OnRefreshListener接口,在onRefresh方法中实现数据的更新操作。

RecyclerView用来替代ListView,使用这两个组件实现了下拉刷新列表数据的功能。

开始时:



下拉刷新进行中:



刷新后:



布局文件layout_swiperefresh_main:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools = "http://schema.android.com/tools"
xmlns:app = "http://schemas.android.com/apk/res-auto"
android:id="@+id/swipe_refresh_widget"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dip">
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dip"
android:orientation="vertical"
app:divider="@drawable/line"
app:dividerPadding="5dp"
app:showDividers="middle">
<TextView
android:id="@+id/tip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="下拉刷新"/>
<android.support.v7.widget.RecyclerView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="@null"
android:scrollbars="vertical" />
</android.support.v7.widget.LinearLayoutCompat>

</android.support.v4.widget.SwipeRefreshLayout>


MainActivity类onCreate方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_swiperefresh_main);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_widget);
mRecyclerView = (RecyclerView) findViewById(android.R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(mAdapter = new RecyclerAdapter());
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,
DividerItemDecoration.VERTICAL_LIST));
swipeRefreshLayout.setColorSchemeResources(R.color.swipe_color_1,
R.color.swipe_color_2,
R.color.swipe_color_3,
R.color.swipe_color_4);
swipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);;
swipeRefreshLayout.setProgressBackgroundColor(R.color.swipe_background_color);

swipeRefreshLayout.setProgressViewEndTarget(true, 100);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Thread(new Runnable() {
@Override
public void run() {
mDatas.clear();
initData();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendEmptyMessage(1);
}
}).start();
}
});

}


DividerItemDecoration是RecyclerView中列表项item之间的分割线。

DividerItemDecoration定义如下:

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

private final int[] ATTRS = new int[]{
android.R.attr.listDivider
};

public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZON
4000
TAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

private Drawable mDivider;
private int mOrientation;

public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
}

public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
}
mOrientation = orientation;
}

@Override
public void onDraw(Canvas c, RecyclerView parent) {
Log.v("recyclerview - itemdecoration", "onDraw()");
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}

public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();

final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}

public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}

@Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}


SwipeRefreshLayout调用setOnRefreshListener方法设置刷新完成时的监听器。当刷新完成时调用会调用OnRefreshListener接口的onRefresh方法,可以在此方法中开启另个线程从网络上获取数据,最后通过Handler交给主线程刷新显示。

RecyclerView调用setAdapter设置一个RecyclerView.Adapter。

MainActivity全部代码:

public class MainActivity extends Activity implements SwipeRefreshLayout.OnRefreshListener{

private SwipeRefreshLayout swipeRefreshLayout;
private RecyclerView mRecyclerView;
private List<String> mDatas = new ArrayList<>();
private RecyclerAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_swiperefresh_main);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_widget);
mRecyclerView = (RecyclerView) findViewById(android.R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(mAdapter = new RecyclerAdapter());
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,
DividerItemDecoration.VERTICAL_LIST));
swipeRefreshLayout.setColorSchemeResources(R.color.swipe_color_1,
R.color.swipe_color_2,
R.color.swipe_color_3,
R.color.swipe_color_4);
swipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);;
swipeRefreshLayout.setProgressBackgroundColor(R.color.swipe_background_color);

swipeRefreshLayout.setProgressViewEndTarget(true, 100);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Thread(new Runnable() {
@Override
public void run() {
mDatas.clear();
initData();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendEmptyMessage(1);
}
}).start();
}
});

}
//handler
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
swipeRefreshLayout.setRefreshing(false);
mAdapter.notifyDataSetChanged();
break;
default:
break;
}
}
};

private void initData() {
for (int i = 'A'; i < 'z'; i++)
{
mDatas.add("" + (char) i);
}
}

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

private final int[] ATTRS = new int[]{
android.R.attr.listDivider
};

public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

private Drawable mDivider;
private int mOrientation;

public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
}

public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
}
mOrientation = orientation;
}

@Override
public void onDraw(Canvas c, RecyclerView parent) {
Log.v("recyclerview - itemdecoration", "onDraw()");
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}

public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();

final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}

public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}

@Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}

class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>
{

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
MainActivity.this).inflate(R.layout.item, parent,
false));
return holder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position)
{
holder.tv.setText(mDatas.get(position));
}

@Override
public int getItemCount()
{
return mDatas.size();
}

class MyViewHolder extends RecyclerView.ViewHolder
{
TextView tv;
public MyViewHolder(View view)
{
super(view);
tv = (TextView) view.findViewById(R.id.id_num);
}
}
}

@Override
public void onRefresh() {

}
}


drawable目录下的line.xml文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

<solid android:color="@android:color/black" />

<!-- 分割线的高度 -->
<size android:height="3dip" />

</shape>


layout文件夹中item.xml文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dip"
android:background="#44ff0000">
<TextView
android:id="@+id/id_num"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="1" />
</FrameLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  下拉刷新