`
104zz
  • 浏览: 1508362 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
阅读更多

 

本例是实现下拉时刷新并且底部设置加载更多选择并在下拉和回滑时加入相应的动画效果,

功能实现主要为自定义一个Layout在此布局中头部刷新主要是用到了在头部添加布局view控件并使用GestureDetector控制下拉时的变化以便控制滑动的效果,在自定义底部也加一个加载更多的布局,中间内嵌一个ListView控件以显示内容。具体步骤如下:

 

第一步:设计自定义布局PullDownListView继承FrameLayout 实现GestureDetector.OnGestureListenerAnimation.AnimationListener接口:

 

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Scroller;
import android.widget.TextView;
import com.example.pulldownview.R;
public class PullDownListView extends FrameLayout implements
GestureDetector.OnGestureListener, Animation.AnimationListener {
public static int MAX_LENGHT = 0;
public static final int STATE_REFRESH = 1;
public static final int SCROLL_TO_CLOSE = 2;
public static final int SCROLL_TO_REFRESH = 3;
public static final double SCALE = 0.9d;
private static final int CLOSEDELAY = 300;
private static final int REFRESHDELAY = 300;
private Animation mAnimationDown;
private Animation mAnimationUp;
private ImageView mArrow;
private View emptyHeaderView;
private ProgressBar mProgressBar;
private TextView more;
private ProgressBar mProgressBar2;
private int mState;
private TextView mTitle;
public ListView mListView;
LinearLayout foot;
LinearLayout footer_layout;
LinearLayout header;
private GestureDetector mDetector;
private FlingRunnable mFlinger;
private int mPading;
private int mDestPading;
private int mLastTop;
private LinearLayout mFirstChild;
private FrameLayout mUpdateContent;
private OnRefreshListioner mRefreshListioner;
private boolean isAutoLoadMore = false;
private boolean hasMore = true;
private boolean isEnd = true;
private boolean listviewDoScroll = false;
private boolean isFirstLoading = false;
private boolean mLongPressing;// 如果设置为true说明刚好到了执行长按的时间
private boolean mPendingRemoved = false;//
private String pulldowntorefresh;
private String releasetorefresh;
private String loading;
Rect r = new Rect();
private MotionEvent downEvent;
private CheckForLongPress mPendingCheckForLongPress = new CheckForLongPress();
private CheckForLongPress2 mPendingCheckForLongPress2 = new CheckForLongPress2();
private float lastY;
private boolean useempty = true;
//这个标签作为测试用
String TAG = "PullDownListView";
/**
 * 长按检查方法执行1线程
 * @author Administrator
 *
 */
private class CheckForLongPress implements Runnable {
public void run() {
if (mListView.getOnItemLongClickListener() == null) {
} else {
postDelayed(mPendingCheckForLongPress2, 100);
}
}
}
/**
 * 长按检查方法执行2线程 ----> 延后 100 
 * @author Administrator
 *
 */
private class CheckForLongPress2 implements Runnable {
public void run() {
mLongPressing = true;
MotionEvent e = MotionEvent.obtain(downEvent.getDownTime(),downEvent.getEventTime()
+ ViewConfiguration.getLongPressTimeout(),
MotionEvent.ACTION_CANCEL, downEvent.getX(),
downEvent.getY(), downEvent.getMetaState());
PullDownListView.super.dispatchTouchEvent(e);
}
}
class FlingRunnable implements Runnable {
private void startCommon() {
removeCallbacks(this);
}
public void run() {
boolean noFinish = mScroller.computeScrollOffset();
int curY = mScroller.getCurrY();
int deltaY = curY - mLastFlingY;
if (noFinish) {
move(deltaY, true);
mLastFlingY = curY;
post(this);
} else {
removeCallbacks(this);
if (mState == SCROLL_TO_CLOSE) {
mState = -1;
}
}
}
public void startUsingDistance(int distance, int duration) {
if (distance == 0)
distance--;
startCommon();
mLastFlingY = 0;
mScroller.startScroll(0, 0, 0, distance, duration);
post(this);
}
private int mLastFlingY;
private Scroller mScroller;
public FlingRunnable() {
mScroller = new Scroller(getContext());
}
}
/**
 * 下拉刷新以及加载更多回调监听接口
 * @author Administrator
 *
 */
public interface OnRefreshListioner {
public abstract void onRefresh();
public abstract void onLoadMore();
}
/**
 * 直接new时调用的构造方法 
 * @param context
 */
public PullDownListView(Context context) {
super(context);
mDetector = new GestureDetector(context, this);
mFlinger = new FlingRunnable();
init();
addRefreshBar();
}
/**
 * 在xml中使用时调用的构造方法
 * @param context
 */
public PullDownListView(Context context, AttributeSet att) {
super(context, att);
useempty = att.getAttributeBooleanValue(null, "useempty", true);
mDetector = new GestureDetector(this);
mFlinger = new FlingRunnable();
init();
addRefreshBar();
}
View view;
/**
 * 添加刷新头部的控件
 */
private void addRefreshBar() {
//向上滑动的动画
mAnimationUp = AnimationUtils.loadAnimation(getContext(),R.anim.rotate_up);
mAnimationUp.setAnimationListener(this);
//向下滑动的动画
mAnimationDown = AnimationUtils.loadAnimation(getContext(),R.anim.rotate_down);
mAnimationDown.setAnimationListener(this);
//刷新头部的view
view = LayoutInflater.from(getContext()).inflate(R.layout.refresh_bar,null);
//添加view在本控件中
addView(view);
/*
 * 以下都是刷新头部的一些控件的设置
 */
mFirstChild = (LinearLayout) view;
mUpdateContent = (FrameLayout) getChildAt(0).findViewById(R.id.iv_content);
mArrow = new ImageView(getContext());
FrameLayout.LayoutParams layoutparams = new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
mArrow.setScaleType(ImageView.ScaleType.FIT_CENTER);
mArrow.setLayoutParams(layoutparams);
mArrow.setImageResource(R.drawable.arrow_down);
mUpdateContent.addView(mArrow);
FrameLayout.LayoutParams layoutparams1 = new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
layoutparams1.gravity = Gravity.CENTER;
mProgressBar = new ProgressBar(getContext(), null,
android.R.attr.progressBarStyleSmallInverse);
mProgressBar.setIndeterminate(false);
int i = getResources().getDimensionPixelSize(R.dimen.updatebar_padding);
mProgressBar.setPadding(i, i, i, i);
mProgressBar.setLayoutParams(layoutparams1);
mUpdateContent.addView(mProgressBar);
mTitle = (TextView) findViewById(R.id.tv_title);
}
public void setGone() {
mTitle.setVisibility(View.GONE);
mUpdateContent.setVisibility(View.GONE);
}
protected void onFinishInflate() {
super.onFinishInflate();
mListView = (ListView) getChildAt(1);
footer_layout = (LinearLayout) LayoutInflater.from(getContext())
.inflate(R.layout.empty_main, null);
foot = (LinearLayout) LayoutInflater.from(getContext()).inflate(
R.layout.ref2, null);
more = (TextView) foot.findViewById(R.id.ref);
mProgressBar2 = (ProgressBar) foot.findViewById(R.id.refbar);
mProgressBar2.setVisibility(View.GONE);
if (useempty) {
header = (LinearLayout) LayoutInflater.from(getContext()).inflate(
R.layout.empty_main, null);
mListView.addHeaderView(header);
}
mListView.addFooterView(footer_layout);
foot.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (!isAutoLoadMore)
onLoadMore();
}
});
mListView.setOnScrollListener(new OnScrollListener() {
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (isEnd && scrollState == SCROLL_STATE_IDLE && hasMore
&& isAutoLoadMore) {
onLoadMore();
}
}
public void onScroll(AbsListView view, int f, int v, int t) {
if (isAutoLoadMore) {
if (f + v >= t - 1)
isEnd = true;
else
isEnd = false;
}
}
});
}
/**
 * 设置没有数据时默认图片
 * 
 * @param empty
 */
public void setEmptyHeaderView(View empty) {
emptyHeaderView = empty;
}
/**
 * 添加空的定部view
 */
public void addEmptyHeaderView() {
header.removeAllViews();
if (emptyHeaderView != null)
header.addView(emptyHeaderView);
}
/**
 * 移除顶部空view
 */
public void removeEmptyHeaderView() {
if (emptyHeaderView != null)
header.removeView(emptyHeaderView);
}
/**
 * 初始化设置及变量
 */
private void init() {
MAX_LENGHT = getResources().getDimensionPixelSize(
R.dimen.updatebar_height);// 62.0dip
setDrawingCacheEnabled(false);
setBackgroundDrawable(null);
setClipChildren(false);
mDetector.setIsLongpressEnabled(false);
mPading = -MAX_LENGHT;
mLastTop = -MAX_LENGHT;
pulldowntorefresh = getContext().getText(R.string.drop_dowm).toString();
releasetorefresh = getContext().getText(R.string.release_update)
.toString();
loading = getContext().getText(R.string.loading).toString();
}
/** deltaY > 0 向上 */
private boolean move(float deltaY, boolean auto) {
//move 方法执行 " 
if (deltaY > 0 && mFirstChild.getTop() == -MAX_LENGHT) {
mPading = -MAX_LENGHT;
return false;
}
if (auto) {
//move 方法执行
if (mFirstChild.getTop() - deltaY < mDestPading) {
deltaY = mFirstChild.getTop() - mDestPading;
}
mFirstChild.offsetTopAndBottom((int) -deltaY);
mListView.offsetTopAndBottom((int) -deltaY);
mPading = mFirstChild.getTop();
if (mDestPading == 0 && mFirstChild.getTop() == 0
&& mState == SCROLL_TO_REFRESH) {
//onRefresh 刷新方法执行
onRefresh();
} else if (mDestPading == -MAX_LENGHT) {
}
invalidate();
updateView();
return true;
} else {
if (mState != STATE_REFRESH
|| (mState == STATE_REFRESH && deltaY > 0)) {
mFirstChild.offsetTopAndBottom((int) -deltaY);
mListView.offsetTopAndBottom((int) -deltaY);
mPading = mFirstChild.getTop();
} else if (mState == STATE_REFRESH && deltaY < 0
&& mFirstChild.getTop() <= 0) {
if (mFirstChild.getTop() - deltaY > 0) {
deltaY = mFirstChild.getTop();
}
mFirstChild.offsetTopAndBottom((int) -deltaY);
mListView.offsetTopAndBottom((int) -deltaY);
mPading = mFirstChild.getTop();
}
}
if (deltaY > 0 && mFirstChild.getTop() <= -MAX_LENGHT) {
mPading = -MAX_LENGHT;
deltaY = -MAX_LENGHT - mFirstChild.getTop();
mFirstChild.offsetTopAndBottom((int) deltaY);
mListView.offsetTopAndBottom((int) deltaY);
mPading = mFirstChild.getTop();
updateView();
invalidate();
return false;
}
updateView();
invalidate();
return true;
}
private void updateView() {
String s = "";
if (mState != STATE_REFRESH) {
if (mFirstChild.getTop() < 0) {
mArrow.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.INVISIBLE);
mTitle.setText(pulldowntorefresh);
if (mLastTop >= 0 && mState != SCROLL_TO_CLOSE) {
mArrow.startAnimation(mAnimationUp);//向上移动动画
}
} else if (mFirstChild.getTop() > 0) {
mTitle.setText(releasetorefresh + s);
mProgressBar.setVisibility(View.INVISIBLE);
mArrow.setVisibility(View.VISIBLE);
if (mLastTop <= 0) {
mArrow.startAnimation(mAnimationDown);//向下移动动画
}
}
}
mLastTop = mFirstChild.getTop();
}
//release 方法执行 
private boolean release() {
if (listviewDoScroll) {
listviewDoScroll = false;
return true;
}
if (mFirstChild.getTop() > 0) {
scrollToUpdate(false);
} else {
scrollToClose();
}
invalidate();
return false;
}
private void scrollToClose() {
mDestPading = -MAX_LENGHT;
mFlinger.startUsingDistance(MAX_LENGHT, CLOSEDELAY);
}
//scrollToUpdate 方法执行
public void scrollToUpdate(boolean load) {
mState = SCROLL_TO_REFRESH;
mDestPading = 0;
if (load) {
mFlinger.startUsingDistance(50, REFRESHDELAY);
load = false;
} else
mFlinger.startUsingDistance(mFirstChild.getTop(), REFRESHDELAY);
}
private void onRefresh() {
mState = STATE_REFRESH;
mTitle.setText(loading);
mProgressBar.setVisibility(View.VISIBLE);
mArrow.setVisibility(View.INVISIBLE);
if (mRefreshListioner != null) {
mRefreshListioner.onRefresh();
}
}
public void onRefreshComplete() {
onRefreshComplete(null);
}
public void onRefreshComplete(String date) {
mState = SCROLL_TO_CLOSE;
mArrow.setImageResource(R.drawable.arrow_down);
mProgressBar2.setVisibility(View.INVISIBLE);
updateCommon();
scrollToClose();
}
public void setMore(boolean hasMore) {
if (hasMore) {
mListView.setFooterDividersEnabled(true);
footer_layout.removeAllViews();
footer_layout.addView(foot);
} else {
mListView.setFooterDividersEnabled(false);
footer_layout.removeAllViews();
}
}
private void updateCommon() {
if (mListView.getCount() == (mListView.getHeaderViewsCount() + mListView
.getFooterViewsCount())) {
Log.e("out", "数据为空");
if (useempty)
addEmptyHeaderView();
} else {
removeEmptyHeaderView();
mListView.setFooterDividersEnabled(false);
footer_layout.removeAllViews();
}
}
public void setFoot() {
footer_layout.setVisibility(View.GONE);
}
public void onFirstLoad() {
if (footer_layout.getChildCount() == 0) {
footer_layout.addView(foot);
}
isFirstLoading = true;
foot.setEnabled(false);
//onFirstLoad 方法执行 
mState = STATE_REFRESH;
mProgressBar2.setVisibility(View.VISIBLE);
more.setText(R.string.loading);
}
public void onLoadMore() {
//onLoadMore 方法执行 
foot.setEnabled(false);
mState = STATE_REFRESH;
mProgressBar2.setVisibility(View.VISIBLE);
more.setText(R.string.loading);
if (mRefreshListioner != null) {
mRefreshListioner.onLoadMore();
}
}
public void onLoadMoreComplete(String date) {
mState = -1;
mProgressBar2.setVisibility(View.INVISIBLE);
more.setText(R.string.seen_more);
updateCommon();
if (isFirstLoading)
isFirstLoading = false;
foot.setEnabled(true);
}
public void onLoadMoreComplete() {
onLoadMoreComplete(null);
}
public boolean dispatchTouchEvent(MotionEvent e) {
if (isFirstLoading) {
return false;
}
int action;
float y = e.getY();
action = e.getAction();
if (mLongPressing && action != MotionEvent.ACTION_DOWN) {
return false;
}
if (e.getAction() == MotionEvent.ACTION_DOWN) {
mLongPressing = true;
}
boolean handled = true;
handled = mDetector.onTouchEvent(e);
switch (action) {
case MotionEvent.ACTION_UP:
boolean f1 = mListView.getTop() <= e.getY()
&& e.getY() <= mListView.getBottom();
if (!handled && mFirstChild.getTop() == -MAX_LENGHT && f1
|| mState == STATE_REFRESH) {
super.dispatchTouchEvent(e);
} else {
//执行释放方法 
handled = release();
}
break;
case MotionEvent.ACTION_CANCEL:
handled = release();
super.dispatchTouchEvent(e);
break;
case MotionEvent.ACTION_DOWN:
downEvent = e;
mLongPressing = false;
//长按的时间间隔
postDelayed(mPendingCheckForLongPress,
ViewConfiguration.getLongPressTimeout() + 100);
mPendingRemoved = false;
super.dispatchTouchEvent(e);
break;
case MotionEvent.ACTION_MOVE:
float deltaY = lastY - y;
lastY = y;
if (!mPendingRemoved) {
removeCallbacks(mPendingCheckForLongPress);
mPendingRemoved = true;
}
if (!handled && mFirstChild.getTop() == -MAX_LENGHT) {
try {
return super.dispatchTouchEvent(e);
} catch (Exception e2) {
e2.printStackTrace();
return true;
}
} else if (handled && mListView.getTop() > 0 && deltaY < 0) {// deltaY小于0,向�?
e.setAction(MotionEvent.ACTION_CANCEL);
super.dispatchTouchEvent(e);
}
break;
default:
break;
}
return true;
}
public void onAnimationEnd(Animation animation) {
int top = mFirstChild.getTop();
if (top < 0)
mArrow.setImageResource(R.drawable.arrow_down);
else if (top > 0)
mArrow.setImageResource(R.drawable.arrow_up);
else {
if (top < mLastTop) {
mArrow.setImageResource(R.drawable.arrow_down);
} else {
mArrow.setImageResource(R.drawable.arrow_up);
}
}
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
public boolean onDown(MotionEvent e) {
return false;
}
public boolean onFling(MotionEvent motionevent, MotionEvent e, float f,
float f1) {
return false;
}
protected void onLayout(boolean flag, int i, int j, int k, int l) {
int top = mPading;
int w = getMeasuredWidth();
mFirstChild.layout(0, top, w, top + MAX_LENGHT);
int h = getMeasuredHeight() + mPading + MAX_LENGHT;
mListView.layout(0, top + MAX_LENGHT, w, h);
}
public void onLongPress(MotionEvent e) {
}
/** deltaY > 0 向上 */
public boolean onScroll(MotionEvent curdown, MotionEvent cur, float deltaX,
float deltaY) {
deltaY = (float) ((double) deltaY * SCALE);
boolean handled = false;
boolean flag = false;
if (mListView.getCount() == 0) {
flag = true;
} else {
View c = mListView.getChildAt(0);
if (mListView.getFirstVisiblePosition() == 0 && c != null
&& c.getTop() == 0) {
flag = true;
}
}
if (deltaY < 0F && flag || getChildAt(0).getTop() > -MAX_LENGHT) { // deltaY
// <
// 0
// 向下
handled = move(deltaY, false);
} else
handled = false;
return handled;
}
public void onShowPress(MotionEvent motionevent) {
}
public boolean onSingleTapUp(MotionEvent motionevent) {
return false;
}
public void setRefreshListioner(OnRefreshListioner RefreshListioner) {
mRefreshListioner = RefreshListioner;
}
public boolean isAutoLoadMore() {
return isAutoLoadMore;
}
public void setAutoLoadMore(boolean isAutoLoadMore) {
this.isAutoLoadMore = isAutoLoadMore;
if (!isAutoLoadMore) {
foot.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onLoadMore();
}
});
mListView.setOnScrollListener(null);
} else {
mListView.setOnScrollListener(new OnScrollListener() {
public void onScrollStateChanged(AbsListView view,
int scrollState) {
if (isEnd && scrollState == SCROLL_STATE_IDLE && hasMore) {
onLoadMore();
}
}
public void onScroll(AbsListView view, int f, int v, int t) {
if (f + v >= t - 1)
isEnd = true;
else
isEnd = false;
}
});
foot.setOnClickListener(null);
}
}
public void setHasMore(boolean hasMore) {
this.hasMore = hasMore;
}
public void removeFoot() {
footer_layout.removeAllViews();
}
public void addFoot() {
footer_layout.removeAllViews();
footer_layout.addView(foot);
}
}
 

 

第二步:设计xml这里注意的是在自定义控件PullDownListView中内嵌一个ListView控件

 

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
       <com.example.widget.PullDownListView
        android:id="@+id/sreach_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
        <ListView
            android:id="@+id/list"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="0.0"
            android:divider="@null"
            android:drawSelectorOnTop="false"
            android:fadingEdgeLength="0.0sp" />
    </com.example.widget.PullDownListView>
</RelativeLayout>
 

 

 

第三步:编写MainActivity 实现PullDownListView.OnRefreshListioner回调接口实现功能的演示:

 

import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ListView;
import com.example.widget.PullDownListView;
public class MainActivity extends Activity  implements PullDownListView.OnRefreshListioner{
private PullDownListView mPullDownView;
private ListView mListView;
private List<String> list = new ArrayList<String>();
private MyAdapter adapter;
private Handler mHandler = new Handler();
private int maxAount = 20;//设置了最大数据值
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    	mPullDownView = (PullDownListView) findViewById(R.id.sreach_list);
mPullDownView.setRefreshListioner(this);
mListView = mPullDownView.mListView;
addLists(10);
    adapter = new MyAdapter(this,list);
    mPullDownView.setMore(true);//这里设置true表示还有更多加载,设置为false底部将不显示更多
    mListView.setAdapter(adapter);
    }
    
    private void addLists(int n){
    
    	 n += list.size();
    	 for(int i=list.size();i<n;i++){
        list.add("选项"+i);
     }
    }
    
    /**
     * 刷新,先清空list中数据然后重新加载更新内容
     */
public void onRefresh() {
mHandler.postDelayed(new Runnable() {
public void run() {
list.clear();
addLists(10);
mPullDownView.onRefreshComplete();//这里表示刷新处理完成后把上面的加载刷新界面隐藏
mPullDownView.setMore(true);//这里设置true表示还有更多加载,设置为false底部将不显示更多
adapter.notifyDataSetChanged();
}
}, 1500);
}
/**
 * 加载更多,在原来基础上在添加新内容
 */
public void onLoadMore() {
mHandler.postDelayed(new Runnable() {
public void run() {
addLists(5);//每次加载五项新内容
mPullDownView.onLoadMoreComplete();//这里表示加载更多处理完成后把下面的加载更多界面(隐藏或者设置字样更多)
if(list.size()<maxAount)//判断当前list中已添加的数据是否小于最大值maxAount,是那么久显示更多否则不显示
mPullDownView.setMore(true);//这里设置true表示还有更多加载,设置为false底部将不显示更多
else
mPullDownView.setMore(false);
adapter.notifyDataSetChanged();
}
}, 1500);
}
    
}
 

 

第四:运行效果如图:




 

 

 



 

  • 大小: 25.2 KB
  • 大小: 26.2 KB
  • 大小: 25.3 KB
  • 大小: 26.3 KB
  • 大小: 26.4 KB
15
5
分享到:
评论
19 楼 lmx612 2017-01-03  
下载下来可以直接运行,也是我想要的 
18 楼 断水 2014-09-17  
怎么除去headView
17 楼 814687491 2014-06-12  
下拉源码下来学习下!
16 楼 猫咪seven 2014-03-04  
LZ太棒了!!!感谢分享!!!
15 楼 yusan 2014-02-22  
,感谢楼主,正好用上了!
14 楼 zywisdoml 2014-01-04  
感谢楼主分享,学习了。
不过貌似还存在bug,就是先点击加载更多然后迅速下拉刷新,headview就收不回去。
13 楼 max8888888 2013-07-24  
感谢楼主,学习了~
12 楼 Sev7en_jun 2013-07-10  
lz是牛人
11 楼 Hackeny 2013-03-07  
感谢楼主分享,
不知道大家有没有发现,代码有个问题,当刷新很多的时候,顶部item不是“选项0”时,下拉时就直接进入刷新操作(顶部覆盖的item都看不到了),不是应该是先将listview的内容显示完才做刷新的吗?
4楼跟在下是一个意思吗?请楼主或其他大神帮忙回答一下啊
10 楼 lhy_0621 2013-03-05  
非常的感谢楼主的共享代码
9 楼 104zz 2013-02-25  
happy9837457 写道
第一次进入加载状态怎么实现!

你可以实现onRefresh()这个方法进行控制你需要的加载状态
8 楼 happy9837457 2013-02-25  
第一次进入加载状态怎么实现!
7 楼 wxcking 2013-01-25  
不错, 可以实现效果, 请问一下如何在列表上加上一个onClick事件, 然后再获得是点击了哪一行, 这个怎么来实现, 求代码, 自己也在尝试中... ...
6 楼 hualikejava 2013-01-25  
我觉得这个已经还是不错的,另外网上也留传那个叫PullToRefreshlibrary
5 楼 284772894 2013-01-23  
代码这么多,能不能优化一下
4 楼 a253861581 2013-01-22  
这个还是有bug,我用了一台旧机器。滑动的时候下拉刷新显示的文字显示不出来。sdk9以上的没事。不知道咋回事,另外我还修改了滑动手指滑出屏幕外滑动不了的情况,总之这个已经很完善类。
3 楼 asleep886 2013-01-11  
哎 我放在 ActivityGroup的子activity中 总是没把头部全部隐去。 郁闷
2 楼 yinhaitao1117 2013-01-10  
我靠,这么好的实例都没有人顶
1 楼 亦飞_成都 2013-01-07  
感谢楼主分享.学习了

相关推荐

    后勤智能管理系统-.. (2).pdf

    后勤智能管理系统-.. (2).pdf

    Markdown.Monster.v2.0.9.0-CRD.rar

    Markdown.Monster.v2.0.9.0-CRD

    毕业设计-主成分分析算法Python代码.rar

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、本项目仅用作交流学习参考,请切勿用于商业用途。

    四川大学期末考试试题(开卷).docx

    四川大学期末考试试题(开卷).docx

    c#入门之实现计算器源码

    c#入门之实现计算器源码

    Python项目-游戏源码-10 植物大战僵尸.zip

    Python课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。

    基于ssm的期末考试考务管理系统源代码(完整前后端+mysql+说明文档+LW).zip

    主要需求:3个权限 该系统功能模块主要为三部分,即学生模块、教师模块、管理员模块。 学生模块包括:查看考试安排信息(随机安排就行)、学生 缓考在线申请(教师查看)、在线签订承诺书(学生签字); 教师模块包括:查询监考表、考试违纪学生信息录入; 管理员模块包括:考试时间地点管理、 调整排班信息、信息管理等(主要是增删改查) 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7

    springboot-基于SpringBoot的小型民营加油站管理系统.zip

    springboot-基于SpringBoot的小型民营加油站管理系统.zip

    framework-all

    framework_all

    【Ubuntu】【交叉编译】实现跑马灯并以开发板为服务器通过cgi实现远程控制.html

    【Ubuntu】【交叉编译】实现跑马灯并以开发板为服务器通过cgi实现远程控制.html

    基于ssm的学生宿舍管理系统设计与实现源代码(java+jsp+mysql+说明文档+LW).zip

    实现了用户在线选择试题并完成答题,在线查看考核分数。管理员管理常用语句管理、常用语句收藏管理、常用语句留言管理、成语学习管理、成语学习收藏管理、成语学习留言管理、字典管理、论坛管理、基础管理、基础收藏管理、基础留言管理、情景学习管理、情景学习收藏管理、情景学习留言管理、诗词学习管理、诗词学习收藏管理、诗词学习留言管理、用户管理、管理员管理等功能。 项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 部署容器:tomcat7

    RTMPOSE rtmpose-m-2xb64-210e-mpii-256x256-A5000

    RTMPOSE rtmpose-m-2xb64-210e-mpii-256x256-A5000

    jdk-17.0.4.1

    jdk-17.0.4.1

    户外广告全球市场研究报告:2023年市场规模约为14121.8亿元

    户外广告全球市场研究报告:2023年市场规模约为14121.8亿元 在数字时代,户外广告作为传统与现代的交汇点,正以独特的魅力吸引着全球广告主的目光。从繁华都市的霓虹灯到偏远乡村的路牌,户外广告无处不在,以其直观、生动的形式,精准触达消费者的生活与出行场景。然而,在激烈的市场竞争中,如何把握市场趋势,实现精准传播,成为广告主面临的一大挑战。 市场概况 近年来,全球广告市场在经济周期动荡中展现出强大的韧性,不断触及新高度。据QYR最新调研,2023年全球广告市场规模已增至约9044.9亿美元,其中户外广告市场占据了一席之地。作为全球广告市场的重要组成部分,中国广告市场规模同样在快速扩张,2023年市场规模约为14121.8亿元,稳居世界前列。户外广告市场更是表现抢眼,2023年全球户外广告市场规模约为547.8亿美元,中国市场规模则达到约820.5亿元,展现出强劲的增长势头。 技术创新与趋势 随着数字化技术的广泛应用,户外广告的形式和内容不断升级,从传统的平面广告到如今的视频广告,再到未来的智能互动广告,户外广告正逐步走向智能化、个性化。视频广告以其音频视觉双重刺激的特点,通过故事情节、

    基于ssm的班主任助理系统的设计与实现+jsp源代码(完整前后端+mysql+说明文档+LW).zip

    学生信息管理: 添加学生信息:录入新学生的信息到系统。 修改学生信息:对现有学生信息进行更新和修改。 请假管理: 新增请假记录:记录学生的请假信息。 审批请假:对学生的请假申请进行审批。 请假统计:对请假记录进行统计分析。 申请假统计:可能是对请假申请的统计,可能包括未批准的请假。 成绩管理: 新增成绩:录入学生的成绩信息。 修改成绩:对学生的成绩进行修改。 删除成绩:从系统中移除学生的成绩记录。 家长信息管理: 新增家长信息:录入家长的联系信息。 修改家长信息:更新家长的联系信息。 删除家长信息:移除家长的联系信息。 学业预警管理: 新增学业预警:对可能存在学业问题的学生设置预警。 修改学业预警:更新学业预警信息。 删除学业预警:移除学业预警。 实习管理: 新增实习信息:录入学生的实习信息。 修改实习信息:更新学生的实习信息。 删除实习信息:移除学生的实习信息。 项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11...

    基于ssm的学生请假系统+jsp源代码(完整前后端+mysql+说明文档+LW).zip

    系统实现: 老师信息管理:老师信息的查询管理,可以删除老师信息、修改老师信息、新增老师信息。 学生信息管理:学生信息的查询管理,可以删除学生信息、修改学生信息、新增学生信息。 请假信息管理:学生的学院、专业、班级、请假类型进行条件查询,还可以对请假数据进行修改、审批、驳回、删除等功能,学生可以进行申请请假信息操作等等。 留言信息管理:对学生添加的留言信息进行回复功能,只有管理员和老师可以进行回复。 项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7

    喜来登五星酒店酒店数字客房管理系统.pdf

    喜来登五星酒店酒店数字客房管理系统.pdf

    Python项目-实例-07 抖音表白.zip

    Python课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。

    vscode的概要介绍与分析

    以下是一个关于VSCode(Visual Studio Code)的资源描述和项目源码的简要介绍: 资源描述 VSCode是一款由微软开发的开源、免费且功能强大的源代码编辑器,它以其轻量级、高效、多语言支持、智能代码补全、内置调试工具、丰富的扩展市场以及跨平台兼容性等特点,赢得了广大开发者的青睐。在资源方面,VSCode提供了详尽的官方文档,涵盖了从安装配置到高级功能的全面指南。此外,互联网上有大量的在线教程、视频教程以及社区论坛和问答网站,如CSDN博客、Stack Overflow等,为开发者提供了丰富的学习资源和交流平台。 项目源码概述 由于VSCode是开源的,其源码可以在GitHub等代码托管平台上找到。VSCode的源码结构清晰,包含了构建脚本、内置插件、App元信息、平台相关静态资源、工具脚本、源码目录等多个部分。其中,源码目录是核心部分,包含了编辑器、工作区、平台支持等多个模块的代码。每个模块都有详细的注释和文档,方便开发者理解和扩展。 VSCode的源码采用了TypeScript语言编写,并使用了Electron框架来构建跨平台桌面应用程序。开发者可以根据自己的

    Java系统源码+旅游管理系统

    Java系统源码+旅游管理系统 内容概要: 本资源包含了完整的Java前后端源码及说明文档,适用于想要快速搭建并部署Java Web应用程序的开发者、学习者。 技术栈: 后端:Java生态系统,包含Spring Boot、Shiro、MyBatis等,数据库使用Mysql 前端:Vue、Bootstrap、Jquery等 适用场景示例: 1、毕业生希望快速启动一个新的Java Web应用程序。 2、团队寻找一个稳定的模板来加速产品开发周期。 3、教育机构或个人学习者用于教学目的或自学练习。 4、创业公司需要一个可以立即投入使用的MVP(最小可行产品)。

Global site tag (gtag.js) - Google Analytics