/**
* @file XListView.java
* @package me.maxwin.view
* @create Mar 18, 2012 6:28:41 PM
* @author Maxwin
* @description An ListView support (a) Pull down to refresh, (b) Pull up to load more.
* Implement IXListViewListener, and see stopRefresh() / stopLoadMore().
*/
package me.maxwin.view;
import me.maxwin.R;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.ScaleAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;
public class XListView extends ListView implements OnScrollListener {
private float mLastY = -1; // save event y
private Scroller mScroller; // used for scroll back
private OnScrollListener mScrollListener; // user's scroll listener
// the interface to trigger refresh and load more.
private IXListViewListener mListViewListener;
// -- header view
private XListViewHeader mHeaderView;
// header view content, use it to calculate the Header's height. And hide it
// when disable pull refresh.
private RelativeLayout mHeaderViewContent;
private TextView mHeaderTimeView;
private int mHeaderViewHeight; // header view's height
private boolean mEnablePullRefresh = true;
private boolean mPullRefreshing = false; // is refreashing.
// -- footer view
private XListViewFooter mFooterView;
private boolean mEnablePullLoad;
private boolean mPullLoading;
private boolean mIsFooterReady = false;
// total list items, used to detect is at the bottom of listview.
private int mTotalItemCount;
// for mScroller, scroll back from header or footer.
private int mScrollBack;
private final static int SCROLLBACK_HEADER = 0;
private final static int SCROLLBACK_FOOTER = 1;
private final static int SCROLL_DURATION = 400; // scroll back duration
private final static int PULL_LOAD_MORE_DELTA = 50; // when pull up >= 50px
// at bottom, trigger
// load more.
private final static float OFFSET_RADIO = 1.8f; // support iOS like pull
// feature.
private int slidePosition, preSlidePosition;
private int downY;
private int downX;
public static View itemView, preItemView;
// private Scroller scroller;
private static final int SNAP_VELOCITY = 600;
private VelocityTracker velocityTracker;
public static boolean isSlide = false;
private boolean isResponse = true;
public static boolean isObstruct = true;
private int mTouchSlop;
private RemoveListener mRemoveListener;
private static Animation scaleHideAnimation;
private static Animation scaleShowAnimation;
/**
* @param context
*/
public XListView(Context context) {
super(context);
initWithContext(context);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
public XListView(Context context, AttributeSet attrs) {
super(context, attrs);
initWithContext(context);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
public XListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// mScroller = new Scroller(context, new DecelerateInterpolator());
initWithContext(context);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
private void initWithContext(Context context) {
mScroller = new Scroller(context, new DecelerateInterpolator());
// XListView need the scroll event, and it will dispatch the event to
// user's listener (as a proxy).
super.setOnScrollListener(this);
// init header view
mHeaderView = new XListViewHeader(context);
mHeaderViewContent = (RelativeLayout) mHeaderView
.findViewById(R.id.xlistview_header_content);
mHeaderTimeView = (TextView) mHeaderView
.findViewById(R.id.xlistview_header_time);
addHeaderView(mHeaderView);
// init footer view
mFooterView = new XListViewFooter(context);
// init header height
mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mHeaderViewHeight = mHeaderViewContent.getHeight();
getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
});
}
@Override
public void setAdapter(ListAdapter adapter) {
// make sure XListViewFooter is the last footer view, and only add once.
if (mIsFooterReady == false) {
mIsFooterReady = true;
addFooterView(mFooterView);
}
super.setAdapter(adapter);
}
/**
* enable or disable pull down refresh feature.
*
* @param enable
*/
public void setPullRefreshEnable(boolean enable) {
mEnablePullRefresh = enable;
if (!mEnablePullRefresh) { // disable, hide the content
mHeaderViewContent.setVisibility(View.INVISIBLE);
} else {
mHeaderViewContent.setVisibility(View.VISIBLE);
}
}
/**
* enable or disable pull up load more feature.
*
* @param enable
*/
public void setPullLoadEnable(boolean enable) {
mEnablePullLoad = enable;
if (!mEnablePullLoad) {
mFooterView.hide();
mFooterView.setOnClickListener(null);
} else {
mPullLoading = false;
mFooterView.show();
mFooterView.setState(XListViewFooter.STATE_NORMAL);
// both "pull up" and "click" will invoke load more.
mFooterView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startLoadMore();
}
});
}
}
/**
* stop refresh, reset header view.
*/
public void stopRefresh() {
if (mPullRefreshing == true) {
mPullRefreshing = false;
resetHeaderHeight();
}
}
/**
* stop load more, reset footer view.
*/
public void stopLoadMore() {
if (mPullLoading == true) {
mPullLoading = false;
mFooterView.setState(XListViewFooter.STATE_NORMAL);
}
}
/**
* set last refresh time
*
* @param time
*/
public void setRefreshTime(String time) {
mHeaderTimeView.setText(time);
}
private void invokeOnScrolling() {
if (mScrollListener instanceof OnXScrollListener) {
OnXScrollListener l = (OnXScrollListener) mScrollListener;
l.onXScrolling(this);
}
}
private void updateHeaderHeight(float delta) {
mHeaderView.setVisiableHeight((int) delta
+ mHeaderView.getVisiableHeight());
if (mEnablePullRefresh && !mPullRefreshing) { // 未处于刷新状态,更新箭头
if (mHeaderView.getVisiableHeight() > mHeaderViewHeight) {
mHeaderView.setState(XListViewHeader.STATE_READY);
} else {
mHeaderView.setState(XListViewHeader.STATE_NORMAL);
}
}
setSelection(0); // scroll to top each time
}
/**
* reset header view's height.
*/
private void resetHeaderHeight() {
int height = mHeaderView.getVisiableHeight();
if (height == 0) // not visible.
return;
// refreshing and header isn't shown fully. do nothing.
if (mPullRefreshing && height <= mHeaderViewHeight) {
return;
}
int finalHeight = 0; // default: scroll back to dismiss header.
// is refreshing, just scroll back to show all the header.
if (mPullRefreshing && height > mHeaderViewHeight) {
finalHeight = mHeaderViewHeight;
}
mScrollBack = SCROLLBACK_HEADER;
mScroller.startScroll(0, height, 0, finalHeight - height,
SCROLL_DURATION);
// trigger computeScroll
invalidate();
}
private void updateFooterHeight(float delta) {
int height = mFooterView.getBottomMargin() + (int) delta;
if (mEnablePullLoad && !mPullLoading) {
if (height > PULL_LOAD_MORE_DELTA) { // height enough to invoke load
// more.
mFooterV
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Android Demo下拉刷新+加载更多.zip (69个子文件)
Android Demo下拉刷新+加载更多
bin
classes.dex 29KB
res
drawable-ldpi
ic_launcher.png 2KB
drawable-hdpi
xlistview_arrow.png 380B
btn_del_bg.9.png 437B
ic_launcher.png 4KB
update.png 1KB
drawable-mdpi
ic_launcher.png 2KB
XListView.apk 34KB
jarlist.cache 120B
dexedLibs
annotations-3446ef193e7d7709dee655a3ecea17a0.jar 943B
classes
me
maxwin
XListViewActivity$1.class 1KB
BuildConfig.class 327B
R$layout.class 517B
R$id.class 980B
R$drawable.class 483B
XListViewActivity$2.class 818B
ItemActivity.class 2KB
view
XListView$1.class 1KB
XListView$OnXScrollListener.class 371B
XListView$IXListViewListener.class 262B
XListView$3$1.class 1KB
XListView$2.class 754B
XListView$3.class 2KB
XListViewHeader.class 3KB
XListViewFooter.class 3KB
XListView$4.class 1KB
XListView.class 12KB
XListView$RemoveListener.class 235B
R$attr.class 313B
R.class 505B
R$string.class 709B
ItemAdapter$ViewHolder.class 553B
ItemAdapter.class 2KB
R$anim.class 466B
XListViewActivity.class 5KB
resources.ap_ 20KB
AndroidManifest.xml 767B
res
drawable-ldpi
ic_launcher.png 2KB
drawable-hdpi
xlistview_arrow.png 1KB
btn_del_bg.9.png 305B
ic_launcher.png 4KB
update.png 2KB
drawable-xhdpi
values
strings.xml 619B
drawable-mdpi
ic_launcher.png 3KB
anim
remain_original_location.xml 347B
slide_out_to_right.xml 351B
slide_in_from_right.xml 356B
layout
list_item.xml 2KB
activity_item.xml 551B
xlistview_footer.xml 991B
main.xml 651B
xlistview_header.xml 2KB
assets
gen
me
maxwin
BuildConfig.java 151B
R.java 3KB
proguard.cfg 1KB
.settings
org.eclipse.core.resources.prefs 57B
org.eclipse.core.runtime.prefs 52B
org.eclipse.jdt.core.prefs 177B
src
me
maxwin
ItemAdapter.java 2KB
view
XListView.java 16KB
XListViewHeader.java 4KB
XListViewFooter.java 3KB
ItemActivity.java 1014B
XListViewActivity.java 3KB
README 162B
.project 812B
.classpath 475B
project.properties 383B
AndroidManifest.xml 767B
共 69 条
- 1
资源评论
- 光强2016-01-25经测试还是可用的
- qq_152271692016-01-11学习了 非常需要这个
华少ss
- 粉丝: 5810
- 资源: 48
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功