前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >定制SwipeRefreshLayout

定制SwipeRefreshLayout

作者头像
全栈程序员站长
发布2022-09-12 19:49:28
1.2K0
发布2022-09-12 19:49:28
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

SwipeRefreshLayout大家都用过,google推出的,亲生儿子,兼容性自然最好!可是SwipeRefreshLayout只支持下拉刷新,没有上拉加载更多,这样是没办法满足我们的需要的,所以本文就对它进行一下定制,加上下拉刷新。

首先贴用法:

xml:

代码语言:javascript
复制
<?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="match_parent"
    android:background="#ffccee"
    android:orientation="vertical" >

    <com.utilslibrary.widget.SuperSwipeLayout
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
        </ListView>
    </com.utilslibrary.widget.SuperSwipeLayout>

</LinearLayout>

Activity 里面只需要这样设置即可:

代码语言:javascript
复制
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.utilslibrary.widget.SuperSwipeLayout;

import java.util.ArrayList;
代码语言:javascript
复制
public class SwipeRefreshLayoutActivity extends Activity {
    private SuperSwipeLayout swipeRefreshLayout;
    private ArrayList<String> data = new ArrayList<String>();
    private ArrayAdapter<String> adapter;
    int loadNum;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_swipe_refresh_layout);

        adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, data);

        swipeRefreshLayout = (SuperSwipeLayout) findViewById(R.id.swipeRefreshLayout);
        ListView listView = (ListView) findViewById(R.id.listView);

        //下拉刷新监听
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            // SwipeRefreshLayout接管其包裹的ListView下拉事件。
            // 每一次对ListView的下拉动作,将触发SwipeRefreshLayout的onRefresh()。
            @Override
            public void onRefresh() {
                System.out.println("======fresh...");
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        adapter.clear();
                        for(int i = 0; i < 20; i ++){
                            adapter.add(i + "");
                        }
                        swipeRefreshLayout.stopFreshing(false);
                        loadNum = 0;
                    }
                }, 3500);
            }
        });

        //加载更多的监听
        swipeRefreshLayout.setOnReLoadListener(new SuperSwipeLayout.OnReLoadListener() {
            @Override
            public void onLoad() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        for(int i = 0; i < 10; i ++){
                            data.add("loadMore: " + loadNum + " - " + i);
                        }
                        //一页的更多加载完了
                        swipeRefreshLayout.stopReLoad();
                        adapter.notifyDataSetChanged();
                        loadNum++;

                        if(loadNum >= 3){
                            //没有更多了
                            swipeRefreshLayout.ReLoadComplete();
                        }
                    }
                }, 1500);
            }
        });

        listView.setAdapter(adapter);
        swipeRefreshLayout.startRefresh();
    }
}



//看到没?用法是不是超简单?哈哈~下面看实现:


import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.drawable.AnimationDrawable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.utilslibrary.R;


/**
 * 定制SwipeRefreshLayout实现自动刷新,加载更多
 * Created by sam on 17/2/22.
 */
public class SuperSwipeLayout extends SwipeRefreshLayout {
    public static final int PULL_STATUS_NOMAL = 0;//正常狀態
    public static final int PULL_STATUS_REFRESHING = 1;//正在刷新
    public static final int PULL_STATUS_LOADMORE = 2;//正在加载更多
    public static final int PULL_STATUS_LOADMORE_STOP = 3;//已经加载完更多
    Context mContext;
    ListView mListView;
    OnReLoadListener mOnReLoadListener;
    View mFooterView;
    View mLoreMoreView;//加载更多的view
    LinearLayout mFooterLayout;//整个footer的布局
    LinearLayout mFooterLayoutGroup;//自定义footerView的父布局
    SwipeRefreshLayout.OnRefreshListener mOnRefreshListener;
    TextView mLoadMoreTextView;
    ImageView mLoadMoreImage;
    private int mStatus;
    String mReLoadingText, mNoMoreText;

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

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

    /**
     * 初始化样式
     */
    private void initRefreshStyle(){
        //加载颜色是循环播放的,只要没有完成刷新就会一直循环
        setColorSchemeResources(
                android.R.color.holo_blue_bright,
                android.R.color.holo_orange_light,
                android.R.color.holo_green_light,
                android.R.color.holo_red_light,
                android.R.color.holo_purple
        );
    }

    private void initLoadTextRes(){
        mReLoadingText = "正在加载更多...";
        mNoMoreText = "没有更多了~";
    }

    public ListView getListView(){
        return mListView;
    }

    private void init(Context context) {
        this.mContext = context;
        initRefreshStyle();
        initLoadTextRes();

        mLoreMoreView = createLoadView(context);
        mLoadMoreTextView = (TextView) mLoreMoreView.findViewWithTag("tv_loadmoer");
        mLoadMoreImage = (ImageView) mLoreMoreView.findViewWithTag("image_loading");
        mLoreMoreView.setVisibility(View.GONE);
        AnimationDrawable anim = (AnimationDrawable) mLoadMoreImage.getBackground();
        anim.start();

        mFooterLayoutGroup = new LinearLayout(mContext);
        mFooterLayoutGroup.setOrientation(LinearLayout.VERTICAL);

        mFooterLayout = new LinearLayout(mContext);
        mFooterLayout.setOrientation(LinearLayout.VERTICAL);

        LinearLayout.LayoutParams footerParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                dipToPixels(context, 45));
        footerParams.gravity = Gravity.CENTER;

