SwipeToLoadLayout下拉刷新上拉加载

github地址:https://github.com/tslearner/SwipeToLoadLayout

下拉刷新动画:箭头 和最后更新时间


配置:

  • 首先在工程的build.gradle上面添加JitPack仓库
    allprojects {
      repositories {
          ...
          maven { url "https://jitpack.io" }
      }
    }
  • 其次,在模块的build.gradle上面添加依赖
    dependencies {
      compile 'com.github.Aspsine:SwipeToLoadLayout:1.0.3'
    }
使用:

MainActivity:


public class MainActivity extends AppCompatActivity {
    RecyclerView recyclerView;
    List list;
    MyAdapter myAdapter;
    SwipeToLoadLayout swipeToLoadLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        swipeToLoadLayout=(SwipeToLoadLayout)findViewById(R.id.swipeToLoad);
        recyclerView=(RecyclerView)findViewById(R.id.swipe_target);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            list.add("原始数据");
        }
        myAdapter = new MyAdapter(this,list);
        //为recyclerView设置适配器
        recyclerView.setAdapter(myAdapter);
        //为swipeToLoadLayout设置下拉刷新监听者
        swipeToLoadLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh() {
                for (int i = 0; i < 20; i++) {
                    list.add(0,"刷新获得的数据");
                }
                myAdapter.notifyDataSetChanged();
                //设置下拉刷新结束
                swipeToLoadLayout.setRefreshing(false);
            }
        });
        //为swipeToLoadLayout设置上拉加载更多监听者
        swipeToLoadLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore() {
                for (int i = 0; i < 20; i++) {
                    list.add("加载更多获得的数据");
                }
                myAdapter.notifyDataSetChanged();
                //设置上拉加载更多结束
                swipeToLoadLayout.setLoadingMore(false);
            }
        });
     
    }
}

MyAdapter:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    List list;

    public MyAdapter(Context context, List data) {
        super();
      list=data;
    }

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

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item, parent, false);
        return  new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        String a=(String)list.get(position);
        holder.tv.setText(a);



    }
    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView tv;

        public ViewHolder(View v) {
            super(v);
            tv = (TextView) v.findViewById(R.id.text);
        }
    }
}


布局:

<?xml version="1.0" encoding="utf-8"?><com.aspsine.swipetoloadlayout.SwipeToLoadLayout  xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     xmlns:app="http://schemas.android.com/apk/res-auto"     android:id="@+id/swipeToLoad"     android:layout_width="match_parent"    android:layout_height="match_parent"    app:refresh_enabled="true"    tools:context="com.example.tianshuai.swipetoloadlayout.MainActivity">       <com.example.tianshuai.swipetoloadlayout.RefreshHeaderView            android:id="@+id/swipe_refresh_header"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:gravity="center"            android:padding="20dp" />       <android.support.v7.widget.RecyclerView             android:id="@+id/swipe_target"              android:layout_width="match_parent"              android:layout_height="match_parent"/>        <com.example.tianshuai.swipetoloadlayout.LoadMoreFooterView              android:id="@id/swipe_load_more_footer"              android:layout_width="match_parent"              android:layout_height="100dp"              android:gravity="center" /></com.aspsine.swipetoloadlayout.SwipeToLoadLayout>

item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text"/>


</LinearLayout>


LoadMoreFooterView:


public class LoadMoreFooterView extends TextView implements SwipeTrigger, SwipeLoadMoreTrigger {
    public LoadMoreFooterView(Context context) {
        super(context);
    }


    public LoadMoreFooterView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public void onLoadMore() {
        setText("LOADING MORE");
    }


    @Override
    public void onPrepare() {
        setText("");
    }


    @Override
    public void onMove(int yScrolled, boolean isComplete, boolean automatic) {
        if (!isComplete) {
            if (yScrolled <= -getHeight()) {
                setText("RELEASE TO LOAD MORE");
            } else {
                setText("SWIPE TO LOAD MORE");
            }
        } else {
            setText("LOAD MORE RETURNING");
        }
    }


    @Override
    public void onRelease() {
        setText("LOADING MORE");
    }


    @Override
    public void onComplete() {
        setText("COMPLETE");
    }


    @Override
    public void onReset() {
        setText("");
    }
}


RefreshHeaderView:
public class RefreshHeaderView extends TextView implements SwipeRefreshTrigger, SwipeTrigger {


    public RefreshHeaderView(Context context) {
        super(context);
    }


    public RefreshHeaderView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public void onRefresh() {
        setText("REFRESHING");
    }


    @Override
    public void onPrepare() {
        setText("");
    }


