标签:
转自:http://blog.csdn.net/jj120522/article/details/8229423
这次就不上图了,例子太多太多了,想必大家都见过.这个功能的实现,简直是开发者必备的.
我也不过多介绍了,网上详细介绍的博客太多太多了,若想深入了解,请参考网上其他博文.
在这里,我只是按照自己的理解,模拟实现了一个,顺便代码贡献出来.
我对之详细标明的注释,想必如果不懂的同学们,看注释也应该明白,前提是,你要耐心看,因为代码有点多,但是我整理过了,还算清晰.
详细代码:
- package com.jj.drag;
-
- import android.content.Context;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup;
- import android.view.animation.Animation;
- import android.view.animation.LinearInterpolator;
- import android.view.animation.RotateAnimation;
- import android.widget.AbsListView;
- import android.widget.AbsListView.OnScrollListener;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.ListView;
- import android.widget.ProgressBar;
- import android.widget.RelativeLayout;
- import android.widget.TextView;
-
- public class DragListView extends ListView implements OnScrollListener,
- OnClickListener {
-
- private enum DListViewState {
- LV_NORMAL,
- LV_PULL_REFRESH,
- LV_RELEASE_REFRESH,
- LV_LOADING;
- }
-
-
- private enum DListViewLoadingMore {
- LV_NORMAL,
- LV_LOADING,
- LV_OVER;
- }
-
- private View mHeadView;
- private TextView mRefreshTextview;
- private TextView mLastUpdateTextView;
- private ImageView mArrowImageView;
- private ProgressBar mHeadProgressBar;
-
- private int mHeadViewWidth;
- private int mHeadViewHeight;
-
- private View mFootView;
- private View mLoadMoreView;
- private TextView mLoadMoreTextView;
- private View mLoadingView;
-
- private Animation animation, reverseAnimation;
-
- private int mFirstItemIndex = -1;
-
-
- private boolean mIsRecord = false;
-
- private int mStartY, mMoveY;
-
- private DListViewState mlistViewState = DListViewState.LV_NORMAL;
-
- private DListViewLoadingMore loadingMoreState = DListViewLoadingMore.LV_NORMAL;
-
- private final static int RATIO = 2;
-
- private boolean mBack = false;
-
- private OnRefreshLoadingMoreListener onRefreshLoadingMoreListener;
-
- private boolean isScroller = true;
-
- public DragListView(Context context) {
- super(context, null);
- initDragListView(context);
- }
-
- public DragListView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initDragListView(context);
- }
-
-
- public void setOnRefreshListener(
- OnRefreshLoadingMoreListener onRefreshLoadingMoreListener) {
- this.onRefreshLoadingMoreListener = onRefreshLoadingMoreListener;
- }
-
-
- public void initDragListView(Context context) {
-
- String time = "1994.12.05";
-
- initHeadView(context, time);
-
- initLoadMoreView(context);
-
- setOnScrollListener(this);
- }
-
-
- public void initHeadView(Context context, String time) {
- mHeadView = LayoutInflater.from(context).inflate(R.layout.head, null);
- mArrowImageView = (ImageView) mHeadView
- .findViewById(R.id.head_arrowImageView);
- mArrowImageView.setMinimumWidth(60);
-
- mHeadProgressBar = (ProgressBar) mHeadView
- .findViewById(R.id.head_progressBar);
-
- mRefreshTextview = (TextView) mHeadView
- .findViewById(R.id.head_tipsTextView);
-
- mLastUpdateTextView = (TextView) mHeadView
- .findViewById(R.id.head_lastUpdatedTextView);
-
- mLastUpdateTextView.setText("最近更新:" + time);
-
- measureView(mHeadView);
-
- mHeadViewWidth = mHeadView.getMeasuredWidth();
- mHeadViewHeight = mHeadView.getMeasuredHeight();
-
- addHeaderView(mHeadView, null, false);
-
- mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
-
- initAnimation();
- }
-
-
- private void initLoadMoreView(Context context) {
- mFootView = LayoutInflater.from(context).inflate(R.layout.footer, null);
-
- mLoadMoreView = mFootView.findViewById(R.id.load_more_view);
-
- mLoadMoreTextView = (TextView) mFootView
- .findViewById(R.id.load_more_tv);
-
- mLoadingView = (LinearLayout) mFootView
- .findViewById(R.id.loading_layout);
-
- mLoadMoreView.setOnClickListener(this);
-
- addFooterView(mFootView);
- }
-
-
- private void initAnimation() {
-
- animation = new RotateAnimation(0, -180,
- RotateAnimation.RELATIVE_TO_SELF, 0.5f,
- RotateAnimation.RELATIVE_TO_SELF, 0.5f);
- animation.setInterpolator(new LinearInterpolator());
- animation.setDuration(250);
- animation.setFillAfter(true);
-
- reverseAnimation = new RotateAnimation(-180, 0,
- RotateAnimation.RELATIVE_TO_SELF, 0.5f,
- RotateAnimation.RELATIVE_TO_SELF, 0.5f);
- reverseAnimation.setInterpolator(new LinearInterpolator());
- reverseAnimation.setDuration(250);
- reverseAnimation.setFillAfter(true);
- }
-
-
- private void measureView(View child) {
- ViewGroup.LayoutParams p = child.getLayoutParams();
- if (p == null) {
- p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_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);
- }
- child.measure(childWidthSpec, childHeightSpec);
- }
-
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
-
- case MotionEvent.ACTION_DOWN:
- doActionDown(ev);
- break;
-
- case MotionEvent.ACTION_MOVE:
- doActionMove(ev);
- break;
-
- case MotionEvent.ACTION_UP:
- doActionUp(ev);
- break;
- default:
- break;
- }
-
- if (isScroller) {
- return super.onTouchEvent(ev);
- } else {
- return true;
- }
-
- }
-
-
- void doActionDown(MotionEvent event) {
- if (mIsRecord == false && mFirstItemIndex == 0) {
- mStartY = (int) event.getY();
- mIsRecord = true;
- }
- }
-
-
- void doActionMove(MotionEvent event) {
- mMoveY = (int) event.getY();
-
- if (mIsRecord == false && mFirstItemIndex == 0) {
- mStartY = (int) event.getY();
- mIsRecord = true;
- }
-
- if (mIsRecord == false || mlistViewState == DListViewState.LV_LOADING) {
- return;
- }
-
- int offset = (mMoveY - mStartY) / RATIO;
-
- switch (mlistViewState) {
-
- case LV_NORMAL: {
-
- if (offset > 0) {
-
- mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
- switchViewState(DListViewState.LV_PULL_REFRESH);
- }
-
- }
- break;
-
- case LV_PULL_REFRESH: {
- setSelection(0);
-
- mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
- if (offset < 0) {
-
- isScroller = false;
- switchViewState(DListViewState.LV_NORMAL);
- Log.e("jj", "isScroller=" + isScroller);
- } else if (offset > mHeadViewHeight) {
- switchViewState(DListViewState.LV_RELEASE_REFRESH);
- }
- }
- break;
-
- case LV_RELEASE_REFRESH: {
- setSelection(0);时时保持在顶部
-
- mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
-
- if (offset >= 0 && offset <= mHeadViewHeight) {
- mBack = true;
- switchViewState(DListViewState.LV_PULL_REFRESH);
- } else if (offset < 0) {
- switchViewState(DListViewState.LV_NORMAL);
- } else {
-
- }
- }
- break;
- default:
- return;
- }
- ;
- }
-
-
- public void doActionUp(MotionEvent event) {
- mIsRecord = false;
- isScroller = true;
- mBack = false;
-
- if (mlistViewState == DListViewState.LV_LOADING) {
- return;
- }
-
- switch (mlistViewState) {
-
- case LV_NORMAL:
-
- break;
-
- case LV_PULL_REFRESH:
- mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
- switchViewState(mlistViewState.LV_NORMAL);
- break;
-
- case LV_RELEASE_REFRESH:
- mHeadView.setPadding(0, 0, 0, 0);
- switchViewState(mlistViewState.LV_LOADING);
- onRefresh();
- break;
- }
-
- }
-
-
- private void switchViewState(DListViewState state) {
-
- switch (state) {
-
- case LV_NORMAL: {
- mArrowImageView.clearAnimation();
- mArrowImageView.setImageResource(R.drawable.arrow);
- }
- break;
-
- case LV_PULL_REFRESH: {
- mHeadProgressBar.setVisibility(View.GONE);
- mArrowImageView.setVisibility(View.VISIBLE);
- mRefreshTextview.setText("下拉可以刷新");
- mArrowImageView.clearAnimation();
-
-
- if (mBack) {
- mBack = false;
- mArrowImageView.clearAnimation();
- mArrowImageView.startAnimation(reverseAnimation);
- }
- }
- break;
-
- case LV_RELEASE_REFRESH: {
- mHeadProgressBar.setVisibility(View.GONE);
- mArrowImageView.setVisibility(View.VISIBLE);
- mRefreshTextview.setText("松开获取更多");
- mArrowImageView.clearAnimation();
- mArrowImageView.startAnimation(animation);
- }
- break;
-
- case LV_LOADING: {
- Log.e("!!!!!!!!!!!", "convert to IListViewState.LVS_LOADING");
- mHeadProgressBar.setVisibility(View.VISIBLE);
- mArrowImageView.clearAnimation();
- mArrowImageView.setVisibility(View.GONE);
- mRefreshTextview.setText("载入中...");
- }
- break;
- default:
- return;
- }
-
- mlistViewState = state;
-
- }
-
-
- private void onRefresh() {
- if (onRefreshLoadingMoreListener != null) {
- onRefreshLoadingMoreListener.onRefresh();
- }
- }
-
-
- public void onRefreshComplete() {
- mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
- switchViewState(mlistViewState.LV_NORMAL);
- }
-
-
- public void onLoadMoreComplete(boolean flag) {
- if (flag) {
- updateLoadMoreViewState(DListViewLoadingMore.LV_OVER);
- } else {
- updateLoadMoreViewState(DListViewLoadingMore.LV_NORMAL);
- }
-
- }
-
-
- private void updateLoadMoreViewState(DListViewLoadingMore state) {
- switch (state) {
-
- case LV_NORMAL:
- mLoadingView.setVisibility(View.GONE);
- mLoadMoreTextView.setVisibility(View.VISIBLE);
- mLoadMoreTextView.setText("查看更多");
- break;
-
- case LV_LOADING:
- mLoadingView.setVisibility(View.VISIBLE);
- mLoadMoreTextView.setVisibility(View.GONE);
- break;
-
- case LV_OVER:
- mLoadingView.setVisibility(View.GONE);
- mLoadMoreTextView.setVisibility(View.VISIBLE);
- mLoadMoreTextView.setText("加载完毕");
- break;
- default:
- break;
- }
- loadingMoreState = state;
- }
-
-
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
-
- }
-
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- mFirstItemIndex = firstVisibleItem;
- }
-
-
- @Override
- public void onClick(View v) {
-
- if (onRefreshLoadingMoreListener != null
- && loadingMoreState == DListViewLoadingMore.LV_NORMAL) {
- updateLoadMoreViewState(DListViewLoadingMore.LV_LOADING);
- onRefreshLoadingMoreListener.onLoadMore();
- }
-
- }
-
-
- public interface OnRefreshLoadingMoreListener {
-
- void onRefresh();
-
-
- void onLoadMore();
- }
-
- }
上面就是全部代码,其实重要的是明白理解,这样我们还可以进行拓展.
具体应用:(只需要这样引用即可.)
- <com.jj.drag.DragListView
- android:id="@+id/dlv_main"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:cacheColorHint="#00000000" />
在Activity中的调用,相比大家都清楚,开个异步或线程进行加载数据,这里我简单说一下异步使用,线程同理.
代码如下:
- class MyAsyncTask extends AsyncTask<Void, Void, Void> {
- private Context context;
- private int index;
-
- public MyAsyncTask(Context context, int index) {
- this.context = context;
- this.index = index;
- }
-
- @Override
- protected Void doInBackground(Void... params) {
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e1) {
- e1.printStackTrace();
- }
-
- return null;
- }
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- }
-
- @Override
- protected void onPostExecute(Void result) {
- super.onPostExecute(result);
- if (index == DRAG_INDEX)
- dlv_main.onRefreshComplete();
- else if (index == LOADMORE_INDEX)
- dlv_main.onLoadMoreComplete(false);
- }
-
- }
先声明一点,这个只是个示例,所以这部分代码写的不够友好,也请见谅.
就说道这里,最后展示一下效果:

