android 列表上拉下拉(IRecyclerview)

非常好用的一个列表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--老余

  • 也可以关注我,在帖子上和我交流

发布了80 篇原创文章 · 获赞 93 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_40251830/article/details/84778549