- 浏览: 1508362 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (63)
- android 地图开发,获取经纬度 (5)
- android基于Gps 定位和基站定位获取经纬度 (0)
- ADB server didn't ACK (1)
- android 开发颜色搭配 (2)
- android 设置wifi静态IP及DNS的方法 (2)
- android自定义滑动启动和关闭按钮 (1)
- android listview滑动删除 (2)
- js显示日历 (1)
- android EditText 设计 (1)
- Oracle执行计划详解 (1)
- android 下拉刷新以及加载更多 (1)
- android 技术 (2)
- android 欢迎界面翻页效果 (1)
- Android Animation 动画 (1)
- js 浮动效果 (1)
- android ListView (1)
- android PopupWindow (1)
- android Activity (1)
- android日期选择 (1)
- XML解析 (1)
- android Activity (1)
- JSON详解 (1)
- android 拍照选图 (2)
- android ActivityDialog (1)
- android Activity自定义Dialog (1)
- Android 感应器 (2)
- android 图片压缩 (1)
- Android 多媒体扫描 (2)
- Android 信息推送 (1)
- xmpp及时通讯 (1)
- Android NDK (1)
- android 图片处理 (1)
- android GridView (1)
- android 录音 (1)
- android 目录 (1)
- android Dialog (1)
- Android 屏幕滑动事件 (1)
- Android 数据库操作 (4)
- android插件开发模式 (1)
- TCP/IP 长连接 (1)
- OS操作 (1)
- android 抓包 (1)
- android 网络数据传输 (1)
最新评论
-
cys一:
google api key v2 新的不能使用
android google地图定位开发,且可以自由移动位置重新获取定位,地址信息 -
lmx612:
下载下来可以直接运行,也是我想要的
android listview 下拉刷新以及加载更多 -
tvvbbb:
辛苦楼主了
android 仿微信聊天界面,以及语音录制功能 -
Mandmg:
等了一天.终于下载到了
android 登陆、提交数据或加载数据时提示页面 -
ya1o1123:
android Activity实现从底部弹出或滑出选择菜单或窗口
本例是实现下拉时刷新并且底部设置加载更多选择并在下拉和回滑时加入相应的动画效果,
功能实现主要为自定义一个Layout在此布局中头部刷新主要是用到了在头部添加布局view控件并使用GestureDetector控制下拉时的变化以便控制滑动的效果,在自定义底部也加一个加载更多的布局,中间内嵌一个ListView控件以显示内容。具体步骤如下:
第一步:设计自定义布局PullDownListView继承FrameLayout 实现GestureDetector.OnGestureListener和Animation.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); } }
第四:运行效果如图:
- pulldownview.zip (679.7 KB)
- 描述: 源码
- 下载次数: 3343
评论
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就收不回去。
不过貌似还存在bug,就是先点击加载更多然后迅速下拉刷新,headview就收不回去。
13 楼
max8888888
2013-07-24
感谢楼主,学习了~
12 楼
Sev7en_jun
2013-07-10
lz是牛人
11 楼
Hackeny
2013-03-07
感谢楼主分享,
不知道大家有没有发现,代码有个问题,当刷新很多的时候,顶部item不是“选项0”时,下拉时就直接进入刷新操作(顶部覆盖的item都看不到了),不是应该是先将listview的内容显示完才做刷新的吗?
4楼跟在下是一个意思吗?请楼主或其他大神帮忙回答一下啊
不知道大家有没有发现,代码有个问题,当刷新很多的时候,顶部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
Markdown.Monster.v2.0.9.0-CRD
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、本项目仅用作交流学习参考,请切勿用于商业用途。
四川大学期末考试试题(开卷).docx
c#入门之实现计算器源码
Python课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
主要需求:3个权限 该系统功能模块主要为三部分,即学生模块、教师模块、管理员模块。 学生模块包括:查看考试安排信息(随机安排就行)、学生 缓考在线申请(教师查看)、在线签订承诺书(学生签字); 教师模块包括:查询监考表、考试违纪学生信息录入; 管理员模块包括:考试时间地点管理、 调整排班信息、信息管理等(主要是增删改查) 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7
springboot-基于SpringBoot的小型民营加油站管理系统.zip
framework_all
【Ubuntu】【交叉编译】实现跑马灯并以开发板为服务器通过cgi实现远程控制.html
实现了用户在线选择试题并完成答题,在线查看考核分数。管理员管理常用语句管理、常用语句收藏管理、常用语句留言管理、成语学习管理、成语学习收藏管理、成语学习留言管理、字典管理、论坛管理、基础管理、基础收藏管理、基础留言管理、情景学习管理、情景学习收藏管理、情景学习留言管理、诗词学习管理、诗词学习收藏管理、诗词学习留言管理、用户管理、管理员管理等功能。 项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 部署容器:tomcat7
RTMPOSE rtmpose-m-2xb64-210e-mpii-256x256-A5000
jdk-17.0.4.1
户外广告全球市场研究报告:2023年市场规模约为14121.8亿元 在数字时代,户外广告作为传统与现代的交汇点,正以独特的魅力吸引着全球广告主的目光。从繁华都市的霓虹灯到偏远乡村的路牌,户外广告无处不在,以其直观、生动的形式,精准触达消费者的生活与出行场景。然而,在激烈的市场竞争中,如何把握市场趋势,实现精准传播,成为广告主面临的一大挑战。 市场概况 近年来,全球广告市场在经济周期动荡中展现出强大的韧性,不断触及新高度。据QYR最新调研,2023年全球广告市场规模已增至约9044.9亿美元,其中户外广告市场占据了一席之地。作为全球广告市场的重要组成部分,中国广告市场规模同样在快速扩张,2023年市场规模约为14121.8亿元,稳居世界前列。户外广告市场更是表现抢眼,2023年全球户外广告市场规模约为547.8亿美元,中国市场规模则达到约820.5亿元,展现出强劲的增长势头。 技术创新与趋势 随着数字化技术的广泛应用,户外广告的形式和内容不断升级,从传统的平面广告到如今的视频广告,再到未来的智能互动广告,户外广告正逐步走向智能化、个性化。视频广告以其音频视觉双重刺激的特点,通过故事情节、
学生信息管理: 添加学生信息:录入新学生的信息到系统。 修改学生信息:对现有学生信息进行更新和修改。 请假管理: 新增请假记录:记录学生的请假信息。 审批请假:对学生的请假申请进行审批。 请假统计:对请假记录进行统计分析。 申请假统计:可能是对请假申请的统计,可能包括未批准的请假。 成绩管理: 新增成绩:录入学生的成绩信息。 修改成绩:对学生的成绩进行修改。 删除成绩:从系统中移除学生的成绩记录。 家长信息管理: 新增家长信息:录入家长的联系信息。 修改家长信息:更新家长的联系信息。 删除家长信息:移除家长的联系信息。 学业预警管理: 新增学业预警:对可能存在学业问题的学生设置预警。 修改学业预警:更新学业预警信息。 删除学业预警:移除学业预警。 实习管理: 新增实习信息:录入学生的实习信息。 修改实习信息:更新学生的实习信息。 删除实习信息:移除学生的实习信息。 项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11...
系统实现: 老师信息管理:老师信息的查询管理,可以删除老师信息、修改老师信息、新增老师信息。 学生信息管理:学生信息的查询管理,可以删除学生信息、修改学生信息、新增学生信息。 请假信息管理:学生的学院、专业、班级、请假类型进行条件查询,还可以对请假数据进行修改、审批、驳回、删除等功能,学生可以进行申请请假信息操作等等。 留言信息管理:对学生添加的留言信息进行回复功能,只有管理员和老师可以进行回复。 项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7
喜来登五星酒店酒店数字客房管理系统.pdf
Python课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
以下是一个关于VSCode(Visual Studio Code)的资源描述和项目源码的简要介绍: 资源描述 VSCode是一款由微软开发的开源、免费且功能强大的源代码编辑器,它以其轻量级、高效、多语言支持、智能代码补全、内置调试工具、丰富的扩展市场以及跨平台兼容性等特点,赢得了广大开发者的青睐。在资源方面,VSCode提供了详尽的官方文档,涵盖了从安装配置到高级功能的全面指南。此外,互联网上有大量的在线教程、视频教程以及社区论坛和问答网站,如CSDN博客、Stack Overflow等,为开发者提供了丰富的学习资源和交流平台。 项目源码概述 由于VSCode是开源的,其源码可以在GitHub等代码托管平台上找到。VSCode的源码结构清晰,包含了构建脚本、内置插件、App元信息、平台相关静态资源、工具脚本、源码目录等多个部分。其中,源码目录是核心部分,包含了编辑器、工作区、平台支持等多个模块的代码。每个模块都有详细的注释和文档,方便开发者理解和扩展。 VSCode的源码采用了TypeScript语言编写,并使用了Electron框架来构建跨平台桌面应用程序。开发者可以根据自己的
Java系统源码+旅游管理系统 内容概要: 本资源包含了完整的Java前后端源码及说明文档,适用于想要快速搭建并部署Java Web应用程序的开发者、学习者。 技术栈: 后端:Java生态系统,包含Spring Boot、Shiro、MyBatis等,数据库使用Mysql 前端:Vue、Bootstrap、Jquery等 适用场景示例: 1、毕业生希望快速启动一个新的Java Web应用程序。 2、团队寻找一个稳定的模板来加速产品开发周期。 3、教育机构或个人学习者用于教学目的或自学练习。 4、创业公司需要一个可以立即投入使用的MVP(最小可行产品)。