- 浏览: 384810 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
longxishui12:
这个一定要顶得高高的。
[Android UI界面] android中仿iphone实现listview的反弹效果 -
klower.jiang:
Good job, Thank you so much!
能够兼容ViewPager的ScrollView -
ZSRTFAT:
...
file size 的大小计算
public class PullToRefreshListView extends ListView implements OnScrollListener { private static final int TAP_TO_REFRESH = 1; private static final int PULL_TO_REFRESH = 2; private static final int RELEASE_TO_REFRESH = 3; private static final int REFRESHING = 4; private static final String TAG = "PullToRefreshListView"; private OnRefreshListener mOnRefreshListener; /** * Listener that will receive notifications every time the list scrolls. */ private OnScrollListener mOnScrollListener; private LayoutInflater mInflater; private LinearLayout mRefreshView; private TextView mRefreshViewText; private ImageView mRefreshViewImage; private ProgressBar mRefreshViewProgress; private TextView mRefreshViewLastUpdated; private int mCurrentScrollState; private int mRefreshState; private RotateAnimation mFlipAnimation; private RotateAnimation mReverseFlipAnimation; private int mRefreshViewHeight; private int mRefreshOriginalTopPadding; private int mLastMotionY; public PullToRefreshListView(Context context) { super(context); init(context); } public PullToRefreshListView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public PullToRefreshListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } private void init(Context context) { // Load all of the animations we need in code rather than through XML mFlipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); mFlipAnimation.setInterpolator(new LinearInterpolator()); mFlipAnimation.setDuration(250); mFlipAnimation.setFillAfter(true); mReverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); mReverseFlipAnimation.setInterpolator(new LinearInterpolator()); mReverseFlipAnimation.setDuration(250); mReverseFlipAnimation.setFillAfter(true); mInflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE); mRefreshView = (LinearLayout) mInflater.inflate( R.layout.pull_to_refresh_header, null); mRefreshViewText = (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_text); mRefreshViewImage = (ImageView) mRefreshView.findViewById(R.id.pull_to_refresh_image); mRefreshViewProgress = (ProgressBar) mRefreshView.findViewById(R.id.pull_to_refresh_progress); mRefreshViewLastUpdated = (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_updated_at); mRefreshViewImage.setMinimumHeight(50); mRefreshView.setOnClickListener(new OnClickRefreshListener()); mRefreshOriginalTopPadding = mRefreshView.getPaddingTop(); mRefreshState = TAP_TO_REFRESH; addHeaderView(mRefreshView); super.setOnScrollListener(this); measureView(mRefreshView); mRefreshViewHeight = mRefreshView.getMeasuredHeight(); } @Override protected void onAttachedToWindow() { setSelection(1); } @Override public void setAdapter(ListAdapter adapter) { super.setAdapter(adapter); setSelection(1); } /** * Set the listener that will receive notifications every time the list * scrolls. * * @param l The scroll listener. */ @Override public void setOnScrollListener(AbsListView.OnScrollListener l) { mOnScrollListener = l; } /** * Register a callback to be invoked when this list should be refreshed. * * @param onRefreshListener The callback to run. */ public void setOnRefreshListener(OnRefreshListener onRefreshListener) { mOnRefreshListener = onRefreshListener; } /** * Set a text to represent when the list was last updated. * @param lastUpdated Last updated at. */ public void setLastUpdated(CharSequence lastUpdated) { if (lastUpdated != null) { mRefreshViewLastUpdated.setVisibility(View.VISIBLE); mRefreshViewLastUpdated.setText(lastUpdated); } else { mRefreshViewLastUpdated.setVisibility(View.GONE); } } @Override public boolean onTouchEvent(MotionEvent event) { final int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_UP: if (!isVerticalScrollBarEnabled()) { setVerticalScrollBarEnabled(true); } if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) { if ((mRefreshView.getBottom() > mRefreshViewHeight || mRefreshView.getTop() >= 0) && mRefreshState == RELEASE_TO_REFRESH) { // Initiate the refresh mRefreshState = REFRESHING; prepareForRefresh(); onRefresh(); } else if (mRefreshView.getBottom() < mRefreshViewHeight || mRefreshView.getTop() < 0) { // Abort refresh and scroll down below the refresh view resetHeader(); setSelection(1); } } break; case MotionEvent.ACTION_DOWN: mLastMotionY = y; break; case MotionEvent.ACTION_MOVE: applyHeaderPadding(event); break; } return super.onTouchEvent(event); } private void applyHeaderPadding(MotionEvent ev) { final int historySize = ev.getHistorySize(); // Workaround for getPointerCount() which is unavailable in 1.5 // (it's always 1 in 1.5) int pointerCount = 1; try { Method method = MotionEvent.class.getMethod("getPointerCount"); pointerCount = (Integer)method.invoke(ev); } catch (NoSuchMethodException e) { pointerCount = 1; } catch (IllegalArgumentException e) { throw e; } catch (IllegalAccessException e) { System.err.println("unexpected " + e); } catch (InvocationTargetException e) { System.err.println("unexpected " + e); } for (int h = 0; h < historySize; h++) { for (int p = 0; p < pointerCount; p++) { if (mRefreshState == RELEASE_TO_REFRESH) { if (isVerticalFadingEdgeEnabled()) { setVerticalScrollBarEnabled(false); } int historicalY = 0; try { // For Android > 2.0 Method method = MotionEvent.class.getMethod( "getHistoricalY", Integer.TYPE, Integer.TYPE); historicalY = ((Float) method.invoke(ev, p, h)).intValue(); } catch (NoSuchMethodException e) { // For Android < 2.0 historicalY = (int) (ev.getHistoricalY(h)); } catch (IllegalArgumentException e) { throw e; } catch (IllegalAccessException e) { System.err.println("unexpected " + e); } catch (InvocationTargetException e) { System.err.println("unexpected " + e); } // Calculate the padding to apply, we divide by 1.7 to // simulate a more resistant effect during pull. int topPadding = (int) (((historicalY - mLastMotionY) - mRefreshViewHeight) / 1.7); mRefreshView.setPadding( mRefreshView.getPaddingLeft(), topPadding, mRefreshView.getPaddingRight(), mRefreshView.getPaddingBottom()); } } } } /** * Sets the header padding back to original size. */ private void resetHeaderPadding() { mRefreshView.setPadding( mRefreshView.getPaddingLeft(), mRefreshOriginalTopPadding, mRefreshView.getPaddingRight(), mRefreshView.getPaddingBottom()); } /** * Resets the header to the original state. */ private void resetHeader() { if (mRefreshState != TAP_TO_REFRESH) { mRefreshState = TAP_TO_REFRESH; resetHeaderPadding(); // Set refresh view text to the pull label mRefreshViewText.setText(R.string.pull_to_refresh_tap_label); // Replace refresh drawable with arrow drawable mRefreshViewImage.setImageResource(R.drawable.ic_pulltorefresh_arrow); // Clear the full rotation animation mRefreshViewImage.clearAnimation(); // Hide progress bar and arrow. mRefreshViewImage.setVisibility(View.GONE); mRefreshViewProgress.setVisibility(View.GONE); } } 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 void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // When the refresh view is completely visible, change the text to say // "Release to refresh..." and flip the arrow drawable. if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL && mRefreshState != REFRESHING) { if (firstVisibleItem == 0) { mRefreshViewImage.setVisibility(View.VISIBLE); if ((mRefreshView.getBottom() > mRefreshViewHeight + 20 || mRefreshView.getTop() >= 0) && mRefreshState != RELEASE_TO_REFRESH) { mRefreshViewText.setText(R.string.pull_to_refresh_release_label); mRefreshViewImage.clearAnimation(); mRefreshViewImage.startAnimation(mFlipAnimation); mRefreshState = RELEASE_TO_REFRESH; } else if (mRefreshView.getBottom() < mRefreshViewHeight + 20 && mRefreshState != PULL_TO_REFRESH) { mRefreshViewText.setText(R.string.pull_to_refresh_pull_label); if (mRefreshState != TAP_TO_REFRESH) { mRefreshViewImage.clearAnimation(); mRefreshViewImage.startAnimation(mReverseFlipAnimation); } mRefreshState = PULL_TO_REFRESH; } } else { mRefreshViewImage.setVisibility(View.GONE); resetHeader(); } } else if (mCurrentScrollState == SCROLL_STATE_FLING && firstVisibleItem == 0 && mRefreshState != REFRESHING) { setSelection(1); } if (mOnScrollListener != null) { mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { mCurrentScrollState = scrollState; if (mOnScrollListener != null) { mOnScrollListener.onScrollStateChanged(view, scrollState); } } public void prepareForRefresh() { resetHeaderPadding(); mRefreshViewImage.setVisibility(View.GONE); // We need this hack, otherwise it will keep the previous drawable. mRefreshViewImage.setImageDrawable(null); mRefreshViewProgress.setVisibility(View.VISIBLE); // Set refresh view text to the refreshing label mRefreshViewText.setText(R.string.pull_to_refresh_refreshing_label); mRefreshState = REFRESHING; } public void onRefresh() { Log.d(TAG, "onRefresh"); if (mOnRefreshListener != null) { mOnRefreshListener.onRefresh(); } } /** * Resets the list to a normal state after a refresh. * @param lastUpdated Last updated at. */ public void onRefreshComplete(CharSequence lastUpdated) { setLastUpdated(lastUpdated); onRefreshComplete(); } /** * Resets the list to a normal state after a refresh. */ public void onRefreshComplete() { Log.d(TAG, "onRefreshComplete"); resetHeader(); // If refresh view is visible when loading completes, scroll down to // the next item. if (mRefreshView.getBottom() > 0) { invalidateViews(); setSelection(1); } } /** * Invoked when the refresh view is clicked on. This is mainly used when * there's only a few items in the list and it's not possible to drag the * list. */ private class OnClickRefreshListener implements OnClickListener { @Override public void onClick(View v) { if (mRefreshState != REFRESHING) { prepareForRefresh(); onRefresh(); } } } /** * Interface definition for a callback to be invoked when list should be * refreshed. */ public interface OnRefreshListener { /** * Called when the list should be refreshed. * <p> * A call to {@link PullToRefreshListView #onRefreshComplete()} is * expected to indicate that the refresh has completed. */ public void onRefresh(); } }
- demo_pulltorefresh_listview.rar (69.5 KB)
- 下载次数: 211
发表评论
-
ListView 滚动加载,more加载
2012-08-30 14:55 1116滚动加载: 转载:http://2528.iteye.com ... -
如何控制ScrollView的滚动条,让滚动条停在指定位置
2012-08-30 14:04 2206myScrollView.post(new Runnable( ... -
Android中ListView和ScrollView总结
2012-08-29 18:31 811快速滚动的解决问题: http://www.2cto. ... -
Android ListView滚动提示等待框
2012-08-28 21:49 917转载: http://www.cnblogs.com/ ... -
锁屏界面
2012-07-02 19:00 701http://blog.csdn.net/qinjuning/ ... -
activity切换动画效果
2012-05-30 16:59 1019转载: http://my.oschina.net/chen ... -
索引DEMO
2012-05-15 22:47 828listview的索引 -
android listview ScrollView冲突 listview checkbox
2012-05-15 22:42 13171、解决问题: 加了checkbox之后,就会影响 ... -
popup
2012-05-15 14:11 911public class PopupWindowActivit ... -
ListView 隔行重复选中的问题
2012-05-09 15:07 1416转载; http://blog.sina.com.cn ... -
解决scrollview不滑动的问题
2012-04-11 13:57 3344scrollview 使用setOnTouchListener ...
相关推荐
本篇文章将详细介绍如何在Android中实现ListView的反弹效果。 首先,我们需要明白,这个反弹效果主要涉及到两个部分:滚动边界检测和动画处理。在Android中,我们可以利用AbsListView的OnScrollListener来监听...
通过这个“仿iPhone的listview下拉更新”的源码学习,开发者不仅可以掌握如何在Android中实现下拉刷新,还能了解到自定义视图、动画效果、数据加载和UI交互等方面的知识,这对于提升Android应用的用户体验具有重要...
在Android开发中,为了使应用界面更接近iOS的风格或者增加独特的用户体验,有时我们需要实现类似iPhone的圆角ListView以及点击效果。本篇文章将详细讲解如何在Android中复现这一功能。 首先,我们要创建一个带有...
"Android ListView反弹效果源码" 是一个针对ListView进行优化的资源包,它提供了实现ListView滚动反弹效果的代码。这个源码可能包括自定义滚动监听器、动画处理和视图处理等关键组件,旨在让ListView在滚动至顶部或...
本篇将详细解析实现Android ListView反弹效果的源码。 首先,反弹效果主要依赖于两个关键组件:OnScrollListener和 OverscrollByCompat 方法。OnScrollListener 是ListView的监听器,用来捕获用户的滚动事件;...
在Android开发中,为了提供与iOS类似的用户体验,开发者经常需要实现ListView的下拉刷新功能,这在标题"android仿iphone的listview下拉更新.zip"中提到。这个压缩包文件很可能是包含了一个示例项目或者代码片段,...
总的来说,实现ListView的反弹效果涉及到对Android UI框架的深入理解,特别是滚动行为和动画系统。通过学习和分析这个源码,开发者可以更好地掌握如何在自己的应用中创建类似的交互效果,提升用户体验。
这个"Android项目仿iphone的listview下拉更新.rar"压缩包文件很可能包含了一个示例项目,演示了如何在Android中实现类似iPhone的下拉刷新效果。下面将详细介绍这个知识点及其相关技术。 1. 下拉刷新概念: 下拉...
在Android应用开发中,我们经常会遇到需要实现类似iPhone的ListView下拉刷新功能,这不仅可以提升用户体验,也能增强应用的互动性。本资源提供了一个Android应用源码,专门用于仿制iPhone风格的ListView下拉更新效果...
本文将围绕“Android仿微信的ListView”这一主题,详细讲解如何实现类似微信聊天界面和好友列表界面的ListView组件。 首先,我们要理解ListView在Android中的角色。ListView是一种可滚动的视图容器,它可以显示一列...
4. **事件处理**:Android UI中的点击、滑动等交互事件,是通过OnClickListener、OnTouchListener等接口来实现的。开发者可以绑定监听器以响应用户操作。 5. **主题和样式**:Android支持全局的主题和局部的样式,...
标题中的“android listview仿iphone特效”指的是在Android开发中,使用ListView组件实现类似iOS界面效果的一种技术。这种效果通常包括但不限于平滑滚动、动态高度调整、渐变背景等,目的是提升Android应用的用户...
本知识点将详细讲解如何在Android中实现一个仿iPhone风格的ListView下拉更新效果。 首先,我们需要了解下拉刷新的基本工作原理。当用户在ListView顶部向下拉动时,视图会显示一个可滚动的指示器,通常是一个旋转的...
"基于Android的仿iPhone的listview下拉更新"项目旨在教授开发者如何在Android应用中实现类似于iPhone的下拉刷新功能,这种功能在当今的移动应用中非常常见,能够带给用户更加流畅的互动体验。 首先,我们要理解下拉...
本文实例讲述了Android编程实现ListView中item部分区域添加点击事件功能。分享给大家供大家参考,具体如下: 需求如题目:Android listview中item部分区域添加点击事件,在一个界面显示了listview,但显示的内容分为...
本篇将深入探讨如何在Android中实现ListView的3D弹性滚动,即Fling效果。 首先,要理解3D效果的本质,它通常是通过改变ListView项的透明度、大小或位置来模拟深度感。在Android中,我们可以通过自定义Adapter和...
本篇文章将深入探讨如何在Android中实现ListView的反弹效果。 首先,我们要理解Android系统本身并未提供直接的API来实现这种反弹效果。因此,我们需要借助第三方库或者自定义View来实现。这里提到的"ListViewScroll...
在Android开发中,ListView是一种非常常见的控件,用于展示大量数据的列表形式。它具有高度可定制性,能够实现各种自定义布局和交互效果。本教程将深入讲解如何实现一个基本的ListView,并在用户点击列表项时跳转到...