在android中有时我们要实现下拉刷新的功能,我在前日人的基础上自己实现了一个。
其实实现的原理很简单,显示在listView的headerView中添加一个要刷新的进度条显示设置这个view影藏,在你拖动listView的时候当你托到最上面的时候,进行判断显示,影藏进度条,在显示进度条后你松开手势的时候根据不同的状态实现页面的操作。不多说了,实现的代码如下:
显示声明一个显示进度条的view的布局文件:head.xml
在重写listView实现onScrollListener
上传一张显示的箭头的图片,这是重其它地方搞来的
其实实现的原理很简单,显示在listView的headerView中添加一个要刷新的进度条显示设置这个view影藏,在你拖动listView的时候当你托到最上面的时候,进行判断显示,影藏进度条,在显示进度条后你松开手势的时候根据不同的状态实现页面的操作。不多说了,实现的代码如下:
显示声明一个显示进度条的view的布局文件:head.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/head_rootLayout" android:layout_width="fill_parent" android:layout_height="wrap_content" > <!-- 内容 --> <RelativeLayout android:id="@+id/head_contentLayout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="30dp" > <!-- 箭头图像、进度条 --> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" > <!-- 箭头 --> <ImageView android:id="@+id/head_arrowImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/arrow" /> <!-- 进度条 --> <ProgressBar android:id="@+id/head_progressBar" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="gone" /> </FrameLayout> <!-- 提示、最近更新 --> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:gravity="center_horizontal" android:orientation="vertical" > <!-- 提示 --> <TextView android:id="@+id/head_tipsTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉刷新" android:textColor="#ffffff" android:textSize="20sp" /> <!-- 最近更新 --> <TextView android:id="@+id/head_lastUpdatedTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="最近更新" android:textColor="#cc6600" android:textSize="10sp" /> </LinearLayout> </RelativeLayout> </LinearLayout>
在重写listView实现onScrollListener
public class MyListView extends ListView implements OnScrollListener { /** * 下拉现实的headView */ private View headView; /** * 刷新的箭头的view */ private ImageView arrowImageView; /** * 显示刷新的进度条 */ private ProgressBar progressBar = null; /** * 显示提示刷新的提示语句 */ private TextView tipsTextView; /** * 显示的第一个Item的view */ private int fistVisibleItem = -1; /** * headView的宽度 */ private int headContextWidth=0; /** * 向下箭头的样式 */ private Animation todownAnimation; /** * 向上箭头的样式 */ private Animation toupAnimation; /** * headView的高度 */ private int headContextHeight = 0; /** * 定义当前滑动的状态 */ private int state = DONE; /** * 未执行的状态 */ private static final int DONE = 0; /** * 即将松开去刷新界面,箭头变为向上 */ private static final int RELEATSE_TO_FRESH = 1; /** * 正在加载数据 */ private static final int LOADING = 2; /** * 拉动去刷新,调整箭头的位置,箭头向下 */ private static final int PULL_TO_REFRESH = 3; /** * 确定当前只有一个开始的位置被记录 */ private boolean isRecorded = false; /** * 设置滑动的比例 */ private static final int FLING_V = 3; /** * 开始的位置 */ private int starty =0; private boolean isback = false; /** * 刷新界面的回调接口 */ private OnRefreshListener onRefreshListener; public interface OnRefreshListener { public void onRefresh(); } public MyListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(); } public MyListView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public MyListView(Context context) { super(context); initView(); } /** * 初始化要显示的headview * * @see intView */ private void initView() { headView = ((LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.head, null); arrowImageView = (ImageView)headView.findViewById(R.id.head_arrowImageView); progressBar = (ProgressBar)headView.findViewById(R.id.head_progressBar); tipsTextView = (TextView)headView.findViewById(R.id.head_tipsTextView); //重新设置headView的大小 resetHeadView(); headContextWidth = headView.getMeasuredWidth(); headContextHeight = headView.getMeasuredHeight(); //设置headView的padding headView.setPadding(0, -headContextHeight, 0, 0); headView.invalidate(); //添加headView到listView的第一个item中去 addHeaderView(headView,null,false); setOnScrollListener(this); todownAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); todownAnimation.setInterpolator(new LinearInterpolator()); todownAnimation.setDuration(250); todownAnimation.setFillAfter(true); toupAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); toupAnimation.setInterpolator(new LinearInterpolator()); toupAnimation.setDuration(250); toupAnimation.setFillAfter(true); state = DONE; isRecorded = false; } /** * 实现listView的触摸的事件 * * @param ev * * 点击的事件 * * @see onTouchEvent */ @Override public boolean onTouchEvent(MotionEvent ev) { int tempy = 0; switch(ev.getAction()) { //点击的事件 case MotionEvent.ACTION_DOWN: if(fistVisibleItem ==0 && !isRecorded) { isRecorded = true; starty = (int)ev.getY(); } break; //移动的事件 case MotionEvent.ACTION_MOVE: tempy = (int)ev.getY(); if(fistVisibleItem ==0 && !isRecorded) { isRecorded = true; starty = (int)ev.getY(); } //当前的用户不在加载数据,并且不在刷新界面的时候 if(state != LOADING && isRecorded) { //可以松开去刷新界面了 if(state == RELEATSE_TO_FRESH) { setSelection(0); //用户在向上推的时候 if((tempy-starty)/FLING_V0) { state = PULL_TO_REFRESH; changeHeadViewState(); } //用户快速向上推 else if(tempy-startyheadContextHeight) { isback = true; state = RELEATSE_TO_FRESH; changeHeadViewState(); } //上推到顶了 else if((tempy-starty)/FLING_V0) { state = PULL_TO_REFRESH; changeHeadViewState(); } } //修改显示view的大小 if(state == PULL_TO_REFRESH||state == RELEATSE_TO_FRESH) { headView.setPadding(0, -headContextHeight+(tempy-starty)/FLING_V, 0, 0); } } break; //手势离开控件 case MotionEvent.ACTION_UP: if(state != LOADING) { if(state == PULL_TO_REFRESH) { state = DONE; changeHeadViewState(); } else if(state == DONE) { } else if(state == RELEATSE_TO_FRESH) { state = LOADING; changeHeadViewState(); //刷新界面 onRefresh(); } } isRecorded = false; break; } return super.onTouchEvent(ev); } /** * 刷新界面的数据 * * @see onRefresh */ private void onRefresh() { if(null != onRefreshListener) { onRefreshListener.onRefresh(); } } /** * 界面刷新结束 * * @see complete */ public void complete() { state = DONE; changeHeadViewState(); } /** * 根据状态修改headView * * @see changeHeadViewState */ private void changeHeadViewState() { switch(state) { //箭头向上 case RELEATSE_TO_FRESH: arrowImageView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tipsTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); arrowImageView.startAnimation(toupAnimation); Log.e(VIEW_LOG_TAG, "RELEATSE_TO_FRESH"); tipsTextView.setText("松开刷新"); break; //箭头向下 case PULL_TO_REFRESH: arrowImageView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tipsTextView.setVisibility(View.VISIBLE); if(isback) { Log.e(VIEW_LOG_TAG, "PULL_TO_REFRESH"); arrowImageView.clearAnimation(); arrowImageView.startAnimation(todownAnimation); isback = false; } tipsTextView.setText("下拉刷新"); break; case DONE: headView.setPadding(0, -headContextHeight, 0, 0); arrowImageView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tipsTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); tipsTextView.setText("下拉刷新"); break; //正在现在插件 case LOADING: headView.setPadding(0,0, 0, 0); arrowImageView.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); tipsTextView.setVisibility(View.VISIBLE); arrowImageView.clearAnimation(); tipsTextView.setText("正在刷新"); break; default: break; } } /** * 重新设置headView的大小 * * @see resetHeadView */ private void resetHeadView() { ViewGroup.LayoutParams layoutParams = headView.getLayoutParams(); if(null == layoutParams) { layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT); } int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, layoutParams.width); int tempHeight = layoutParams.height; int childHeightSpec=0; if(tempHeight>0) { childHeightSpec=MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY); } else { childHeightSpec=MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.UNSPECIFIED); } headView.measure(childWidthSpec, childHeightSpec); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } /** * listView滑动的时候获取第一个显示的item */ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { fistVisibleItem = firstVisibleItem; } public void setOnRefreshListener(OnRefreshListener onRefreshListener) { this.onRefreshListener = onRefreshListener; } }
上传一张显示的箭头的图片,这是重其它地方搞来的
发表评论
-
android aidl 主进程子进程间数据相互传递
2012-12-18 11:49 3967android中进程间的通信对与大量的接口的调用的时候,一般是 ... -
android 实现在titlebar上显示进度条
2012-11-13 18:48 867先是在setContextView之前设置界面的样式 requ ... -
android aidl进程间方法的调用
2012-10-10 14:21 1646android 进程的通信很多,可以用intent传递数据,可 ... -
listView 点击一个Item效果
2012-01-13 17:20 6本人刚做一个项目需求是这样的:展示通话记录的列表,点击每一条记 ... -
android aidl
2012-01-11 11:12 1058android中的进程间的通信很多,下面粗略的讲解一下如何实现 ... -
android 权限大全
2011-12-22 20:08 890android.permission.ACCESS_CHECK ... -
android Action大全
2011-12-21 20:26 1172String ADD_SHORTCUT_ACTION 动作 ... -
android 自定义桌面
2011-12-03 16:23 14161、 把背景图片push到SDCard中 adb pu ... -
android 游戏开发加载界面获取资源文件中图片ID的集合
2011-12-03 13:18 4980主要给大家介绍如何加载界面的图片。正如前面Abs ... -
android 判断网络是否连接可用
2011-12-03 13:06 1695// 判断网络是否正常 public static boole ... -
火星通讯录
2011-11-25 20:27 1430一、用.rar打开apk文档,得到文档结构图如下所示 ... -
android 四种加载模式2
2011-11-16 11:13 1000singleInstance模式解决了这个问题(绕了这么半天才 ... -
activity 的四种加载的模式1
2011-11-16 11:11 1033在android应用的开发中有时会activity之间的重复的 ... -
android 面试题
2011-11-09 20:17 1052android 面试题 1.android中进程和进程间的通信 ... -
android ksoap调用天气预报
2011-11-08 19:27 5133下面例子改自网上例子:http://express.ruank ... -
android NDK
2011-11-03 21:34 2079Cygwin+Android NDK的安装 时 间 版 本 ... -
android 判断sdcard是否存在,以及写入权限
2011-10-16 16:57 5789做android 开发的时候经常涉及到权限的问题,而我们像sd ... -
android bitmap
2011-10-14 11:02 849对于android终端应用软件开发的人员来说图片显示时,如果图 ... -
android popupwindow,调用本地的图库,照相
2011-10-14 10:51 5434我们写项目的时候又是要自定义弹出美观的悬浮操作窗口,这里我们可 ... -
android notification
2011-10-14 10:39 1053前些天刚刚做一个项目的预演,要用到广播通知,一下是一些小的学习 ...
相关推荐
本教程将基于提供的`PullToRefreshTest`项目,详细介绍如何在Android中快速实现下拉刷新功能。我们将讨论以下几个关键知识点: 1. **SwipeRefreshLayout**: Android SDK提供了一个名为`SwipeRefreshLayout`的布局...
本篇文章将探讨一种实现Android下拉刷新的方法,主要涉及自定义View组件以及相关监听器的使用。 首先,我们需要创建一个自定义的View组件,我们将其命名为`PullToRefreshView`。这个组件需要继承自`LinearLayout`或...
通过以上步骤,我们便可以在Android原生环境中实现一个基本的下拉刷新功能。这个例子对于Android新手来说是一个很好的学习起点,可以帮助他们理解如何在实际项目中运用SwipeRefreshLayout。在实际开发中,还可以根据...
实现WebView的下拉刷新功能,我们可以利用Android的SwipeRefreshLayout控件。SwipeRefreshLayout是Android SDK提供的一种可以包裹其他ViewGroup,尤其是ListView、GridView、RecyclerView等的容器,当用户下拉时,它...
本教程将指导你在Android Studio中为ListView实现下拉刷新功能。 1. **下拉刷新概念** 下拉刷新(Pull-to-Refresh)是一种常见的UI设计模式,允许用户通过从列表顶部向下拉动来触发数据的更新。这种功能常见于新闻...
"Android 阻尼下拉刷新列表的实现方法" Android 阻尼下拉刷新列表是一个非常实用的功能,它可以提供给用户一个更加流畅的体验。下面我们将详细介绍 Android 阻尼下拉刷新列表的实现方法。 首先,我们需要了解 ...
下拉刷新功能通常在用户滚动列表到顶部时触发,更新数据并显示刷新状态。在Android中,我们通常使用SwipeRefreshLayout来实现这一功能。SwipeRefreshLayout包含一个子视图,当用户下拉这个子视图时,会触发刷新事件...
这样,无需从头实现下拉刷新功能,可以节省时间和精力。 五、PullToRefreshListFragment `PullToRefreshListFragment`这个名字暗示了这是一个针对ListFragment的下拉刷新实现。ListFragment是Android SDK中的一个类...
8. **兼容性**:下拉刷新功能需考虑不同Android版本和设备的兼容性。SwipeRefreshLayout自API 19引入,对于更低版本的Android,可能需要使用第三方库如PullToRefresh或SwipeBackLayout来实现类似功能。 9. **第三方...
通过分析这个DEMO,开发者可以学习如何结合SwipeRefreshLayout和自定义滚动监听来实现完整的上拉加载和下拉刷新功能。同时,这个DEMO也提供了一个基础框架,开发者可以根据自己的需求在此基础上进行扩展,例如,替换...
本资源包“Android开发+下拉刷新功能+快速实现教程+应用开发技巧:Android教你如何一分钟实现下拉刷新功能项目完整实例代码”提供了一种快速集成下拉刷新功能到Android应用中的方法。该资源详细展示了通过简洁的实例...
通过以上步骤,你可以在你的Android应用中实现一个通用的下拉刷新功能。无论是使用Android SDK自带的SwipeRefreshLayout还是第三方库如XRefreshView,都能满足你对下拉刷新的需求,并且可以根据项目需求进行定制,...
ListView下拉刷新功能是现代移动应用中的一个常见特性,允许用户通过下拉列表来获取最新的数据,如社交媒体的新消息或天气更新。这个"Android应用源码 ListView下拉刷新 Demo"提供了一个实际的例子,帮助开发者了解...
本篇文章将详细讲解如何在Android中实现ListView的下拉刷新功能,以达到类似手机微博的用户体验。 首先,我们需要了解下拉刷新的基本原理。在Android中,下拉刷新通常由一个可扩展的Header View组成,当用户下拉时...
"ScrollView实现下拉刷新"这个主题聚焦于如何在滚动视图中添加一个下拉刷新功能,这通常用于列表或者网格视图,使得用户可以更新内容而无需离开当前页面。这种特性在许多应用程序中非常常见,比如社交媒体应用和新闻...
这个"Android listView下拉刷新上拉刷新带阻尼效果"的源码Demo是几年前的一个示例,旨在帮助学生理解和实现Android应用中的下拉刷新和上拉加载更多功能,同时加入了阻尼效果,提升用户体验。阻尼效果是指在用户滑动...
本教程将重点讲解如何在ListView中实现下拉刷新和动态加载数据的功能,同时处理图文混排的问题。 首先,我们要引入SwipeRefreshLayout库,它是Android SDK提供的一个下拉刷新框架。在`build.gradle`文件中添加以下...
在本项目中,你将找到一个可以直接运行的Android下拉刷新的代码实现。 下拉刷新的实现通常涉及到两个关键组件:SwipeRefreshLayout和RecyclerView(或ListView)。SwipeRefreshLayout是Android SDK提供的一种布局...
本Demo "Android ListView下拉刷新 Demo.rar" 主要是为了展示如何在ListView中实现下拉刷新功能,帮助开发者更好地理解和实践这一功能。 首先,我们要理解下拉刷新的基本概念。下拉刷新,顾名思义,是指用户在...
综上所述,要在Android的ScrollView中实现下拉刷新功能,可以利用SwipeRefreshLayout组件或者自定义ScrollView。通过这种方式,用户可以轻松地在应用中触发数据的刷新,提高用户体验。同时,这也可以作为提升开发者...