至于如果显示,如何adapter.notifyDataSetChanged();那就要大家开发时候自己调理了.
最后说明一点:网上有好多介绍下拉刷新的例子,但是他们没有对滑动进行处理,比如,我下拉的时候现在不想刷新了,这时我又向上滑动,正常的处理,应该滑动到FirstItemIndex=1就是顶部,滑动就结束了.(意思就是要下拉和listview正常滑动要分开)可是网上一些案例都没有对之处理,用起来不友好,大家可以看看成功案例,那些新浪,腾讯,百度等.
解决方法:(这是onTouch方法中的一部分.)
- if (isScroller) {
- return super.onTouchEvent(ev);
- } else {
- return true;
- }
要问Why的话,那么你就要去详细看Touch种种事件,记住,这里用到的不是分发与拦截,分发拦截流程如下:
Activity 的dispatchTouchEvent开始分发给子的View,如果该View是ViewGroup的话,那么执行其dispatchTouchEvent进行分发,在执行相应的onInterceptTouchEvent拦截.如果要想实现上诉说的那种效果,那么在自定义ListView中对拦截分发方法是无效的,只有在ListView的上一层进行处理,比我我们在外层自定义一个布局,等等,实现起来总之麻烦一个字,其实我们也可以考虑考虑onTouchEvent事件的实现,
ListView.java
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (mItemsCanFocus && ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
-
-
- return false;
- }
- return super.onTouchEvent(ev);
- }
继续点击查看父类,这里就不显示了,自己可以查看源码,其实就是我们ListView滑动的具体实现,而此时我们只是想临时屏蔽掉此滑动,那么我们只需要不调用父类的onTouchEvent不就OK的,是的,确实如此,而何时进行屏蔽,大家就仔细看上面源码实现吧,解释的也很清楚,这样大家都明白了吧。注:有疑问请留言!之前这个例子android 自定义ScrollView实现反弹效果(以及解决和ListView之间的冲突)没有解决这个问题,因为处境不同.(不过正在完善,相信也会完美的实现这些效果,因为原理上是行的通的。)
知识拓展:
首先我们还是看一些案例:

