Android ExpandableListView的下拉刷新实现
该控件的修改时根据PullToRefreshList的机制修改
下面是对ExpandableListView的扩展
package com.up91.gwy.view.componet; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import com.up91.gwy.R; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.LinearInterpolator; import android.view.animation.RotateAnimation; import android.widget.AbsListView; import android.widget.ExpandableListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ImageView; import android.widget.ListAdapter; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; public class PullToRefreshExpandableListView extends ExpandableListView implements OnScrollListener { private static final String TAG = "PullToRefreshExpandableListView"; private static final int TAP_TO_REFRESH = ; private static final int PULL_TO_REFRESH = ; private static final int RELEASE_TO_REFRESH = ; private static final int REFRESHING = ; private OnRefreshListener mOnRefreshListener; private OnScrollListener mOnScrollListener; private LayoutInflater mInflater; private RelativeLayout 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; private boolean isInInitState; public PullToRefreshExpandableListView(Context context) { super(context); init(context); } public PullToRefreshExpandableListView(Context context, AttributeSet attrs) { super(context,attrs); init(context); } public PullToRefreshExpandableListView(Context context,AttributeSet attrs, int defStyle) { super(context,attrs,defStyle); init(context); } private void init(Context context){ mFlipAnimation = new RotateAnimation(,-, RotateAnimation.RELATIVE_TO_SELF,0.5f, RotateAnimation.RELATIVE_TO_SELF,0.5f); mFlipAnimation.setInterpolator(new LinearInterpolator()); mFlipAnimation.setDuration(); mFlipAnimation.setFillAfter(true); mReverseFlipAnimation = new RotateAnimation(-,, RotateAnimation.RELATIVE_TO_SELF,0.5f, RotateAnimation.RELATIVE_TO_SELF,0.5f); mReverseFlipAnimation.setInterpolator(new LinearInterpolator()); mReverseFlipAnimation.setDuration(); mReverseFlipAnimation.setFillAfter(true); mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mRefreshView = (RelativeLayout) mInflater.inflate(R.layout.pull_to_refresh_header, this,false); 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(); mRefreshView.setOnClickListener(new OnClickRefreshListener()); mRefreshOriginalTopPadding = mRefreshView.getPaddingTop(); mRefreshState = TAP_TO_REFRESH; addHeaderView(mRefreshView); super.setOnScrollListener(this); measureView(mRefreshView); mRefreshViewHeight = mRefreshView.getMeasuredHeight(); } 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(, +, p.width); int lpHeight = p.height; int childHeightSpec; if(lpHeight > ){ childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); }else{ childHeightSpec = MeasureSpec.makeMeasureSpec(, MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec,childHeightSpec); } private class OnClickRefreshListener implements OnClickListener{ @Override public void onClick(View v) { if(mRefreshState != REFRESHING){ prepareForRefresh(); onRefresh(); } } } public interface OnRefreshListener{ public void onRefresh(); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); setSelection(); } @Override public void setAdapter(ListAdapter adapter) { super.setAdapter(adapter); setSelection(); } @Override public void setOnScrollListener(OnScrollListener l) { mOnScrollListener = l; } public void setOnRefreshListener(OnRefreshListener onRefreshListener){ mOnRefreshListener = onRefreshListener; } public void setLastUpdated(CharSequence lastUpdated){ if(lastUpdated != null){ mRefreshViewLastUpdated.setVisibility(View.VISIBLE); mRefreshViewLastUpdated.setText(lastUpdated); }else{ mRefreshViewLastUpdated.setVisibility(View.GONE); } } public boolean onTouchEvent(MotionEvent event) { final int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_UP: if (!isVerticalScrollBarEnabled()) { setVerticalScrollBarEnabled(true); } if (getFirstVisiblePosition() == && mRefreshState != REFRESHING) { if ((mRefreshView.getBottom() > mRefreshViewHeight || mRefreshView.getTop() >= ) && mRefreshState == RELEASE_TO_REFRESH) { // Initiate the refresh mRefreshState = REFRESHING; prepareForRefresh(); onRefresh(); } else if (mRefreshView.getBottom() < mRefreshViewHeight || mRefreshView.getTop() < ) { // Abort refresh and scroll down below the refresh view resetHeader(); setSelection(); } } 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 = ; try { Method method = MotionEvent.class.getMethod("getPointerCount"); pointerCount = (Integer)method.invoke(ev); } catch (NoSuchMethodException e) { pointerCount = ; } catch (IllegalArgumentException e) { throw e; } catch (IllegalAccessException e) { System.err.println("unexpected " + e); } catch (InvocationTargetException e) { System.err.println("unexpected " + e); } for (int h = ; h < historySize; h++) { for (int p = ; p < pointerCount; p++) { if (mRefreshState == RELEASE_TO_REFRESH) { if (isVerticalFadingEdgeEnabled()) { setVerticalScrollBarEnabled(false); } int historicalY = ; 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()); } } } } private void resetHeaderPadding() { mRefreshView.setPadding( mRefreshView.getPaddingLeft(), mRefreshOriginalTopPadding, mRefreshView.getPaddingRight(), mRefreshView.getPaddingBottom()); } 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); } } 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 == ) { mRefreshViewImage.setVisibility(View.VISIBLE); if((mRefreshView.getBottom() > mRefreshViewHeight + || mRefreshView.getTop() >= ) && mRefreshState == PULL_TO_REFRESH){ mRefreshViewText.setText(R.string.pull_to_refresh_release_label); mRefreshViewImage.clearAnimation(); mRefreshViewImage.startAnimation(mFlipAnimation); mRefreshState = RELEASE_TO_REFRESH; }else if(mRefreshState == RELEASE_TO_REFRESH &&mRefreshView.getBottom() < mRefreshViewHeight + ){ mRefreshViewImage.setVisibility(View.GONE); resetHeader(); }else if(mRefreshView.getBottom() == mRefreshViewHeight && mRefreshState == TAP_TO_REFRESH){ //不作为 mRefreshViewImage.setVisibility(View.GONE); resetHeader(); } else if(mRefreshView.getBottom() < mRefreshViewHeight + && mRefreshState == TAP_TO_REFRESH){ mRefreshViewText.setText(R.string.pull_to_refresh_pull_label); mRefreshState = PULL_TO_REFRESH; mRefreshViewImage.clearAnimation(); mRefreshViewImage.startAnimation(mReverseFlipAnimation); } } else { mRefreshViewImage.setVisibility(View.GONE); resetHeader(); } } else if (mCurrentScrollState == SCROLL_STATE_FLING && firstVisibleItem == && mRefreshState != REFRESHING) { setSelection(); } if (mOnScrollListener != null) { mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } 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() { if (mOnRefreshListener != null) { mOnRefreshListener.onRefresh(); resetHeader(); } } public void onRefreshComplete(CharSequence lastUpdated) { setLastUpdated(lastUpdated); onRefreshComplete(); } public void onRefreshComplete() { resetHeader(); // If refresh view is visible when loading completes, scroll down to // the next item. if (mRefreshView.getBottom() > ) { invalidateViews(); setSelection(); } } }
使用时:
expLV.setOnRefreshListener(new OnRefreshListener(){ @Override public void onRefresh() { //远程取数据机制 });
Android ExpandableListView的下拉刷新实现的更多相关文章
- Android之自定义控件-下拉刷新
实现效果: 图片素材: --> 首先, 写先下拉刷新时的刷新布局 pull_to_refresh.xml: <resources> <string name=& ...
- Android SwipeRefreshLayout 官方下拉刷新控件介绍
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24521483 下面App基本都有下拉刷新的功能,以前基本都使用XListView ...
- android控件 下拉刷新pulltorefresh
外国人写的下拉刷新控件,我把他下载下来放在网盘,有时候訪问不了github 支持各种控件下拉刷新 ListView.ViewPager.WevView.ExpandableListView.GridV ...
- Android内置下拉刷新组件SwipeRefreshLayout
也许下拉刷新之前,你可能会使用一些第三方的开源库,例如PullToRefresh, ActionBar-PullToRefresh等待,但现在有的正式组成部分---SwipeRefreshLayout ...
- 【转载】Android中ListView下拉刷新的实现
在网上看到一个下拉刷新的例子,很的很棒,转载和更多的人分享学习 原文:http://blog.csdn.net/loongggdroid/article/details/9385535 ListVie ...
- Android中ListView下拉刷新的实现
ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: packa ...
- Android之XListView下拉刷新,更新网络美女图
一.简介: 下拉刷新是一种特定的手动刷新交互,和其他的同类操作不同的地方在于它采用了更加直觉的下拉操作,所以它的交互足够清晰明显. 下拉刷新主要用在类似ListView这样的控件,设计下拉刷新有三 ...
- Android之SwipeRefreshLayout下拉刷新组件
SwipeRefreshLayout概述 SwipeRefrshLayout是Google官方更新的一个Widget,可以实现下拉刷新的效果.该控件集成自ViewGroup在support-v4兼容包 ...
- Android中实现下拉刷新
需求:项目中的消息列表界面要求实现类似sina微博的下拉刷新: 思路:一般的消息列表为ListView类型,将list加载到adapter中,再将adapter加载到 ListView中,从而实现消息 ...
随机推荐
- 懒加载 字典转模型 自定义cell
1 懒加载: 1> 什么是懒加载? 懒加载又称为延时加载,即在系统调用的时候加载,如果系统不调用则不会加载.所谓的懒加载其实就是重写其 get 方法. 2> 特点:在使用懒加载的时候要 ...
- java 中文转换成Unicode编码和Unicode编码转换成中文
转自:一叶飘舟 http://blog.csdn.net/jdsjlzx/article/details/ package lia.meetlucene; import java.io.IOExcep ...
- 新浪微博API开放平台进行程序开发第一步(java)
申请开发者权限步骤: 1.登录sina微博,点击“应用” 2.点击“微博开发平台 我也要做开发者” 3.点击“我的应用”,填写“开发者信息” 4.点击“创建应用”,就是你将要开发的微博应用程序,可以是 ...
- 分布式架构高可用架构篇_06_MySQL源码编译安装(CentOS-6.7+MySQL-5.6)
redhat: 下载:http://dev.mysql.com/downloads/mysql/ 选择5.6 source包 解压 cmake . -DCMAKE_INSTALL_PREFIX=/us ...
- sql like模糊查询
1.SQL LIKE 子句中使用百分号(%)字符来表示任意字符,类似于UNIX或正则表达式中的星号 (*). 2.LIKE 通常与 % 一同使用,类似于一个元字符的搜索. 3. > SELECT ...
- python twisted启动定时服务
以下是python脚本send_mms.py #############################################!/usr/bin/python# -*- coding: ut ...
- 我的Ubuntu系统配置所作的备份记录如下
Ubuntu无法关机解决办法 说明:如果不成功请参考一下文章最后的内容,也许会有帮助. 其实不止在ubuntu里面,fedora里面我也遇到了这个问题,就是电脑可以重启,但是不能直接关机,否则就一直停 ...
- PHP防止用户重复提交表单
我们提交表单的时候,不能忽视的一个限制是防止用户重复提交表单,因为有可能用户连续点击了提交按钮或者是攻击者恶意提交数据,那么我们在提交数据后的处理如修改或添加数据到数据库时就会惹上麻烦. 那么如何规避 ...
- Jquery--string
--判断string是否为空 state !== undefined || state !== null || state != ""
- CREATE INDEX SELECT COUNT(*)
CREATE INDEX windex_countrycode ON sales_rank (countrycode); CREATE INDEX windex_grab_amz_date ON sa ...