/*
* Copyright (C) 2013 www.418log.org
*
* 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.ab.view.pullview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.DecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ProgressBar;
import android.widget.Scroller;
import com.ab.view.listener.AbOnListViewListener;
// TODO: Auto-generated Javadoc
/**
* The Class AbPullGridView.
*/
public class AbPullGridView extends AbBaseGridView implements OnScrollListener,OnTouchListener {
/** The m last y. */
private float mLastY = -1;
/** The m scroller. */
private Scroller mScroller;
/** 头部刷新View. */
private AbListViewHeader mHeaderView;
/** The m footer view. */
private AbListViewFooter mFooterView;
/** 头部View的高度. */
private int mHeaderViewHeight;
/** The m enable pull refresh. */
private boolean mEnablePullRefresh = true;
/** The m enable pull load. */
private boolean mEnablePullLoad = true;
/** The m pull refreshing. */
private boolean mPullRefreshing = false;
/** The m pull loading. */
private boolean mPullLoading;
/** The m ab on refresh listener. */
private AbOnListViewListener mListViewListener = null;
/** The m scroll back. */
private int mScrollBack;
/** The Constant SCROLLBACK_HEADER. */
private final static int SCROLLBACK_HEADER = 0;
/** The Constant SCROLL_DURATION. */
private final static int SCROLL_DURATION = 200;
/** The Constant OFFSET_RADIO. */
private final static float OFFSET_RADIO = 1.8f;
/** The m grid view. */
private GridView mGridView = null;
/** 数据相关. */
private BaseAdapter mAdapter = null;
/** 外层是否可滚动. */
private boolean childScrollState = false;
/**上一次的数量*/
private int count = 0;
/** 总条数. */
private int mTotalItemCount;
/**
* 构造..
*
* @param context the context
*/
public AbPullGridView(Context context) {
super(context);
initView(context);
}
/**
* 构造.
*
* @param context the context
* @param attrs the attrs
*/
public AbPullGridView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
/**
* Inits the with context.
*
* @param context the context
*/
private void initView(Context context) {
mScroller = new Scroller(context, new DecelerateInterpolator());
// init header view
mHeaderView = new AbListViewHeader(context);
// init header height
mHeaderViewHeight = mHeaderView.getHeaderHeight();
mHeaderView.setGravity(Gravity.BOTTOM);
addHeaderView(mHeaderView);
mGridView = this.getGridView();
mGridView.setCacheColorHint(context.getResources().getColor(android.R.color.transparent));
//默认值 自定义可以到Activity中修改
mGridView.setColumnWidth(150);
mGridView.setGravity(Gravity.CENTER);
mGridView.setHorizontalSpacing(5);
mGridView.setNumColumns(GridView.AUTO_FIT);
mGridView.setPadding(5, 5, 5, 5);
mGridView.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
mGridView.setVerticalSpacing(5);
mGridView.setOnScrollListener(this);
mGridView.setOnTouchListener(this);
// init footer view
mFooterView = new AbListViewFooter(context);
addFooterView(mFooterView);
//默认是打开刷新与更多
setPullRefreshEnable(true);
setPullLoadEnable(true);
//先隐藏
mFooterView.hide();
}
/**
* 打开或者关闭下拉刷新功能.
*
* @param enable 开关标记
*/
public void setPullRefreshEnable(boolean enable) {
mEnablePullRefresh = enable;
if (!mEnablePullRefresh) {
mHeaderView.setVisibility(View.INVISIBLE);
} else {
mHeaderView.setVisibility(View.VISIBLE);
}
}
/**
* 打开或者关闭加载更多功能.
*
* @param enable 开关标记
*/
public void setPullLoadEnable(boolean enable) {
mEnablePullLoad = enable;
if (!mEnablePullLoad) {
mFooterView.hide();
mFooterView.setOnClickListener(null);
} else {
mPullLoading = false;
mFooterView.setState(AbListViewFooter.STATE_READY);
//load more点击事件.
mFooterView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startLoadMore();
}
});
}
}
/**
* 停止刷新并重置header的状态.
*/
public void stopRefresh() {
if (mPullRefreshing == true) {
mPullRefreshing = false;
resetHeaderHeight();
}
}
/**
* 开始加载更多.
*/
private void startLoadMore() {
mFooterView.show();
mPullLoading = true;
mFooterView.setState(AbListViewFooter.STATE_LOADING);
if (mListViewListener != null) {
//开始下载数据
mListViewListener.onLoadMore();
}
}
/**
* 停止加载更多并重置footer的状态.
*
*/
public void stopLoadMore() {
mFooterView.hide();
mPullLoading = false;
//判断有没有更多数据了
int countNew = mAdapter.getCount();
if(countNew > count){
mFooterView.setState(AbListViewFooter.STATE_READY);
}else{
mFooterView.setState(AbListViewFooter.STATE_NO);
}
}
/**
* 更新header的高度.
*
* @param 新增的高度
*/
private void updateHeaderHeight(float delta) {
int newHeight = (int) delta + mHeaderView.getVisiableHeight();
mHeaderView.setVisiableHeight(newHeight);
if (mEnablePullRefresh && !mPullRefreshing) {
if (mHeaderView.getVisiableHeight() >= mHeaderViewHeight) {
mHeaderView.setState(AbListViewHeader.STATE_READY);
} else {
mHeaderView.setState(AbListViewHeader.STATE_NORMAL);
}
}
}
/**
* 根据状态设置Header的位置.
*/
private void resetHeaderHeight() {
//当前下拉到的高度
int height = mHeaderView.getVisiableHeight();
if (height < mHeaderViewHeight || !mPullRefreshing) {
//距离短 隐藏
mScrollBack = SCROLLBACK_HEADER;
mScroller.startScroll(0, height, 0, -1*height, SCROLL_DURATION);
}else if(height > mHeaderViewHeight || !mPullRefreshing){
//距离多的 弹回到mHeaderViewHeight
mScrollBack = SCROLLBACK_HEADER;
mScroller.startScroll(0, height, 0, -(height-mHeaderViewHeight), SCROLL_DURATION);
}
//锁定事件
childScrollState = true;
invalidate();
}
/**
* 描述:事件
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
//GridView接受事件,自己的跳过
if(childScrollState){
return false;
}
if (mLastY == -1) {
mLastY = ev.getRawY();
}
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//Log.i("TAG", "--ACTION_DOWN--");
mLastY = ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
//Log.i("TAG", "--ACTION_MOVE--");
final float deltaY = ev.getRawY() - mLastY;
mLastY = ev.getRawY();
if (mEnablePullRefresh && (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) {
//下拉更新高度
updateHeaderHeight(deltaY / OFFSET_RADIO);
} else if (mEnablePullLoad && !mPullLoading && mGridView.getLastVisiblePosition() == (mTotalItemCount-1) && deltaY<0) {
startLoadMore();
}
break;
case MotionEvent.ACTION_UP:
//Log.i("TAG", "--ACTION_UP--");
mLastY = -1;
//需要刷新的条件
if (mEnablePullRefresh && mHeaderView.getVisiableHeight() >= mHeaderViewHeight) {
mPullRefreshing = true;
mHeaderView.setState(AbListViewHeader.STATE_REFRESHING);
if (mListViewListener != null) {
//刷新
mListViewListener.onRefresh();
}
}
if(mEnablePullRefresh){
//Log.i("TAG", "--弹回--");
//弹回
resetHeaderHeight();
}
break;
default:
break;
}
return super.onTouchEvent(ev);
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
if (mScrollBack == SCROLLBACK_HEADER) {
mHeaderView.setVisiableHeight(mScroller.getCurrY());
}
postInvalidate();
}
super.computeScroll();
}
/**
* 描述:设置ListView的监听器.
*
* @param listViewListener
*/
public void setAbOnListViewListener(AbOnListViewListener listViewListener) {
mListViewListener = listViewListener;
}
/**
* 描述:设置数据列表的适配器.
* @param adapter the new adapter
*/
public void setAdapter(BaseAdapter adapter) {
mAdapter = adapter;
mGridView.setAdapter(mAdapter);
}
@Override
public boolean onTouch(View arg0, MotionEvent ev) {
return onTouchEvent(ev);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
mTotalItemCount = totalItemCount;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
// 当滚动时
case OnScrollListener.SCROLL_STATE_IDLE:
if(view.getFirstVisiblePosition() == 0){
//Log.i("TAG", "滚动到顶部");
childScrollState = false;
}else if (view.getLastVisiblePosition() == (view.getCount() - 1)) {
//Log.i("TAG", "滚动到底部");
childScrollState = false;
}else{
if(!mPullRefreshing){
childScrollState = true;
}
}
break;
case OnScrollListener.SCROLL_STATE_FLING:
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
break;
}
}
/**
*
* 描述:获取Header View
* @return
* @throws
*/
public AbListViewHeader getHeaderView() {
return mHeaderView;
}
/**
*
* 描述:获取Footer View
* @return
* @throws
*/
public AbListViewFooter getFooterView() {
return mFooterView;
}
/**
*
* 描述:获取Header ProgressBar,用于设置自定义样式
* @return
* @throws
*/
public ProgressBar getHeaderProgressBar() {
return mHeaderView.getHeaderProgressBar();
}
/**
*
* 描述:获取Footer ProgressBar,用于设置自定义样式
* @return
* @throws
*/
public ProgressBar getFooterProgressBar() {
return mFooterView.getFooterProgressBar();
}
}