com.list.helper.view.listviewhelper.SwipeListViewHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.list.helper.view.listviewhelper.SwipeListViewHelper.java

Source

/*
 * Copyright 2015 shizhefeiLuckyJayce Licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.list.helper.view.listviewhelper;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ListView;

import com.list.helper.R;
import com.list.helper.view.IRefreshPresenter;
import com.list.helper.view.listviewhelper.imp.DeFaultLoadViewFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import util.ClientInfo;
import util.SizeUtils;

/**
 * .????
 *
 * @param <DATA>
 * @author LuckyJayce
 */
public class SwipeListViewHelper<DATA> implements IListViewHelper<DATA> {
    private SwipeRefreshLayout swipeRefreshLayout;
    private ListView mListView;

    private Context context;

    private IDataAdapter<DATA> dataAdapter;
    /**
     * ????????
     */
    private boolean hasMoreData = true;
    private boolean isLoading = false;
    private boolean autoLoadMore = true;

    private boolean needShowLoadingWhenAdapterEmpty = true;

    private IRefreshPresenter refreshPresenter;
    private OnScrollListener onScrollListenerOut;
    private OnStateChangeListener<DATA> onStateChangeListener;

    private ILoadViewFactory.ILoadView mLoadView;
    private ILoadViewFactory.ILoadMoreView mLoadMoreView;

    public SwipeListViewHelper(SwipeRefreshLayout pullToRefreshAdapterViewBase) {
        this(pullToRefreshAdapterViewBase, new DeFaultLoadViewFactory().madeLoadView(),
                new DeFaultLoadViewFactory().madeLoadMoreView());
    }

    public SwipeListViewHelper(SwipeRefreshLayout pullToRefreshAdapterViewBase,
            boolean needShowLoadingWhenAdapterEmpty) {
        this(pullToRefreshAdapterViewBase, new DeFaultLoadViewFactory().madeLoadView(),
                new DeFaultLoadViewFactory().madeLoadMoreView());
        this.needShowLoadingWhenAdapterEmpty = needShowLoadingWhenAdapterEmpty;

    }

    public SwipeListViewHelper(SwipeRefreshLayout pullToRefreshAdapterViewBase,
            ILoadViewFactory.ILoadView loadView) {
        this(pullToRefreshAdapterViewBase, loadView, new DeFaultLoadViewFactory().madeLoadMoreView());
    }