    @Override
    public void onMove(int yScrolled, boolean isComplete, boolean automatic) {
        if (!isComplete) {
            if (yScrolled >= getHeight()) {
                setText("RELEASE TO REFRESH");
            } else {
                setText("SWIPE TO REFRESH");
            }
        } else {
            setText("REFRESH RETURNING");
        }
    }


    @Override
    public void onRelease() {
    }


    @Override
    public void onComplete() {
        setText("COMPLETE");
    }


    @Override
    public void onReset() {
        setText("");
    }
}


修改RefreshHeaderView样式;


public class RefreshHeaderView extends LinearLayout implements SwipeRefreshTrigger, SwipeTrigger {
    String TAG="RefreshHeaderView";
    private Context mContext;
    private TextView tv;
    private RoundProgressBar mRoundProgressBar;


    public RefreshHeaderView(Context context) {
        super(context);
        init(context);
    }


    public RefreshHeaderView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }


    public void init(Context context){
        mContext=context;
        LayoutInflater.from(context).inflate(R.layout.refresh_header, this);
    }


    @Override
    protected void onFinishInflate() {
        Log.d(TAG, "onFinishInflate: ");
        super.onFinishInflate();
        initView();
    }


    public void initView(){
        tv=(TextView)findViewById(R.id.text);
        mRoundProgressBar=(RoundProgressBar)findViewById(R.id.roundProgressBar2);
        mRoundProgressBar.setMax(100);
        mRoundProgressBar.setProgress(80);
    }


    @Override
    public void onRefresh() {
        Log.d(TAG, "onRefresh: ");
        tv.setText("正在刷新数据中");
    }


    @Override
    public void onPrepare() {
        Log.d(TAG, "onPrepare: ");
        tv.setText("下拉后刷新");
    }


    @Override
    public void onMove(int yScrolled, boolean isComplete, boolean automatic) {
        if (!isComplete) {
            if (yScrolled >= getHeight()) {
                tv.setText("释放立即刷新");
            } else {
                tv.setText("下拉后刷新");
            }
        } /*else {
            tv.setText("REFRESH RETURNING");
        }*/
    }


    @Override
    public void onRelease() {
        Log.d(TAG, "onRelease: ");
    }


    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete: ");
        tv.setText("完成刷新");
    }


    @Override
    public void onReset() {
        Log.d(TAG, "onReset: ");
        tv.setText("");
    }
}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:android_custom="http://schemas.android.com/apk/res-auto"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal">


    <com.example.tianshuai.swipetoloadlayout.RoundProgressBar
        android:id="@+id/roundProgressBar2"
        android:layout_width="50dip"
        android:layout_height="50dip"
        android_custom:roundColor="#D1D1D1"
        android_custom:roundProgressColor="@android:color/black"
        android_custom:textColor="#9A32CD"
        android_custom:textIsDisplayable="false"
        android_custom:roundWidth="4dip"
        android_custom:textSize="18sp"/>


    <TextView
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        android:text=""
        android:layout_gravity="center_vertical"/>


</LinearLayout>


public class RoundProgressBar extends View {
    /**
     * 画笔对象的引用
     */
    private Paint paint;


    /**
     * 圆环的颜色
     */
    private int roundColor;


    /**
     * 圆环进度的颜色
     */
    private int roundProgressColor;


    /**
     * 中间进度百分比的字符串的颜色
     */
    private int textColor;


    /**
     * 中间进度百分比的字符串的字体
     */
    private float textSize;


    /**
     * 圆环的宽度
     */
    private float roundWidth;


    /**
     * 最大进度
     */
    private int max;


    /**
     * 当前进度
     */
    private int progress;
    /**
     * 是否显示中间的进度
     */
    private boolean textIsDisplayable;


    /**
     * 进度的风格,实心或者空心
     */
    private int style;


    public static final int STROKE = 0;
    public static final int FILL = 1;


    public RoundProgressBar(Context context) {
        this(context, null);
    }