        mFooterLayout.addView(mFooterLayoutGroup);//外部添加的footerView
        mFooterLayout.addView(mLoreMoreView, footerParams);//加载更多view

        mListView = new ListView(context);
        mListView.addFooterView(mFooterLayout);
        addView(mListView, new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

        mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if (mStatus == PULL_STATUS_LOADMORE_STOP) {
                    return;
                }
                // 当不滚动时
                if (mStatus != PULL_STATUS_LOADMORE
                        && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                    // 判断是否滚动到底部
                    if (view.getLastVisiblePosition() == view.getCount() - 1) {
                        if (null != mListView && mListView.getFooterViewsCount() == 0) {
                            mLoreMoreView.setVisibility(View.INVISIBLE);
                            return;
                        }

                        //加载更多佈局的代码
                        mOnReLoadListener.onLoad();
                        setStatus(PULL_STATUS_LOADMORE);
                    }
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            }
        });

        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //这里要减去footerview
                //
                int defaultViewCount = mListView.getHeaderViewsCount() + mListView.getFooterViewsCount();

                if (null != mOnReLoadListener && mListView.getCount() > defaultViewCount) {
                    mLoreMoreView.setVisibility(View.VISIBLE);
                    System.out.println("===onGlobalLayout " + mListView.getCount());
                    return;
                }
            }
        });
    }

    private View createLoadView(Context context){
        LinearLayout layout = new LinearLayout(context);
        layout.setOrientation(LinearLayout.HORIZONTAL);

        ImageView imageView = new ImageView(context);
        imageView.setTag("image_loading");

        TextView textView = new TextView(context);
        textView.setTag("tv_loadmoer");

        LinearLayout.LayoutParams imageParams = new LinearLayout.LayoutParams(dipToPixels(context, 40),
                dipToPixels(context, 40));
        imageParams.gravity = Gravity.CENTER;
        imageView.setBackgroundResource(R.drawable.progressbar);
        layout.addView(imageView, imageParams);

        LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT);
        textParams.gravity = Gravity.CENTER;
        layout.addView(textView, textParams);
        return layout;
    }

    private int dipToPixels(Context context, float dip){
        return (int)(context.getResources().getDisplayMetrics().density * dip);
    }

    private void setStatus(int status){
        mStatus = status;

        switch (status){
            case PULL_STATUS_NOMAL:
                mLoadMoreTextView.setText(mReLoadingText);
                break;
            case PULL_STATUS_LOADMORE:
                mLoreMoreView.setVisibility(View.VISIBLE);
                mLoadMoreImage.setVisibility(View.VISIBLE);
                mLoadMoreTextView.setText(mReLoadingText);
                break;
            case PULL_STATUS_LOADMORE_STOP:
                mLoadMoreTextView.setText(mNoMoreText);
                mLoadMoreImage.setVisibility(View.GONE);
                break;
            case PULL_STATUS_REFRESHING:

                break;
        }
    }

    /**
     * 更多加载完成
     */
    public void stopReLoad(){
        setStatus(PULL_STATUS_NOMAL);
    }

    /**
     * 没有更多了~
     */
    public void ReLoadComplete(){
        setStatus(PULL_STATUS_LOADMORE_STOP);
    }

    /**
     * 这里说一下,一般listview加载更多是没有footerview的,
     * 但我这样把它加进去了,mFooterLayout是整个footerview的容器,是线性布局的,当然你也可以改
     * 加载更多的view会拼在addFooterView这个传进来的view下面
     * @param footerView
     */
    public void addFooterView(View footerView){
        if(null == mFooterLayoutGroup || mFooterLayoutGroup.getChildCount() > 0){
            return;
        }

        mFooterLayoutGroup.addView(footerView,
                new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    }

    public void removeFooterView(){
        if(null != mFooterLayoutGroup && mFooterLayoutGroup.getChildCount() > 0){
            mFooterLayoutGroup.removeAllViews();
        }
    }

    /**
     * 自动刷新
     */
    public void startRefresh(){
        this.post(new Runnable() {

            @Override
            public void run() {
                setStatus(PULL_STATUS_REFRESHING);
                setRefreshing(true);
                mOnRefreshListener.onRefresh();
            }
        });
    }

    public void stopFreshing(boolean fresh){
        if(fresh){
            setStatus(PULL_STATUS_REFRESHING);
        }else{
            setStatus(PULL_STATUS_NOMAL);
        }
        super.setRefreshing(fresh);
    }

    public void setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener){
        mOnRefreshListener = listener;
        super.setOnRefreshListener(mOnRefreshListener);
    }

    public void setOnReLoadListener(OnReLoadListener listener){
        this.mOnReLoadListener = listener;
    }

    public interface OnReLoadListener{
        public void onLoad();
    }

}




 
 

                                                        发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/152935.html原文链接:https://javaforall.cn
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档