    public SwipeListViewHelper(SwipeRefreshLayout swipeRefreshLayout, ILoadViewFactory.ILoadView loadView,
            ILoadViewFactory.ILoadMoreView loadMoreView) {
        super();
        this.context = swipeRefreshLayout.getContext().getApplicationContext();
        this.autoLoadMore = true;
        this.swipeRefreshLayout = swipeRefreshLayout;

        if (swipeRefreshLayout.getParent() == null) {
            throw new RuntimeException("PtrClassicFrameLayout Parent");
        }
        swipeRefreshLayout.setColorSchemeColors(context.getResources().getColor(R.color.color_04a6e9));
        try {
            Method method = swipeRefreshLayout.getClass().getDeclaredMethod("ensureTarget");
            method.setAccessible(true);
            method.invoke(swipeRefreshLayout);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            Field field = swipeRefreshLayout.getClass().getDeclaredField("mTarget");
            field.setAccessible(true);
            mListView = (ListView) field.get(swipeRefreshLayout);
        } catch (Exception e) {
            e.printStackTrace();
        }
        mListView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        mListView.setCacheColorHint(Color.TRANSPARENT);
        mListView.setOnScrollListener(onScrollListener);
        mListView.setOnItemSelectedListener(onItemSelectedListener);

        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refresh();
            }
        });

        mLoadView = loadView;
        mLoadView.init(swipeRefreshLayout, onClickRefreshListener);

        mLoadMoreView = loadMoreView;
        mLoadMoreView.init(mListView, onClickLoadMoreListener);
    }

    /**
     * ???
     *
     * @param refreshPresenter
     */
    public void setRefreshPresenter(IRefreshPresenter refreshPresenter) {
        this.refreshPresenter = refreshPresenter;
    }

    /**
     * ??
     *
     * @param adapter
     */
    public void setAdapter(IDataAdapter<DATA> adapter) {
        mListView.setAdapter(adapter);
        this.dataAdapter = adapter;
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        mListView.setOnItemClickListener(onItemClickListener);
    }

    @Override
    public void setOnItemLongClickListener(AdapterView.OnItemLongClickListener onItemLongClickListener) {
        mListView.setOnItemLongClickListener(onItemLongClickListener);
    }

    @Override
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListenerOut = onScrollListener;
    }

    @Override
    public void setDivider(int ColorId) {
        mListView.setDivider(new ColorDrawable(ColorId));
    }

    @Override
    public void setDividerHeight(int dip) {
        mListView.setDividerHeight(SizeUtils.dip2px(context, dip));
    }

    @Override
    public void setFooterDividersEnabled(boolean enabled) {
        mListView.setFooterDividersEnabled(enabled);
    }

    @Override
    public void setHeaderDividersEnabled(boolean enabled) {
        mListView.setHeaderDividersEnabled(enabled);
    }

    @Override
    public void addHeaderView(View view) {
        mListView.addHeaderView(view);
    }

    private void showUIWhenRefresh() {
        if (dataAdapter == null || refreshPresenter == null) {
            if (swipeRefreshLayout != null) {
                swipeRefreshLayout.setRefreshing(false);
            }
            return;
        }
        isLoading = true;
        // mLoadMoreView.showNormal();
        if (dataAdapter.isEmpty()) {
            if (needShowLoadingWhenAdapterEmpty) {
                mLoadView.showLoading();
                swipeRefreshLayout.setRefreshing(false);
            }
        } else {
            if (!swipeRefreshLayout.isRefreshing()) {
                swipeRefreshLayout.setRefreshing(true);
            }
        }
        if (onStateChangeListener != null) {
            onStateChangeListener.onStartRefresh(dataAdapter);
        }
    }

    public void refresh() {
        showUIWhenRefresh();
        refreshPresenter.refreshRequest();
    }

    public void refreshWithCache() {
        showUIWhenRefresh();
        swipeRefreshLayout.postDelayed(new Runnable() {

            @Override
            public void run() {
                refreshPresenter.getCacheData();
                refreshPresenter.refreshRequest();
            }
        }, 500);

    }

    @Override
    public void refreshWithCacheNoDelay() {
        showUIWhenRefresh();
        refreshPresenter.getCacheData();
        refreshPresenter.refreshRequest();
    }

    @Override
    public void refreshComplete(DATA result) {
        if (result == null) {
            swipeRefreshLayout.setRefreshing(false);
            swipeRefreshLayout.postDelayed(new Runnable() {

                @Override
                public void run() {
                    if (dataAdapter.isEmpty()) {
                        mLoadView.showFail();
                    } else {
                        mLoadView.tipFail();
                    }
                    isLoading = false;
                }
            }, 200);
        } else {
            swipeRefreshLayout.setRefreshing(false);
            dataAdapter.setData(result, true);
            dataAdapter.notifyDataSetChanged();
            swipeRefreshLayout.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (dataAdapter.isEmpty()) {
                        mLoadView.showEmpty();
                    } else {
                        mLoadView.restore();
                        mListView.setSelection(0);
                    }
                    hasMoreData = refreshPresenter.hasData();
                    if (hasMoreData) {
                        mLoadMoreView.showNormal();
                    } else {
                        mLoadMoreView.showNomore();
                    }
                    isLoading = false;
                }
            }, 200);
        }
        if (onStateChangeListener != null) {
            onStateChangeListener.onEndRefresh(dataAdapter, result);
        }

    }

    @Override
    public void loadMore() {
        if (isLoading()) {
            return;
        }
        if (dataAdapter.isEmpty()) {
            refresh();
            return;
        }
        if (dataAdapter == null || refreshPresenter == null) {
            if (swipeRefreshLayout != null) {
                new Handler().postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        swipeRefreshLayout.setRefreshing(false);
                    }
                }, 200);
            }
            return;
        }
        isLoading = true;
        if (onStateChangeListener != null) {
            onStateChangeListener.onStartLoadMore(dataAdapter);
        }
        mLoadMoreView.showLoading();

        refreshPresenter.loadMoreRequest();
    }

    @Override
    public void loadMoreDataComplete(DATA result) {
        if (result == null) {
            mLoadView.tipFail();
            mLoadMoreView.showFail();
        } else {
            dataAdapter.setData(result, false);
            dataAdapter.notifyDataSetChanged();
            if (dataAdapter.isEmpty()) {
                mLoadView.showEmpty();
            } else {
                mLoadView.restore();
            }
            hasMoreData = refreshPresenter.hasData();
            if (hasMoreData) {
                mLoadMoreView.showNormal();
            } else {
                mLoadMoreView.showNomore();
            }
        }
        if (onStateChangeListener != null) {
            onStateChangeListener.onEndLoadMore(dataAdapter, result);
        }
        isLoading = false;
    }

    @Override
    public void updateList() {
        dataAdapter.notifyDataSetChanged();
        if (dataAdapter.isEmpty()) {
            mLoadView.showEmpty();
        } else {
            mLoadView.restore();
        }
        hasMoreData = refreshPresenter.hasData();
        if (hasMoreData) {
            mLoadMoreView.showNormal();
        } else {
            mLoadMoreView.showNomore();
        }
    }

    public void sethasMoreData(boolean hasMoreData) {
        this.hasMoreData = hasMoreData;
    }

    @Override
    public void clearData() {
        dataAdapter.clearData();
    }

    @Override
    public DATA getData() {
        return dataAdapter.getData();
    }

    @Override
    public boolean isLoading() {
        return isLoading;
    }

    @Override
    public void setLoading(boolean isLoading) {
        this.isLoading = isLoading;
    }

    @Override
    public ListView getListView() {
        return mListView;
    }

    @Override
    public IDataAdapter<DATA> getAdapter() {
        return dataAdapter;
    }

    private OnClickListener onClickLoadMoreListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            loadMore();
        }
    };

    private OnClickListener onClickRefreshListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            clearData();
            refresh();
        }
    };
    /**
     * ?
     */
    private OnScrollListener onScrollListener = new OnScrollListener() {

        @Override
        public void onScrollStateChanged(AbsListView listView, int scrollState) {
            if (autoLoadMore) {
                if (hasMoreData) {
                    if (!swipeRefreshLayout.isRefreshing()) {// ??

                        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
                                && listView.getLastVisiblePosition() + 1 == listView.getCount()) {// ?

                            // ?

                            if (ClientInfo.hasNetwork(context)) {
                                loadMore();
                            } else {
                                if (!isLoading()) {
                                    mLoadMoreView.showFail();
                                }
                            }
                        }
                    }
                }
            }
            if (onScrollListenerOut != null) {
                onScrollListenerOut.onScrollStateChanged(listView, scrollState);
            }
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            if (onScrollListenerOut != null) {
                onScrollListenerOut.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
            }
        }

    };
    /**
     *  ?
     */
    private OnItemSelectedListener onItemSelectedListener = new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> listView, View view, int position, long id) {
            if (autoLoadMore) {
                if (hasMoreData) {
                    if (listView.getLastVisiblePosition() + 1 == listView.getCount()) {// ?
                        // ?
                        if (ClientInfo.hasNetwork(context)) {
                            loadMore();
                        }
                    }
                }
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

}