下拉刷新与上拉加载更多

代码如下:

/**
 * ListView下拉刷新和加载更多
 * <p>
 *
 * <strong>变更说明:</strong>
 * <p>
 * 默认如果设置了OnRefreshListener接口和OnLoadMoreListener接口
 * <p>
 * 剩余三个Flag: <br>
 * mIsAutoLoadMore(是否自动加载更多) <br>
 * mIsMoveToFirstItemAfterRefresh(下拉刷新后是否显示第一条Item) <br>
 * mIsDoRefreshOnWindowFocused(当该ListView所在的控件显示到屏幕上时,是否直接显示正在刷新...)
 *
 * @author lee
 */
public class MongoPullToRefreshOrLoadMoreListView extends ListView implements
		OnScrollListener {

	/** 显示格式化日期模板 */
	private final static String DATE_FORMAT_STR = "yyyy年MM月dd日 HH:mm";

	/** 实际的padding的距离与界面上偏移距离的比例 */
	private final static int RATIO = 3;

	// ===========================以下4个常量为
	// 下拉刷新的状态标识===============================
	/** 松开刷新 */
	private final static int RELEASE_TO_REFRESH = 0;
	/** 下拉刷新 */
	private final static int PULL_TO_REFRESH = 1;
	/** 正在刷新 */
	private final static int REFRESHING = 2;
	/** 刷新完成 or 什么都没做,恢复原状态。 */
	private final static int DONE = 3;

	// ===========================以下3个常量为
	// 加载更多的状态标识===============================
	/** 加载中 */
	private final static int ENDINT_LOADING = 1;
	/** 手动完成刷新 */
	private final static int ENDINT_MANUAL_LOAD_DONE = 2;
	/** 自动完成刷新 */
	private final static int ENDINT_AUTO_LOAD_DONE = 3;

	/**
	 * <strong>下拉刷新HeadView的实时状态flag</strong>
	 *
	 * <p>
	 * 0 : RELEASE_TO_REFRESH;
	 * <p>
	 * 1 : PULL_To_REFRESH;
	 * <p>
	 * 2 : REFRESHING;
	 * <p>
	 * 3 : DONE;
	 *
	 */
	private int mHeadState;

	/**
	 * <strong>加载更多FootView(EndView)的实时状态flag</strong>
	 *
	 * <p>
	 * 0 : 完成/等待刷新 ;
	 * <p>
	 * 1 : 加载中
	 */
	private int mEndState;

	// ================================= 功能设置Flag
	// ================================

	/** 可以加载更多否 */
	private boolean mCanLoadMore = false;

	/** 可以下拉刷新否 */
	private boolean mCanRefresh = false;

	/** 可以自动加载更多吗?(注意,先判断是否有加载更多,如果没有,这个flag也没有意义) */
	private boolean mIsAutoLoadMore = false;

	/** 下拉刷新后是否显示第一条Item */
	private boolean mIsMoveToFirstItemAfterRefresh = false;

	/** 当该ListView所在的控件显示到屏幕上时,是否直接显示正在刷新... */
	private boolean mIsDoRefreshOnUIChanged = false;

	public boolean isCanLoadMore() {
		return mCanLoadMore;
	}

	public void setCanLoadMore(boolean pCanLoadMore) {
		mCanLoadMore = pCanLoadMore;
		if (mCanLoadMore && getFooterViewsCount() == 0) {
			addFooterView();
		} else {
			if (null != mEndRootView) {
				removeFooterView(mEndRootView);
			}
		}
	}

	public boolean isCanRefresh() {
		return mCanRefresh;
	}

	public void setCanRefresh(boolean pCanRefresh) {
		mCanRefresh = pCanRefresh;
	}

	public boolean isAutoLoadMore() {
		return mIsAutoLoadMore;
	}

	public void setAutoLoadMore(boolean pIsAutoLoadMore) {
		mIsAutoLoadMore = pIsAutoLoadMore;
	}

	public boolean isMoveToFirstItemAfterRefresh() {
		return mIsMoveToFirstItemAfterRefresh;
	}

	public void setMoveToFirstItemAfterRefresh(
			boolean pIsMoveToFirstItemAfterRefresh) {
		mIsMoveToFirstItemAfterRefresh = pIsMoveToFirstItemAfterRefresh;
	}

	public boolean isDoRefreshOnUIChanged() {
		return mIsDoRefreshOnUIChanged;
	}

	public void setDoRefreshOnUIChanged(boolean pIsDoRefreshOnWindowFocused) {
		mIsDoRefreshOnUIChanged = pIsDoRefreshOnWindowFocused;
	}

	// ============================================================================

	private LayoutInflater mInflater;

	private LinearLayout mHeadRootView;
	private TextView mTipsTextView;
	private TextView mLastUpdatedTextView;
	private ImageView mArrowImageView;
	private ProgressBar mProgressBar;

	private View mEndRootView;
	private ProgressBar mEndLoadProgressBar;
	private TextView mEndLoadTipsTextView;

	/** headView动画 */
	private RotateAnimation mArrowAnim;
	/** headView反转动画 */
	private RotateAnimation mArrowReverseAnim;

	/** 用于保证startY的值在一个完整的touch事件中只被记录一次 */
	private boolean mIsRecored;

	private int mHeadViewWidth;
	private int mHeadViewHeight;

	private int mStartY;
	private boolean mIsBack;

	private int mFirstItemIndex;
	private int mLastItemIndex;
	private int mCount;

	@SuppressWarnings("unused")
	private boolean mEnoughCount;// 足够数量充满屏幕?

	private OnRefreshListener mRefreshListener;
	private OnLoadMoreListener mLoadMoreListener;

	private String mLabel;

	public String getLabel() {
		return mLabel;
	}

	public void setLabel(String pLabel) {
		mLabel = pLabel;
	}

	public MongoPullToRefreshOrLoadMoreListView(Context pContext) {
		super(pContext);
		init(pContext);
	}

	public MongoPullToRefreshOrLoadMoreListView(Context pContext,
			AttributeSet pAttrs) {
		super(pContext, pAttrs);
		init(pContext);
	}

	public MongoPullToRefreshOrLoadMoreListView(Context pContext,
			AttributeSet pAttrs, int pDefStyle) {
		super(pContext, pAttrs, pDefStyle);
		init(pContext);
	}

	/**
	 * 初始化操作
	 *
	 * @param pContext
	 */
	private void init(Context pContext) {
		// final ViewConfiguration _ViewConfiguration =
		// ViewConfiguration.get(pContext);
		// mTouchSlop = _ViewConfiguration.getScaledTouchSlop();

		setCacheColorHint(pContext.getResources().getColor(R.color.transparent));
		setOnLongClickListener(null);
		mInflater = LayoutInflater.from(pContext);

		addHeadView();

		setOnScrollListener(this);

		initPullImageAnimation(0);
	}

	/**
	 * 添加下拉刷新的HeadView
	 */
	private void addHeadView() {
		mHeadRootView = (LinearLayout) mInflater.inflate(
				R.layout.pull_to_refresh_head2, null);

		mArrowImageView = (ImageView) mHeadRootView
				.findViewById(R.id.head_arrowImageView);
		mArrowImageView.setMinimumWidth(70);
		mArrowImageView.setMinimumHeight(50);
		mProgressBar = (ProgressBar) mHeadRootView
				.findViewById(R.id.head_progressBar);
		mTipsTextView = (TextView) mHeadRootView
				.findViewById(R.id.head_tipsTextView);
		mLastUpdatedTextView = (TextView) mHeadRootView
				.findViewById(R.id.head_lastUpdatedTextView);

		measureView(mHeadRootView);
		mHeadViewHeight = mHeadRootView.getMeasuredHeight();
		mHeadViewWidth = mHeadRootView.getMeasuredWidth();

		mHeadRootView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
		mHeadRootView.invalidate();

		addHeaderView(mHeadRootView, null, false);

		mHeadState = DONE;
		changeHeadViewByState();
	}

	/**
	 * 添加加载更多FootView
	 */
	private void addFooterView() {
		mEndRootView = mInflater.inflate(R.layout.pull_to_refresh_load_more,
				null);
		mEndRootView.setVisibility(View.VISIBLE);
		mEndLoadProgressBar = (ProgressBar) mEndRootView
				.findViewById(R.id.pull_to_refresh_progress);
		mEndLoadTipsTextView = (TextView) mEndRootView
				.findViewById(R.id.load_more);
		mEndRootView.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				if (mCanLoadMore) {
					if (mCanRefresh) {
						if (mEndState != ENDINT_LOADING
								&& mHeadState != REFRESHING) {
							mEndState = ENDINT_LOADING;
							onLoadMore();
						}
					} else if (mEndState != ENDINT_LOADING) {
						mEndState = ENDINT_LOADING;
						onLoadMore();
					}
				}
			}
		});

		addFooterView(mEndRootView);

		if (mIsAutoLoadMore) {
			mEndState = ENDINT_AUTO_LOAD_DONE;
		} else {
			mEndState = ENDINT_MANUAL_LOAD_DONE;
		}
	}

	/**
	 * 实例化下拉刷新的箭头的动画效果
	 */
	private void initPullImageAnimation(final int pAnimDuration) {

		int _Duration;

		if (pAnimDuration > 0) {
			_Duration = pAnimDuration;
		} else {
			_Duration = 250;
		}

		Interpolator _Interpolator = new LinearInterpolator();

		mArrowAnim = new RotateAnimation(0, -180,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		mArrowAnim.setInterpolator(_Interpolator);
		mArrowAnim.setDuration(_Duration);
		mArrowAnim.setFillAfter(true);

		mArrowReverseAnim = new RotateAnimation(-180, 0,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		mArrowReverseAnim.setInterpolator(_Interpolator);
		mArrowReverseAnim.setDuration(_Duration);
		mArrowReverseAnim.setFillAfter(true);
	}

	/**
	 * 测量HeadView宽高(此方法仅适用于LinearLayout)
	 *
	 * @param pChild
	 */
	private void measureView(View pChild) {
		ViewGroup.LayoutParams p = pChild.getLayoutParams();
		if (p == null) {
			p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
		}
		int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
		int lpHeight = p.height;

		int childHeightSpec;
		if (lpHeight > 0) {
			childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
					MeasureSpec.EXACTLY);
		} else {
			childHeightSpec = MeasureSpec.makeMeasureSpec(0,
					MeasureSpec.UNSPECIFIED);
		}
		pChild.measure(childWidthSpec, childHeightSpec);
	}

	/**
	 * 为了判断滑动到ListView底部没
	 */
	@Override
	public void onScroll(AbsListView pView, int pFirstVisibleItem,
			int pVisibleItemCount, int pTotalItemCount) {
		mFirstItemIndex = pFirstVisibleItem;
		mLastItemIndex = pFirstVisibleItem + pVisibleItemCount - 2;
		mCount = pTotalItemCount - 2;
		if (pTotalItemCount > pVisibleItemCount) {
			mEnoughCount = true;
		} else {
			mEnoughCount = false;
		}
	}

	/**
	 * 加载判断。
	 */
	@Override
	public void onScrollStateChanged(AbsListView pView, int pScrollState) {
		if (mCanLoadMore) {
			if (mLastItemIndex == mCount && pScrollState == SCROLL_STATE_IDLE) {
				if (mEndState != ENDINT_LOADING) {
					if (mIsAutoLoadMore) {
						if (mCanRefresh) {
							if (mHeadState != REFRESHING) {
								mEndState = ENDINT_LOADING;
								onLoadMore();
								changeEndViewByState();
							}
						} else {
							mEndState = ENDINT_LOADING;
							onLoadMore();
							changeEndViewByState();
						}
					} else {
						mEndState = ENDINT_MANUAL_LOAD_DONE;
						changeEndViewByState();
					}
				}
			}
		} else if (mEndRootView != null
				&& mEndRootView.getVisibility() == VISIBLE) {
			mEndRootView.setVisibility(View.GONE);
			this.removeFooterView(mEndRootView);
		}
	}

	/**
	 * 改变加载更多状态
	 */
	private void changeEndViewByState() {
		if (mCanLoadMore) {
			switch (mEndState) {
			case ENDINT_LOADING: // 刷新中
				if (mEndLoadTipsTextView.getText().equals(
						R.string.p2refresh_doing_end_refresh)) {
					break;
				}
				mEndLoadTipsTextView
						.setText(R.string.p2refresh_doing_end_refresh);
				mEndLoadTipsTextView.setVisibility(View.VISIBLE);
				mEndLoadProgressBar.setVisibility(View.VISIBLE);
				break;
			case ENDINT_MANUAL_LOAD_DONE:// 手动刷新完成

				mEndLoadTipsTextView
						.setText(R.string.p2refresh_end_click_load_more);
				mEndLoadTipsTextView.setVisibility(View.VISIBLE);
				mEndLoadProgressBar.setVisibility(View.GONE);

				mEndRootView.setVisibility(View.VISIBLE);
				break;
			case ENDINT_AUTO_LOAD_DONE:// 自动刷新完成

				mEndLoadTipsTextView.setText(R.string.p2refresh_end_load_more);
				mEndLoadTipsTextView.setVisibility(View.VISIBLE);
				mEndLoadProgressBar.setVisibility(View.GONE);

				mEndRootView.setVisibility(View.VISIBLE);
				break;
			default:
				break;
			}
		}
	}

	/**
	 * 注意事项: 此方法不适用于ViewPager中, 方法为:直接调用pull2RefreshManually();
	 */
	@Override
	public void onWindowFocusChanged(boolean pHasWindowFocus) {
		super.onWindowFocusChanged(pHasWindowFocus);
		if (mIsDoRefreshOnUIChanged) {
			if (pHasWindowFocus) {
				pull2RefreshManually();
			}
		}
	}

	/**
	 * 当该ListView所在的控件显示到屏幕上时,直接显示正在刷新...
	 */
	public void pull2RefreshManually() {
		mHeadState = REFRESHING;
		changeHeadViewByState();
		onRefresh();

		mIsRecored = false;
		mIsBack = false;
	}

	/**
	 */
	public boolean onTouchEvent(MotionEvent event) {

		if (mCanRefresh) {
			if (mCanLoadMore && mEndState == ENDINT_LOADING) {
				return super.onTouchEvent(event);
			}

			switch (event.getAction()) {

			case MotionEvent.ACTION_DOWN:

				if (mFirstItemIndex == 0 && !mIsRecored) {
					mIsRecored = true;
					mStartY = (int) event.getY();
				} else if (mFirstItemIndex == 0 && mIsRecored) {
					mStartY = (int) event.getY();
				}

				break;

			case MotionEvent.ACTION_UP:

				if (mHeadState != REFRESHING) {

					if (mHeadState == DONE) {

					}
					if (mHeadState == PULL_TO_REFRESH) {
						mHeadState = DONE;
						changeHeadViewByState();
					}
					if (mHeadState == RELEASE_TO_REFRESH) {
						mHeadState = REFRESHING;
						changeHeadViewByState();
						onRefresh();
					}
				}

				mIsRecored = false;
				mIsBack = false;

				break;

			case MotionEvent.ACTION_MOVE:

				int _TempY = (int) event.getY();

				if (!mIsRecored && mFirstItemIndex == 0) {
					mIsRecored = true;
					mStartY = _TempY;
				}

				if (mHeadState != REFRESHING && mIsRecored) {

					if (mHeadState == RELEASE_TO_REFRESH) {

						setSelection(0);

						if (((_TempY - mStartY) / RATIO < mHeadViewHeight)
								&& (_TempY - mStartY) > 0) {
							mHeadState = PULL_TO_REFRESH;
							changeHeadViewByState();
						} else if (_TempY - mStartY <= 0) {
							mHeadState = DONE;
							changeHeadViewByState();
						}
					}
					if (mHeadState == PULL_TO_REFRESH) {

						setSelection(0);

						if ((_TempY - mStartY) / RATIO >= mHeadViewHeight) {
							mHeadState = RELEASE_TO_REFRESH;
							mIsBack = true;
							changeHeadViewByState();
						} else if (_TempY - mStartY <= 0) {
							mHeadState = DONE;
							changeHeadViewByState();
						}
					}

					if (mHeadState == DONE) {
						if (_TempY - mStartY > 0) {
							mHeadState = PULL_TO_REFRESH;
							changeHeadViewByState();
						}
					}

					if (mHeadState == PULL_TO_REFRESH) {
						mHeadRootView.setPadding(0, -1 * mHeadViewHeight
								+ (_TempY - mStartY) / RATIO, 0, 0);

					}

					if (mHeadState == RELEASE_TO_REFRESH) {
						mHeadRootView.setPadding(0, (_TempY - mStartY) / RATIO
								- mHeadViewHeight, 0, 0);
					}
				}
				break;
			}
		}

		return super.onTouchEvent(event);
	}

	/**
	 * 当HeadView状态改变时候,调用该方法,以更新界面
	 */
	private void changeHeadViewByState() {
		switch (mHeadState) {
		case RELEASE_TO_REFRESH:
			mArrowImageView.setVisibility(View.VISIBLE);
			mProgressBar.setVisibility(View.GONE);
			mTipsTextView.setVisibility(View.VISIBLE);
			// mLastUpdatedTextView.setVisibility(View.VISIBLE);

			mArrowImageView.clearAnimation();
			mArrowImageView.startAnimation(mArrowAnim);
			mTipsTextView.setText(R.string.p2refresh_release_refresh);

			break;
		case PULL_TO_REFRESH:
			mProgressBar.setVisibility(View.GONE);
			mTipsTextView.setVisibility(View.VISIBLE);
			// mLastUpdatedTextView.setVisibility(View.VISIBLE);
			mArrowImageView.clearAnimation();
			mArrowImageView.setVisibility(View.VISIBLE);
			if (mIsBack) {
				mIsBack = false;
				mArrowImageView.clearAnimation();
				mArrowImageView.startAnimation(mArrowReverseAnim);
				mTipsTextView.setText(R.string.p2refresh_pull_to_refresh);
			} else {
				mTipsTextView.setText(R.string.p2refresh_pull_to_refresh);
			}
			break;

		case REFRESHING:

			changeHeaderViewRefreshState();
			break;
		case DONE:

			mHeadRootView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
			mProgressBar.setVisibility(View.GONE);
			mArrowImageView.clearAnimation();
			// mArrowImageView.setImageResource(R.drawable.pulltorefresh_arrow);
			mArrowImageView.setImageResource(R.drawable.arrow_gray);
			mTipsTextView.setText(R.string.p2refresh_pull_to_refresh);
			mLastUpdatedTextView.setVisibility(View.GONE);

			break;
		}
	}

	/**
	 * 改变HeadView在刷新状态下的显示
	 */
	private void changeHeaderViewRefreshState() {
		mHeadRootView.setPadding(0, 0, 0, 0);
		mProgressBar.setVisibility(View.VISIBLE);
		mArrowImageView.clearAnimation();
		mArrowImageView.setVisibility(View.GONE);
		mTipsTextView.setText(R.string.p2refresh_doing_head_refresh);
		mLastUpdatedTextView.setVisibility(View.VISIBLE);
	}

	/**
	 * 下拉刷新监听接口
	 */
	public interface OnRefreshListener {
		public void onRefresh();
	}

	/**
	 * 加载更多监听接口
	 */
	public interface OnLoadMoreListener {
		public void onLoadMore();
	}

	public void setOnRefreshListener(OnRefreshListener pRefreshListener) {
		if (pRefreshListener != null) {
			mRefreshListener = pRefreshListener;
			mCanRefresh = true;
		}
	}

	public void setOnLoadListener(OnLoadMoreListener pLoadMoreListener) {
		if (pLoadMoreListener != null) {
			mLoadMoreListener = pLoadMoreListener;
			mCanLoadMore = true;
			if (mCanLoadMore && getFooterViewsCount() == 0) {
				addFooterView();
			}
		}
	}

	/**
	 * 正在下拉刷新
	 */
	private void onRefresh() {
		if (mRefreshListener != null) {
			mRefreshListener.onRefresh();
		}
	}

	/**
	 * 下拉刷新完成
	 */
	public void onRefreshComplete() {

		mHeadState = DONE;
		mLastUpdatedTextView.setText(getResources().getString(
				R.string.p2refresh_refresh_lasttime)
				+ new SimpleDateFormat(DATE_FORMAT_STR, Locale.CHINA)
						.format(new Date()));
		changeHeadViewByState();

		if (mIsMoveToFirstItemAfterRefresh) {
			mFirstItemIndex = 0;
			setSelection(0);
		}
	}

	/**
	 * 正在加载更多,FootView显示 : 加载中...
	 */
	private void onLoadMore() {
		if (mLoadMoreListener != null) {
			mEndLoadTipsTextView.setText(R.string.p2refresh_doing_end_refresh);
			mEndLoadTipsTextView.setVisibility(View.VISIBLE);
			mEndLoadProgressBar.setVisibility(View.VISIBLE);
			mLoadMoreListener.onLoadMore();
		}
	}

	/**
	 * 加载更多完成
	 */
	public void onLoadMoreComplete() {
		if (mIsAutoLoadMore) {
			mEndState = ENDINT_AUTO_LOAD_DONE;
		} else {
			mEndState = ENDINT_MANUAL_LOAD_DONE;
		}
		changeEndViewByState();
	}

	/**
	 * 主要更新一下刷新时间啦!
	 */
	public void setAdapter(BaseAdapter adapter) {
		mLastUpdatedTextView.setText(getResources().getString(
				R.string.p2refresh_refresh_lasttime)
				+ new SimpleDateFormat(DATE_FORMAT_STR, Locale.CHINA)
						.format(new Date()));
		super.setAdapter(adapter);
	}

	public void setEndRootViewVisibility(boolean b) {

		if (mEndRootView == null) {
			return;
		}

		if (getFooterViewsCount() == 0 && b) {
			addFooterView();
		} else {
			removeFooterView(mEndRootView);
		}
	}

	public View getFooterView() {
		return mEndRootView;
	}

}