    public RoundProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);


        paint = new Paint();




        TypedArray mTypedArray = getContext().obtainStyledAttributes(attrs,
                R.styleable.RoundProgressBar);


        //获取自定义属性和默认值
        roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED);
        roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
        textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.GREEN);
        textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);
        roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 5);
        max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100);
        textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);
        style = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0);


        mTypedArray.recycle();
    }




    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);


        /**
         * 画最外层的大圆环
         */
        int centre = getWidth()/2; //获取圆心的x坐标
        int radius = (int) (centre - roundWidth/2); //圆环的半径
        paint.setColor(roundColor); //设置圆环的颜色
        paint.setStyle(Paint.Style.STROKE); //设置空心
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度
        paint.setAntiAlias(true);  //消除锯齿
        canvas.drawCircle(centre, centre, radius, paint); //画出圆环


        Log.e("log", centre + "");


        /**
         * 画进度百分比
         */
        paint.setStrokeWidth(0);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体
        int percent = (int)(((float)progress / (float)max) * 100);  //中间的进度百分比,先转换成float在进行除法运算,不然都为0
        float textWidth = paint.measureText(percent + "%");   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间


        if(textIsDisplayable && percent != 0 && style == STROKE){
            canvas.drawText(percent + "%", centre - textWidth / 2, centre + textSize/2, paint); //画出进度百分比
        }




        /**
         * 画圆弧 ,画圆环的进度
         */


        //设置进度是实心还是空心
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度
        paint.setColor(roundProgressColor);  //设置进度的颜色
        RectF oval = new RectF(centre - radius, centre - radius, centre
                + radius, centre + radius);  //用于定义的圆弧的形状和大小的界限


        switch (style) {
            case STROKE:{
                paint.setStyle(Paint.Style.STROKE);
                canvas.drawArc(oval, 0, 360 * progress / max, false, paint);  //根据进度画圆弧
                break;
            }
            case FILL:{
                paint.setStyle(Paint.Style.FILL_AND_STROKE);
                if(progress !=0)
                    canvas.drawArc(oval, 0, 360 * progress / max, true, paint);  //根据进度画圆弧
                break;
            }
        }


    }




    public synchronized int getMax() {
        return max;
    }


    /**
     * 设置进度的最大值
     * @param max
     */
    public synchronized void setMax(int max) {
        if(max < 0){
            throw new IllegalArgumentException("max not less than 0");
        }
        this.max = max;
    }


    /**
     * 获取进度.需要同步
     * @return
     */
    public synchronized int getProgress() {
        return progress;
    }


    /**
     * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
     * 刷新界面调用postInvalidate()能在非UI线程刷新
     * @param progress
     */
    public synchronized void setProgress(int progress) {
        if(progress < 0){
            throw new IllegalArgumentException("progress not less than 0");
        }
        if(progress > max){
            progress = max;
        }
        if(progress <= max){
            this.progress = progress;
            postInvalidate();
        }


    }




    public int getCricleColor() {
        return roundColor;
    }


    public void setCricleColor(int cricleColor) {
        this.roundColor = cricleColor;
    }


    public int getCricleProgressColor() {
        return roundProgressColor;
    }


    public void setCricleProgressColor(int cricleProgressColor) {
        this.roundProgressColor = cricleProgressColor;
    }


    public int getTextColor() {
        return textColor;
    }


    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }


    public float getTextSize() {
        return textSize;
    }


    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }


    public float getRoundWidth() {
        return roundWidth;
    }


    public void setRoundWidth(float roundWidth) {
        this.roundWidth = roundWidth;
    }






}




<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <declare-styleable name="RoundProgressBar">
        <attr name="roundColor" format="color"/>
        <attr name="roundProgressColor" format="color"/>
        <attr name="roundWidth" format="dimension"></attr>
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
        <attr name="max" format="integer"></attr>
        <attr name="textIsDisplayable" format="boolean"></attr>
        <attr name="style">
            <enum name="STROKE" value="0"></enum>
            <enum name="FILL" value="1"></enum>
        </attr>
    </declare-styleable>
</resources>



SwipeToLoadLayout常用属性:


app:refresh_enabled:设置是否可以下拉刷新
app:load_more_enabled:设置是否可以上拉加载更多
app:swipe_style:设置下拉刷新与上拉加载的样式,其值为classic,above,blew或scale
app:refresh_trigger_offset:触发下拉刷新的偏移量,默认值是下拉刷新头部的高度
app:load_more_trigger_offset:触发上拉加载更多的偏移量,默认值是上拉加载更多的高度
app:refresh_final_drag_offset:下拉刷新最大可以拖动的偏移量
app:load_more_final_drag_offset:上拉加载更多最大可以拖动的偏移量
app:release_to_refreshing_scrolling_duration:释放下拉刷新持续滚动的时间
app:release_to_loading_more_scrolling_duration:释放上拉加载更多持续滚动的时间
app:refresh_complete_delay_duration:下拉刷新完成延迟的持续时间
app:load_more_complete_delay_duration:上拉加载更多完成延迟的持续时间
app:refresh_complete_to_default_scrolling_duration:默认完成下拉刷新持续滚动时间
app:load_more_complete_to_default_scrolling_duration: 默认完成上拉加载更多持续滚动时间
app:default_to_refreshing_scrolling_duration:默认下拉刷新滚动时间
app:default_to_loading_more_scrolling_duration:默认上拉加载更多滚动时间


      
      





        
        







        
        







        
        







        
        





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值