非常好用的一个列表View
- 依赖
implementation 'com.github.Aspsine:IRecyclerView:0.0.7
- 使用布局(展示列表的布局) main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<com.aspsine.irecyclerview.IRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recycleview_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:loadMoreEnabled="true"
app:loadMoreFooterLayout="@layout/layout_irecyclerview_load_more_footer"
app:refreshEnabled="true"
app:refreshHeaderLayout="@layout/layout_irecyclerview_refresh_header" />
- 头布局(下拉刷新展示的布局,需要修改View名称【包名+类名】) layout_irecyclerview_refresh_header.xml
<?xml version="1.0" encoding="utf-8"?>
<com.example.yufuhao.myrecyclerview.header.ClassicRefreshHeaderView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
android:background="#ff0000"
android:padding="10dp" />
脚布局(上拉加载更多时展示的布局,需要修改View名称【包名+类名】)layout_irecyclerview_load_more_footer.xml
<?xml version="1.0" encoding="utf-8"?>
<com.example.yufuhao.myrecyclerview.footer.LoadMoreFooterView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:padding="10dp"
android:background="#00ff00"
android:layout_height="48dp"/>
- 自定义头布局的类 ClassicRefreshHeaderView
public class ClassicRefreshHeaderView extends RelativeLayout implements RefreshTrigger {
private ImageView ivArrow;
private ImageView ivSuccess;
private TextView tvRefresh;
private ProgressBar progressBar;
private Animation rotateUp;
private Animation rotateDown;
private boolean rotated = false;
private int mHeight;
public ClassicRefreshHeaderView(Context context) {
this(context, null);
}
public ClassicRefreshHeaderView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ClassicRefreshHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflate(context, R.layout.layout_irecyclerview_classic_refresh_header_view, this);
tvRefresh = (TextView) findViewById(R.id.tvRefresh);
ivArrow = (ImageView) findViewById(R.id.ivArrow);
ivSuccess = (ImageView) findViewById(R.id.ivSuccess);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
rotateUp = AnimationUtils.loadAnimation(context, R.anim.rotate_up);
rotateDown = AnimationUtils.loadAnimation(context, R.anim.rotate_down);
}
@Override
public void onStart(boolean automatic, int headerHeight, int finalHeight) {
this.mHeight = headerHeight;
progressBar.setIndeterminate(false);
}
@Override
public void onMove(boolean isComplete, boolean automatic, int moved) {
if (!isComplete) {
ivArrow.setVisibility(VISIBLE);
progressBar.setVisibility(GONE);
ivSuccess.setVisibility(GONE);
if (moved <= mHeight) {
if (rotated) {
ivArrow.clearAnimation();
ivArrow.startAnimation(rotateDown);
rotated = false;
}
tvRefresh.setText("SWIPE TO REFRESH");
} else {
tvRefresh.setText("RELEASE TO REFRESH");
if (!rotated) {
ivArrow.clearAnimation();
ivArrow.startAnimation(rotateUp);
rotated = true;
}
}
}
}
@Override
public void onRefresh() {
ivSuccess.setVisibility(GONE);
ivArrow.clearAnimation();
ivArrow.setVisibility(GONE);
progressBar.setVisibility(VISIBLE);
tvRefresh.setText("REFRESHING");
}
@Override
public void onRelease() {
}
@Override
public void onComplete() {
rotated = false;
ivSuccess.setVisibility(VISIBLE);
ivArrow.clearAnimation();
ivArrow.setVisibility(GONE);
progressBar.setVisibility(GONE);
tvRefresh.setText("COMPLETE");
}
@Override
public void onReset() {
rotated = false;
ivSuccess.setVisibility(GONE);
ivArrow.clearAnimation();
ivArrow.setVisibility(GONE);
progressBar.setVisibility(GONE);
}
}
- 自定义脚布局的类 LoadMoreFooterView
public class LoadMoreFooterView extends FrameLayout {
private Status mStatus;
private View mLoadingView;
private View mErrorView;
private View mTheEndView;
private OnRetryListener mOnRetryListener;
public LoadMoreFooterView(Context context) {
this(context, null);
}
public LoadMoreFooterView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LoadMoreFooterView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.layout_irecyclerview_load_more_footer_view, this, true);
mLoadingView = findViewById(R.id.loadingView);
mErrorView = findViewById(R.id.errorView);
mTheEndView = findViewById(R.id.theEndView);
mErrorView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mOnRetryListener != null) {
mOnRetryListener.onRetry(LoadMoreFooterView.this);
}
}
});
setStatus(Status.GONE);
}
public void setOnRetryListener(OnRetryListener listener) {
this.mOnRetryListener = listener;
}
public Status getStatus() {
return mStatus;
}
public void setStatus(Status status) {
this.mStatus = status;
change();
}
public boolean canLoadMore() {
return mStatus == Status.GONE || mStatus == Status.ERROR;
}
private void change() {
switch (mStatus) {
case GONE:
mLoadingView.setVisibility(GONE);
mErrorView.setVisibility(GONE);
mTheEndView.setVisibility(GONE);
break;
case LOADING:
mLoadingView.setVisibility(VISIBLE);
mErrorView.setVisibility(GONE);
mTheEndView.setVisibility(GONE);
break;
case ERROR:
mLoadingView.setVisibility(GONE);
mErrorView.setVisibility(VISIBLE);
mTheEndView.setVisibility(GONE);
break;
case THE_END:
mLoadingView.setVisibility(GONE);
mErrorView.setVisibility(GONE);
mTheEndView.setVisibility(VISIBLE);
break;
}
}
public enum Status {
GONE, LOADING, ERROR, THE_END
}
public interface OnRetryListener {
void onRetry(LoadMoreFooterView view);
}
}
- 自定义适配器+多条目 MyRecyclerAdapter
public class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context context;
List<String> list;
private LayoutInflater inflater;
public MyRecyclerAdapter(Context context, List<String> list) {
this.context = context;
this.list = list;
inflater = LayoutInflater.from(context);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == 1) {
View view1 = inflater.inflate(R.layout.item, parent, false);
MyViewHolder holder1 = new MyViewHolder(view1);
return holder1;
} else {
View view2 = inflater.inflate(R.layout.itme_two, parent, false);
TwoViewHolder holder2 = new TwoViewHolder(view2);
return holder2;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof MyViewHolder) {
MyViewHolder myViewHolder = (MyViewHolder) holder;
myViewHolder.one_tv.setText(list.get(position));
}
if (holder instanceof TwoViewHolder) {
TwoViewHolder twoViewHolder = (TwoViewHolder) holder;
twoViewHolder.two_tv.setText(list.get(position));
}
}
@Override
public int getItemViewType(int position) {
return 1;
}
@Override
public int getItemCount() {
return list.size();
}
//这是一个viewholder
class MyViewHolder extends RecyclerView.ViewHolder {
TextView one_tv;
ImageView one_img;
public MyViewHolder(View view) {
super(view);
one_tv = (TextView) view.findViewById(R.id.one_title);
one_img = (ImageView) view.findViewById(R.id.one_image);
}
}
class TwoViewHolder extends RecyclerView.ViewHolder {
TextView two_tv;
ImageView two_img01;
ImageView two_img02;
public TwoViewHolder(View view) {
super(view);
two_tv = (TextView) view.findViewById(R.id.two_title);
two_img01 = (ImageView) view.findViewById(R.id.two_img01);
two_img02 = (ImageView) view.findViewById(R.id.two_img02);
}
}
}
- 适配器的两个布局(为了不缺少东西,就多占用点空间,如果这个自己写,完全可以跳过)
- item.xml 和 item_two.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal">
<TextView
android:id="@+id/one_title"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="10dp"
android:layout_weight="1"
android:textSize="15sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/one_image"
android:layout_width="120dp"
android:layout_height="80dp"
android:layout_margin="10dp" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="140dp"
android:orientation="vertical">
<TextView
android:id="@+id/two_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:lines="1"
android:textSize="15sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="105dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/two_img01"
android:layout_width="0dp"
android:layout_height="70dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp"
android:layout_weight="1" />
<ImageView
android:id="@+id/two_img02"
android:layout_width="0dp"
android:layout_height="70dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
最后数据和view的搭配
public class MainActivity extends Activity {
private IRecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
List<String> list = new ArrayList<>();
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
recyclerView.setRefreshing(false);
break;
case 2:
loadMoreFooterView.setStatus(LoadMoreFooterView.Status.GONE);
break;
}
}
};
private LoadMoreFooterView loadMoreFooterView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (IRecyclerView) findViewById(R.id.recycleview_id);
loadMoreFooterView = (LoadMoreFooterView) recyclerView.getLoadMoreFooterView();
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.addItemDecoration(
new HorizontalDividerItemDecoration.Builder(this)
.color(Color.RED)
.build());
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
list.clear();
list.add("a");
recyclerView.setRefreshing(true);
handler.sendEmptyMessageDelayed(1, 2000);
}
});
recyclerView.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
list.addAll(list);
loadMoreFooterView.setStatus(LoadMoreFooterView.Status.LOADING);
handler.sendEmptyMessageDelayed(2, 2000);
}
});
list.add("q");
list.add("w");
list.add("e");
//添加适配器
MyRecyclerAdapter adapter = new MyRecyclerAdapter(MainActivity.this, list);
recyclerView.setIAdapter(adapter);
}
}
- 上拉和下拉是的动画
rotate_down.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="150"
android:fillAfter="true"
android:fromDegrees="-180"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:toDegrees="0" />
rotate_up.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="150"
android:fillAfter="true"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-180" />
-
提示1 这个setIAdapter();方法一定要看准,有一个 I,如果不佳 I 是没有上拉的
-
提示2 上拉加载更多,可以设置三种状态,手动设置最后展示的效果
-
如果遇到什么问题,可以直接打电话
-
15010082410--老余
-
也可以关注我,在帖子上和我交流