下拉刷新与上拉加载更多,布布扣,bubuko.com

时间: 2024-10-12 18:07:17

下拉刷新与上拉加载更多的相关文章

Android如何定制一个下拉刷新,上滑加载更多的容器

前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉刷新和上滑,非常考验对android布局与父子触摸机制的功底,因此参考gitHub上的一个热门的下拉刷新项目 之所以选择他是因为它一个类就完成了所有View的适配,非常的精简强力. 需求 咱对下拉刷新.上滑加载更多的控件,需求如下: 1:下拉刷新,拖动到一定距离,提示文字变成 放手刷新 2:刷新完成

Android 下拉刷新,上滑加载更多

底部上拉效果 public class ListViewFooter extends LinearLayout { public final static int STATE_NORMAL = 0; public final static int STATE_READY = 1; public final static int STATE_LOADING = 2; private Context mContext; private View mContentView; private View

android ListView的上部下拉刷新下部点击加载更多具体实现及拓展

转自:http://blog.csdn.net/jj120522/article/details/8229423 这次就不上图了,例子太多太多了,想必大家都见过.这个功能的实现,简直是开发者必备的. 我也不过多介绍了,网上详细介绍的博客太多太多了,若想深入了解,请参考网上其他博文. 在这里,我只是按照自己的理解,模拟实现了一个,顺便代码贡献出来. 我对之详细标明的注释,想必如果不懂的同学们,看注释也应该明白,前提是,你要耐心看,因为代码有点多,但是我整理过了,还算清晰. 详细代码: [java]

vue之better-scroll的封装,包含下拉刷新,上拉加载功能及UI(核心为借鉴,我仅仅是给轮子套上了外胎...)

先发原文作者.地址等信息.我把内容全部搬过来了,也可以去看原文.内容绝对是满满的干货,给原作者点赞!(我添加的内容在转载过来的后面,内容不多) 作者: ustbhuangyi 链接:http://www.imooc.com/article/18232 来源:慕课网 在我们日常的移动端项目开发中,处理滚动列表是再常见不过的需求了,以滴滴为例,可以是这样竖向滚动的列表,如图所示: 也可以是横向滚动的导航栏,如图所示: 可以打开"微信 -> 钱包->滴滴出行"体验效果. 我们在实

Android自定义控件——ListView的下拉刷新与上拉加载

转载请注明出处:http://blog.csdn.net/allen315410/article/details/39965327 1.简介 无疑,在Android开发中,ListView是使用非常频繁的控件之一,ListView提供一个列表的容易,允许我们以列表的形式将数据展示到界面上,但是Google给我们提供的原生ListView的控件,虽然在功能上很强大,但是在用户体验和动态效果上,还是比较差劲的.为了改善用户体验,市面上纷纷出现了各种各样的自定义的ListView,他们功能强大,界面美

Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件

前言 下拉刷新组件在开发中使用率是非常高的,基本上联网的APP都会采用这种方式.对于开发效率而言,使用获得大家认可的开源库必然是效率最高的,但是不重复发明轮子的前提是你得自己知道轮子是怎么发明出来的,并且自己能够实现这些功能.否则只是知道其原理,并没有去实践那也就是纸上谈兵了.做程序猿,动手做才会遇到真正的问题,否则就只是自以为是的认为自己懂了.今天这篇文章就是以自己重复发明轮子这个出发点而来的,通过实现经典.使用率较高的组件来提高自己的认识.下面我们就一起来学习吧. 整体布局结构      

自定义(下拉刷新、上拉加载)帧动画

前些天搞了个系统的下拉刷新跟上拉加载,由于效果一般所以才会有了今天这篇博文 对于大多数的码农来说,能弄出些自己感兴趣的好东西还是比较开心的.-- package com.example.administrator.xlistview; import android.content.Context; import android.graphics.drawable.AnimationDrawable; import android.util.AttributeSet; import android

vue2.0 移动端,下拉刷新,上拉加载更多插件,修改版

在[实现丰盛]的插件基础修改[vue2.0 移动端,下拉刷新,上拉加载更多 插件], 1.修改加载到尾页面,返回顶部刷新数据,无法继续加重下一页 2.修改加载完成文字提示 原文链接:http://www.cnblogs.com/sichaoyun/p/6647458.html <template lang="html"> <div class="yo-scroll" :class="{'down':(state===0),'up':(st

SVPullToRefresh? 下拉刷新,上拉加载

一.下载第三方库 https://github.com/samvermette/SVPullToRefresh 二.使用方法 1.导入下载的第三方库 2.导入头文件 在需要的类里导入这一个头文件就能,同时使用下拉刷新,上拉加载 #import "SVPullToRefresh.h" 3.下拉刷新 [objc] view plain copy [_tableView addPullToRefreshWithActionHandler:^{ //数据的加载,和表的刷新的代码. //全部需要