ListView下拉刷新
来源:互联网 发布:天书世界太极进阶数据 编辑:程序博客网 时间:2024/06/05 17:18
ListView下拉刷新是在开发过程中经常用到的一个功能,整理如下,如果初学者有需要可以作为参考。下拉刷新头部布局如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/drop_drown_list_header_padding_bottom"android:paddingTop="@dimen/drop_drown_list_header_padding_top"><!--进度条 --><ProgressBar android:id="@+id/drop_drown_list_header_progress_bar" android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/drop_drown_list_header_progress_bar_style" android:indeterminate="true" android:layout_toLeftOf="@+id/drop_drown_list_header_default_text_layout" android:visibility="gone"/><!--翻转图片 --><ImageView android:id="@+id/drop_drown_list_header_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/image_content" android:src="@drawable/drop_down_list_arrow" android:layout_toLeftOf="@+id/drop_drown_list_header_default_text_layout" android:visibility="gone"/><!--文字提示 --><RelativeLayout android:id="@+id/drop_drown_list_header_default_text_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginLeft="10dp" android:gravity="center"> <TextView android:id="@+id/drop_drown_list_header_default_text" style="@style/drop_drown_list_header_font_style" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:gravity="center"/> <TextView android:id="@+id/drop_down_list_header_second_text" style="@style/drop_drown_list_header_font_style" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/drop_drown_list_header_default_text" android:gravity="center" android:visibility="gone"/></RelativeLayout>
在布局中添加了一个ImageView用于显示下拉的箭头,一个ProgressBar正在加载时候的等待状态,两个TextView用于状态提示和显示时间接下来是在listView中添加header布局,并在onTouchEvent和滚动事件中改变header中个组件的状态和样式:public class DropDrownListView extends ListView implements OnScrollListener {private boolean isDropDrownStyle = true;private boolean hasReachedTop = false;//头部不同状态的提示文字private String headerDefaultText;private String headerPullText;private String headerReleaseText;private String headerLoadingText;private Context context;private int currentScrollState;//listView的滚动状态private int currentHeaderStatus;//头部布局的状态有四种private RelativeLayout headerLayout;private ImageView headerImage;private ProgressBar headerProgressBar;private TextView headerText;private TextView headerSecondText;//动画private RotateAnimation flipAnimation;private RotateAnimation reverseFlipAnimation;private OnScrollListener onScrollListener;private int headerReleaseMinDistance;private int headerOriginalHeight;private int headerOriginalTopPadding;private float actionDownPointY;private float headerPaaddingTopRate = 1.5f;//头部布局的四种状态public static final int HEADER_STATUS_CLICK_TO_LOAD = 1;public static final int HEADER_STATUS_DROP_DROWN_TO_LAOD = 2;public static final int HEADER_STATUS_RELEASE_TO_LOAD = 3;public static final int HEADER_STATUS_LOADING = 4;public DropDrownListView(Context context) { super(context); init(context);}public DropDrownListView(Context context, AttributeSet attrs) { super(context, attrs); getAttrs(context, attrs); init(context);}public DropDrownListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); getAttrs(context, attrs); init(context);}/** * 初始化布局 * * @param context */private void init(Context context) { this.context = context; initDropDownStyle(); super.setOnScrollListener(this);}private void initDropDownStyle() { if (headerLayout != null) { if (isDropDrownStyle) { addHeaderView(headerLayout); } else { removeHeaderView(headerLayout); } return; } if (!isDropDrownStyle) { return; } headerReleaseMinDistance = getResources().getDimensionPixelSize( R.dimen.drop_drown_list_header_release_min_distance); flipAnimation = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); flipAnimation.setInterpolator(new LinearInterpolator()); flipAnimation.setDuration(250); flipAnimation.setFillAfter(true); reverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); reverseFlipAnimation.setInterpolator(new LinearInterpolator()); reverseFlipAnimation.setDuration(250); reverseFlipAnimation.setFillAfter(true); headerDefaultText = context .getString(R.string.drop_drown_list_header_default_text); headerPullText = context .getString(R.string.drop_drown_list_header_pull_text); headerReleaseText = context .getString(R.string.drop_drown_list_header_release_text); headerLoadingText = context .getString(R.string.drop_drown_list_header_loading_text); LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); headerLayout = (RelativeLayout) inflater.inflate( R.layout.drop_drown_list_header, null); headerText = (TextView) headerLayout .findViewById(R.id.drop_drown_list_header_default_text); headerImage = (ImageView) headerLayout .findViewById(R.id.drop_drown_list_header_image); headerProgressBar = (ProgressBar) headerLayout .findViewById(R.id.drop_drown_list_header_progress_bar); headerSecondText = (TextView) headerLayout .findViewById(R.id.drop_down_list_header_second_text); headerLayout.setClickable(true); headerLayout.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onDropDown(); } }); headerText.setText(headerDefaultText); addHeaderView(headerLayout); measureHeaderLayout(headerLayout); headerOriginalHeight = headerLayout.getMeasuredHeight(); headerOriginalTopPadding = headerLayout.getPaddingTop(); currentHeaderStatus = HEADER_STATUS_CLICK_TO_LOAD;}@Overridepublic boolean onTouchEvent(MotionEvent ev) { hasReachedTop = false; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: actionDownPointY = ev.getY(); break; case MotionEvent.ACTION_MOVE: adjustHeaderPadding(ev); break; case MotionEvent.ACTION_UP: if (!isVerticalFadingEdgeEnabled()) { setVerticalScrollBarEnabled(false); } if (getFirstVisiblePosition() == 0 && currentHeaderStatus != HEADER_STATUS_LOADING) { switch (currentHeaderStatus) { case HEADER_STATUS_RELEASE_TO_LOAD: onDropDown(); break; case HEADER_STATUS_DROP_DROWN_TO_LAOD: setHeaderStatusClickToLoad(); setSecondPositionVisible(); break; } } break; } return super.onTouchEvent(ev);}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) { currentScrollState = scrollState; if (currentScrollState == SCROLL_STATE_IDLE) { hasReachedTop = false; } if (onScrollListener != null) { onScrollListener.onScrollStateChanged(view, scrollState); }}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (currentScrollState == SCROLL_STATE_TOUCH_SCROLL && currentHeaderStatus != HEADER_STATUS_LOADING) { if (firstVisibleItem == 0) { headerImage.setVisibility(View.VISIBLE); int pointButtom = headerOriginalHeight + headerReleaseMinDistance; if (headerLayout.getBottom() >= pointButtom) { setHeaderStatusReleaseToLoad(); } else if (headerLayout.getBottom() < pointButtom) { setHeaderStatusDropDownToLoad(); } } else { setHeaderStatusClickToLoad(); } } else if (currentHeaderStatus == SCROLL_STATE_FLING && firstVisibleItem == 0 && currentHeaderStatus != HEADER_STATUS_LOADING) { setSecondPositionVisible(); hasReachedTop = true; } else if (currentScrollState == SCROLL_STATE_FLING && hasReachedTop) { setSecondPositionVisible(); } if (onScrollListener != null) { onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); }}public void setSecondPositionVisible() { if (getAdapter() != null && getAdapter().getCount() > 0 && getFirstVisiblePosition() == 0) { setSelection(1); }}private void adjustHeaderPadding(MotionEvent ev) { int pointCount = ev.getHistorySize(); if (isVerticalFadingEdgeEnabled()) { setVerticalScrollBarEnabled(false); } for (int i = 0; i < pointCount; i++) { if (currentHeaderStatus == HEADER_STATUS_DROP_DROWN_TO_LAOD || currentHeaderStatus == HEADER_STATUS_RELEASE_TO_LOAD) { headerLayout .setPadding( headerLayout.getPaddingLeft(), (int) (((ev.getHistoricalY(i) - actionDownPointY) - headerOriginalHeight) / headerPaaddingTopRate), headerLayout.getPaddingRight(), headerLayout.getPaddingBottom()); } }}private void onDropDown() { if (currentHeaderStatus != HEADER_STATUS_LOADING && onDropDownListener != null) { onDropDownBegin(); onDropDownListener.onDropDown(); }}private void onDropDownBegin() { setHeaderStatusLoading();}/** * headerLayout的初始状态 */private void setHeaderStatusClickToLoad() { if (currentHeaderStatus != HEADER_STATUS_CLICK_TO_LOAD) { resetHeaderPadding(); headerImage.clearAnimation(); headerImage.setVisibility(View.GONE); headerProgressBar.setVisibility(View.GONE); headerText.setText(headerDefaultText); currentHeaderStatus = HEADER_STATUS_CLICK_TO_LOAD; }}/** * headerLayout的下拉状态 */private void setHeaderStatusDropDownToLoad() { if (currentHeaderStatus != HEADER_STATUS_DROP_DROWN_TO_LAOD) { headerImage.setVisibility(View.VISIBLE); if (currentHeaderStatus != HEADER_STATUS_CLICK_TO_LOAD) { headerImage.clearAnimation(); headerImage.startAnimation(reverseFlipAnimation); } headerProgressBar.setVisibility(View.GONE); headerText.setText(headerPullText); if (isVerticalFadingEdgeEnabled()) { setVerticalScrollBarEnabled(false); } currentHeaderStatus = HEADER_STATUS_DROP_DROWN_TO_LAOD; }}private void setHeaderStatusReleaseToLoad() { if (currentHeaderStatus != HEADER_STATUS_RELEASE_TO_LOAD) { headerImage.setVisibility(View.GONE); headerImage.clearAnimation(); headerImage.startAnimation(flipAnimation); headerProgressBar.setVisibility(View.GONE); headerText.setText(headerReleaseText); currentHeaderStatus = HEADER_STATUS_RELEASE_TO_LOAD; }}private void setHeaderStatusLoading() { if (currentHeaderStatus != HEADER_STATUS_LOADING) { resetHeaderPadding(); headerImage.setVisibility(View.GONE); headerImage.clearAnimation(); headerProgressBar.setVisibility(View.VISIBLE); headerText.setText(headerLoadingText); currentScrollState = HEADER_STATUS_LOADING; setSelection(0); }}private void resetHeaderPadding() { headerLayout.setPadding(headerLayout.getPaddingLeft(), headerOriginalTopPadding, headerLayout.getPaddingRight(), headerLayout.getPaddingBottom());}private void measureHeaderLayout(View child) { ViewGroup.LayoutParams p = child.getLayoutParams(); if (p == null) { p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, p.width); int lpHeight = p.height; int childHeightSpace; if (lpHeight > 0) { childHeightSpace = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); } else { childHeightSpace = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpace);}private OnDropDownListener onDropDownListener;public void OnDropDownComplete(CharSequence secondText) { setHeaderSecondText(secondText); onDropDownComplete();}public void setHeaderSecondText(CharSequence secondText) { if (secondText == null) { headerSecondText.setVisibility(View.GONE); } else { headerSecondText.setVisibility(View.VISIBLE); headerSecondText.setText(secondText); }}public void onDropDownComplete() { setHeaderStatusClickToLoad(); if (headerLayout.getBottom() > 0) { invalidateViews(); setSecondPositionVisible(); }}public void setOnDropDownListener(OnDropDownListener listener) { onDropDownListener = listener;}public interface OnDropDownListener { public void onDropDown();}private void getAttrs(Context context, AttributeSet attrs) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.drop_down_list_attr); isDropDrownStyle = ta.getBoolean( R.styleable.drop_down_list_attr_isDropDownStyle, false); ta.recycle();}/** * 使listView的第二个item可见 */@Overridepublic void setAdapter(ListAdapter adapter) { // TODO Auto-generated method stub super.setAdapter(adapter); setSecondPositionVisible();}
}
下拉刷新中有四种状态分别为初始状态, 下拉状态, 释放刷新状态,刷新状态。在onTouchEvent()中通过getAction()方法获取到当前的按下的状态 在ACTION_DOWN状态获取点击时Y轴的坐标,在ACTION_MOVE 调节header布局的在Y轴的padding,在ACTION_UP状态下 若在释放刷新状态, 就会加载刷新,在下拉状态则返回初始状态。
在onScroll中根据滚动状态来判断刷新状态,当滚动的距离大于设定的距离是变为释放刷新状态,小于设定距离时变为下拉状态
源码如下http://download.csdn.net/detail/coder0408/8858767
0 0
- ListView下拉回弹刷新
- ListView下拉刷新
- listView下拉刷新2
- ListView 下拉刷新错误
- Android ListView下拉刷新
- listview下拉刷新
- listview实现下拉刷新
- ListView下拉刷新
- android Listview下拉刷新
- ListView下拉回弹刷新
- Android ListView下拉刷新
- 自定义ListView,下拉刷新
- listview 下拉刷新
- ListView下拉刷新
- ListView下拉刷新
- ListView实现下拉刷新
- ListView下拉回弹刷新
- Listview的下拉刷新
- Java 转发和重定向的区别
- HandlerThared
- Ubuntu上如何安装gensim?
- iframe与主框架跨域相互访问方法
- java中double类型的数据保留两位小数的方法
- ListView下拉刷新
- Spring Security 3.x 完整入门
- HashMap和TreeMap的区别
- Convert Sorted Array to Binary Search Tree
- 一步到位修改linux系统时间
- 图形化界面
- 矩阵理解(一)
- IOS上 关于状态栏的相关设置(UIStatusBar)
- Android studio隐藏标题栏