效果就是可以上下拖拽.而用在最多的地方就是ListView,而普通的布局拖拽直接自定义布局就OK了,详情请参考上面连接那篇文章.
实现起来也不是很麻烦,就是对上面那个自定义类稍作修改,把底部也做成动态拖拽效果就OK了.
这里不详细讲解,因为注释相当明确,如有疑问,请指出.
代码如下:
- package com.jj.drag;
-
- import android.content.Context;
- import android.os.AsyncTask;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup;
- import android.view.animation.Animation;
- import android.view.animation.LinearInterpolator;
- import android.view.animation.RotateAnimation;
- import android.widget.AbsListView;
- import android.widget.AbsListView.OnScrollListener;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.ListView;
- import android.widget.ProgressBar;
- import android.widget.RelativeLayout;
- import android.widget.TextView;
-
- public class DragListView extends ListView implements OnScrollListener,
- OnClickListener {
-
- private enum DListViewState {
- LV_NORMAL,
- LV_PULL_REFRESH,
-
- }
-
-
- private enum DListViewLoadingMore {
- LV_NORMAL,
- LV_PULL_REFRESH,
- }
-
- private View mHeadView, mFootView;
-
- private int mHeadViewWidth;
- private int mHeadViewHeight;
-
- private int mFirstItemIndex = -1;
-
- private int mLastItemIndex = -1;
-
-
- private boolean mIsRecord = false;
-
- private boolean mIsRecord_B = false;
-
- private int mStartY, mMoveY;
-
- private DListViewState mlistViewState = DListViewState.LV_NORMAL;
-
- private DListViewLoadingMore loadingMoreState = DListViewLoadingMore.LV_NORMAL;
-
- private final static int RATIO = 2;
-
- private boolean isScroller = true;
-
- private MyAsynTask myAsynTask;
- private final static int DRAG_UP = 1, DRAG_DOWN = 2;
-
- public DragListView(Context context) {
- super(context, null);
- initDragListView(context);
- }
-
- public DragListView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initDragListView(context);
- }
-
-
- public void initDragListView(Context context) {
-
- initHeadView(context);
-
- initFooterView(context);
-
- setOnScrollListener(this);
- }
-
-
- public void initHeadView(Context context) {
- mHeadView = LayoutInflater.from(context).inflate(R.layout.head, null);
- measureView(mHeadView);
-
- mHeadViewWidth = mHeadView.getMeasuredWidth();
- mHeadViewHeight = mHeadView.getMeasuredHeight();
-
- addHeaderView(mHeadView, null, false);
-
- mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
-
- }
-
-
- private void initFooterView(Context context) {
- mFootView = LayoutInflater.from(context).inflate(R.layout.head, null);
- addFooterView(mFootView, null, false);
-
- mFootView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
- }
-
-
- private void measureView(View child) {
- ViewGroup.LayoutParams p = child.getLayoutParams();
- if (p == null) {
- p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_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);
- }
- child.measure(childWidthSpec, childHeightSpec);
- }
-
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
-
- switch (ev.getAction()) {
-
- case MotionEvent.ACTION_DOWN:
- doActionDown_B(ev);
- doActionDown(ev);
- break;
-
- case MotionEvent.ACTION_MOVE:
- doActionMove_B(ev);
- doActionMove(ev);
- break;
-
- case MotionEvent.ACTION_UP:
- doActionUp_B(ev);
- doActionUp(ev);
- break;
- default:
- break;
- }
-
-
- if (isScroller) {
- return super.onTouchEvent(ev);
- } else {
- return true;
- }
-
- }
-
-
- void doActionDown(MotionEvent event) {
-
- if (mIsRecord == false && mFirstItemIndex == 0) {
- mStartY = (int) event.getY();
- mIsRecord = true;
- }
- }
-
-
- void doActionDown_B(MotionEvent event) {
-
- if (mIsRecord_B == false && mLastItemIndex == getCount()) {
- mStartY = (int) event.getY();
- mIsRecord_B = true;
- }
- }
-
-
- void doActionMove(MotionEvent event) {
-
-
- mMoveY = (int) event.getY();
-
-
- if (mIsRecord == false && mFirstItemIndex == 0) {
- mStartY = (int) event.getY();
- mIsRecord = true;
- }
-
- if (mIsRecord == false)
- return;
-
-
- int offset = (mMoveY - mStartY) / RATIO;
-
- switch (mlistViewState) {
-
- case LV_NORMAL: {
-
- if (offset > 0) {
-
- mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
- mlistViewState = DListViewState.LV_PULL_REFRESH;
- }
- }
- break;
-
- case LV_PULL_REFRESH: {
- setSelection(0);
-
- mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
- if (offset < 0) {
-
- isScroller = false;
- mlistViewState = mlistViewState.LV_NORMAL;
- }
- }
- break;
- default:
- return;
- }
- }
-
- void doActionMove_B(MotionEvent event) {
- mMoveY = (int) event.getY();
-
- if (mIsRecord_B == false && mLastItemIndex == getCount()) {
- mStartY = (int) event.getY();
- mIsRecord_B = true;
- }
-
- if (mIsRecord_B == false)
- return;
-
-
- int offset = (mMoveY - mStartY) / RATIO;
-
- switch (loadingMoreState) {
-
- case LV_NORMAL: {
-
- if (offset < 0) {
- int distance = Math.abs(offset);
-
- mFootView.setPadding(0, distance - mHeadViewHeight, 0, 0);
- loadingMoreState = loadingMoreState.LV_PULL_REFRESH;
- }
- }
- break;
-
- case LV_PULL_REFRESH: {
- setSelection(getCount() - 1);
-
- int distance = Math.abs(offset);
- mFootView.setPadding(0, distance - mHeadViewHeight, 0, 0);
-
- if (offset > 0) {
-
- isScroller = false;
- loadingMoreState = loadingMoreState.LV_NORMAL;
- }
- }
- break;
- default:
- return;
- }
- }
-
-
- public void doActionUp(MotionEvent event) {
- mIsRecord = false;
- mIsRecord_B = false;
- isScroller = true;
- mlistViewState = mlistViewState.LV_NORMAL;
-
-
- myAsynTask = new MyAsynTask();
- myAsynTask.execute(DRAG_UP);
-
- }
-
- private void doActionUp_B(MotionEvent event) {
- mIsRecord = false;
- isScroller = true;
-
- loadingMoreState = loadingMoreState.LV_NORMAL;
-
-
- myAsynTask = new MyAsynTask();
- myAsynTask.execute(DRAG_DOWN);
- }
-
-
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
-
- }
-
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- mFirstItemIndex = firstVisibleItem;
- mLastItemIndex = firstVisibleItem + visibleItemCount;
-
- }
-
- @Override
- public void onClick(View v) {
-
- }
-
-
- private class MyAsynTask extends AsyncTask<Integer, Integer, Void> {
- private final static int STEP = 30;
- private final static int TIME = 5;
- private int distance;
- private int number;
- private int disPadding;
- private int DRAG;
-
- @Override
- protected Void doInBackground(Integer... params) {
- try {
- this.DRAG = params[0];
- if (params[0] == DRAG_UP) {
-
- distance = mHeadView.getPaddingTop()
- + Math.abs(mHeadViewHeight);
- } else {
-
- distance = mFootView.getPaddingTop()
- + Math.abs(mHeadViewHeight);
- }
-
-
- if (distance % STEP == 0) {
- number = distance / STEP;
- } else {
- number = distance / STEP + 1;
- }
-
- for (int i = 0; i < number; i++) {
- Thread.sleep(TIME);
- publishProgress(STEP);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- @Override
- protected void onProgressUpdate(Integer... values) {
- super.onProgressUpdate(values);
-
- switch (DRAG) {
- case DRAG_UP:
- disPadding = Math.max(mHeadView.getPaddingTop() - STEP, -1
- * mHeadViewHeight);
- mHeadView.setPadding(0, disPadding, 0, 0);
- break;
- case DRAG_DOWN:
- disPadding = Math.max(mFootView.getPaddingTop() - STEP, -1
- * mHeadViewHeight);
- mFootView.setPadding(0, disPadding, 0, 0);
- break;
- default:
- break;
- }
-
- }
-
- }
-
- }
运行效果:

默认效果 下拉拖拽效果(会自动回缩) 上拉拖拽效果(会自动回缩)
前面那章实现起来有点小BUG,正在处理,不过这个实现起来没有发现什么BUG,要说BUG的话,那么就是优化,因为我觉得上面效果是实现了,可是性能觉得有点差,比如说“我每次UP的时候要执行任务,那么就要创建任务对象,你想想看,每次执行都要创建,那么要创建多少对象,虽说JAVA虚拟机会自动回收,但是总觉得不是很完善,嗯,临时就如此了,自己在研究研究看.
至于微信,陌陌等大多数应用都是(数据少的话,就上下都可以拖拽,只是一个人性效果,而数据多的话,上部用于加载过时数据.下部只是个形式.),效果实现起来也不难,只是进行了些判断,效果嘛,其实上面自定义ListView整理下就OK了.
上面我详细给出了两个自定义源码的实现,大家可以直接引用.
在这里我将源码上传,如果上面看的不明白的话,你可以下载,只要你耐心看,我相信大家都能弄明白,都会进行响应扩展的.其实我们要的就是创新,而不是简单应用.
源码一
源码二
就说到这里,如有疑问请留言。
另外,如果对您有帮助的话,记得赞一个哦.
在此:Thanks for you !
android ListView的上部下拉刷新下部点击加载更多具体实现及拓展
标签:
原文地址:http://www.cnblogs.com/duanweishi/p/4302291.html