package com.marshalchen.common.uimodule.superlistview;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewStub;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ListAdapter;
import com.marshalchen.common.uimodule.R;
/**
* Created by kentin on 24/04/14.
*/
public abstract class BaseSuperAbsListview extends FrameLayout implements AbsListView.OnScrollListener {
protected int ITEM_LEFT_TO_LOAD_MORE = 10;
protected ViewStub mProgress;
protected ViewStub mMoreProgress;
protected AbsListView mList;
protected ViewStub mEmpty;
protected float mDividerHeight;
protected int mDivider;
protected boolean mClipToPadding;
protected int mPadding;
protected int mPaddingTop;
protected int mPaddingBottom;
protected int mPaddingLeft;
protected int mPaddingRight;
protected int mScrollbarStyle;
protected int mEmptyId;
protected int mMoreProgressId;
protected AbsListView.OnScrollListener mOnScrollListener;
protected OnMoreListener mOnMoreListener;
protected boolean isLoadingMore;
protected int mSelector;
protected SwipeRefreshLayout mPtrLayout;
protected int mSuperListViewMainLayout;
private int mProgressId;
public SwipeRefreshLayout getSwipeToRefresh() {
return mPtrLayout;
}
public AbsListView getList() {
return mList;
}
public BaseSuperAbsListview(Context context) {
super(context);
initView();
}
public BaseSuperAbsListview(Context context, AttributeSet attrs) {
super(context, attrs);
initAttrs(attrs);
initView();
}
public BaseSuperAbsListview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initAttrs(attrs);
initView();
}
protected void initAttrs(AttributeSet attrs) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.superlistview);
try {
mClipToPadding = a.getBoolean(R.styleable.superlistview_superlv__listClipToPadding, false);
mDivider = a.getColor(R.styleable.superlistview_superlv__listDivider, 0);
mDividerHeight = a.getDimension(R.styleable.superlistview_superlv__listDividerHeight, 0.0f);
mPadding = (int) a.getDimension(R.styleable.superlistview_superlv__listPadding, -1.0f);
mPaddingTop = (int) a.getDimension(R.styleable.superlistview_superlv__listPaddingTop, 0.0f);
mPaddingBottom = (int) a.getDimension(R.styleable.superlistview_superlv__listPaddingBottom, 0.0f);
mPaddingLeft = (int) a.getDimension(R.styleable.superlistview_superlv__listPaddingLeft, 0.0f);
mPaddingRight = (int) a.getDimension(R.styleable.superlistview_superlv__listPaddingRight, 0.0f);
mScrollbarStyle = a.getInt(R.styleable.superlistview_superlv__scrollbarStyle, -1);
mEmptyId = a.getResourceId(R.styleable.superlistview_superlv__empty, 0);
mMoreProgressId = a.getResourceId(R.styleable.superlistview_superlv__moreProgress, R.layout.super_list_view_view_more_progress);
mProgressId = a.getResourceId(R.styleable.superlistview_superlv__progress, R.layout.super_list_view_view_progress_gridview);
mSelector = a.getResourceId(R.styleable.superlistview_superlv__listSelector, 0);
} finally {
a.recycle();
}
}
private void initView() {
if (isInEditMode()) {
return;
}
View v = LayoutInflater.from(getContext()).inflate(mSuperListViewMainLayout, this);
mPtrLayout = (SwipeRefreshLayout) v.findViewById(R.id.ptr_layout);
mPtrLayout.setEnabled(false);
mProgress = (ViewStub) v.findViewById(android.R.id.progress);
mProgress.setLayoutResource(mProgressId);
mProgress.inflate();
mMoreProgress = (ViewStub) v.findViewById(R.id.more_progress);
mMoreProgress.setLayoutResource(mMoreProgressId);
if (mMoreProgressId != 0)
mMoreProgress.inflate();
mMoreProgress.setVisibility(View.GONE);
mEmpty = (ViewStub) v.findViewById(R.id.empty);
mEmpty.setLayoutResource(mEmptyId);
if (mEmptyId != 0)
mEmpty.inflate();
mEmpty.setVisibility(View.GONE);
initAbsListView(v);
}
/**
* Implement this method to customize the AbsListView
*/
protected abstract void initAbsListView(View view);
/**
* Set the adapter to the listview
* Automativally hide the progressbar
* Set the refresh to false
* If adapter is empty, then the emptyview is shown
*
* @param adapter
*/
public void setAdapter(ListAdapter adapter) {
mProgress.setVisibility(View.GONE);
if (mEmpty != null && mEmptyId != 0)
mList.setEmptyView(mEmpty);
mList.setVisibility(View.VISIBLE);
mPtrLayout.setRefreshing(false);
adapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
mProgress.setVisibility(View.GONE);
isLoadingMore = false;
mPtrLayout.setRefreshing(false);
if (mList.getAdapter().getCount() == 0 && mEmptyId != 0) {
mEmpty.setVisibility(View.VISIBLE);
} else if (mEmptyId != 0) {
mEmpty.setVisibility(View.GONE);
}
}
});
if ((adapter == null || adapter.getCount() == 0) && mEmptyId != 0) {
mEmpty.setVisibility(View.VISIBLE);
}
}
/**
* Remove the adapter from the listview
*/
public abstract void clear();
/**
* Show the progressbar
*/
public void showProgress() {
hideList();
if (mEmptyId != 0) mEmpty.setVisibility(View.INVISIBLE);
mProgress.setVisibility(View.VISIBLE);
}
/**
* Hide the progressbar and show the listview
*/
public void showList() {
hideProgress();
mList.setVisibility(View.VISIBLE);
}
public void showMoreProgress() {
mMoreProgress.setVisibility(View.VISIBLE);
}
public void hideMoreProgress() {
mMoreProgress.setVisibility(View.GONE);
}
/**
* Set the listener when refresh is triggered and enable the SwipeRefreshLayout
*
* @param listener
*/
public void setRefreshListener(SwipeRefreshLayout.OnRefreshListener listener) {
mPtrLayout.setEnabled(true);
mPtrLayout.setOnRefreshListener(listener);
}
/**
* Set the colors for the SwipeRefreshLayout states
*
* @param col1
* @param col2
* @param col3
* @param col4
*/
public void setRefreshingColor(int col1, int col2, int col3, int col4) {
mPtrLayout.setColorScheme(col1, col2, col3, col4);
}
/**
* Hide the progressbar
*/
public void hideProgress() {
mProgress.setVisibility(View.GONE);
}
/**
* Hide the listview
*/
public void hideList() {
mList.setVisibility(View.GONE);
}
/**
* Set the scroll listener for the listview
*
* @param listener
*/
public void setOnScrollListener(AbsListView.OnScrollListener listener) {
mOnScrollListener = listener;
}
/**
* Set the onItemClickListener for the listview
*
* @param listener
*/
public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
mList.setOnItemClickListener(listener);
}
/**
* @return the listview adapter
*/
public ListAdapter getAdapter() {
return mList.getAdapter();
}
private int getFirstVisiblePosition() {
return mList.getFirstVisiblePosition();
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (mOnScrollListener != null) mOnScrollListener.onScrollStateChanged(view, scrollState);
}
/**
* Sets the More listener
*
* @param onMoreListener
* @param max Number of items before loading more
*/
public void setupMoreListener(OnMoreListener onMoreListener, int max) {
mOnMoreListener = onMoreListener;
ITEM_LEFT_TO_LOAD_MORE = max;
}
public void setOnMoreListener(OnMoreListener onMoreListener) {
mOnMoreListener = onMoreListener;
}
public void setNumberBeforeMoreIsCalled(int max) {
ITEM_LEFT_TO_LOAD_MORE = max;
}
public boolean isLoadingMore() {
return isLoadingMore;
}
/**
* Enable/Disable the More event
*
* @param isLoadingMore
*/
public void setLoadingMore(boolean isLoadingMore) {
this.isLoadingMore = isLoadingMore;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
if (((totalItemCount - firstVisibleItem - visibleItemCount) == ITEM_LEFT_TO_LOAD_MORE || (totalItemCount - firstVisibleItem - visibleItemCount) == 0 && totalItemCount > visibleItemCount) && !isLoadingMore) {
isLoadingMore = true;
if (mOnMoreListener != null) {
mMoreProgress.setVisibility(View.VISIBLE);
mOnMoreListener.onMoreAsked(mList.getAdapter().getCount(), ITEM_LEFT_TO_LOAD_MORE, firstVisibleItem);
}
}
if (mOnScrollListener != null)
mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
/**
* Remove the moreListener
*/
public void removeMoreListener() {
mOnMoreListener = null;
}
public void setOnTouchListener(OnTouchListener listener) {
mList.setOnTouchListener(listener);
}
}