该控件的修改时根据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的下拉刷新实现的更多相关文章

  1. Android之自定义控件-下拉刷新

    实现效果: 图片素材:         --> 首先, 写先下拉刷新时的刷新布局 pull_to_refresh.xml: <resources> <string name=& ...

  2. Android SwipeRefreshLayout 官方下拉刷新控件介绍

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24521483 下面App基本都有下拉刷新的功能,以前基本都使用XListView ...

  3. android控件 下拉刷新pulltorefresh

    外国人写的下拉刷新控件,我把他下载下来放在网盘,有时候訪问不了github 支持各种控件下拉刷新 ListView.ViewPager.WevView.ExpandableListView.GridV ...

  4. Android内置下拉刷新组件SwipeRefreshLayout

    也许下拉刷新之前,你可能会使用一些第三方的开源库,例如PullToRefresh, ActionBar-PullToRefresh等待,但现在有的正式组成部分---SwipeRefreshLayout ...

  5. 【转载】Android中ListView下拉刷新的实现

    在网上看到一个下拉刷新的例子,很的很棒,转载和更多的人分享学习 原文:http://blog.csdn.net/loongggdroid/article/details/9385535 ListVie ...

  6. Android中ListView下拉刷新的实现

    ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: packa ...

  7. Android之XListView下拉刷新,更新网络美女图

    一.简介:   下拉刷新是一种特定的手动刷新交互,和其他的同类操作不同的地方在于它采用了更加直觉的下拉操作,所以它的交互足够清晰明显. 下拉刷新主要用在类似ListView这样的控件,设计下拉刷新有三 ...

  8. Android之SwipeRefreshLayout下拉刷新组件

    SwipeRefreshLayout概述 SwipeRefrshLayout是Google官方更新的一个Widget,可以实现下拉刷新的效果.该控件集成自ViewGroup在support-v4兼容包 ...

  9. Android中实现下拉刷新

    需求:项目中的消息列表界面要求实现类似sina微博的下拉刷新: 思路:一般的消息列表为ListView类型,将list加载到adapter中,再将adapter加载到 ListView中,从而实现消息 ...

随机推荐

  1. [转].net中的认证(authentication)与授权(authorization)

    本文转自:http://www.cnblogs.com/yjmyzz/archive/2010/08/29/1812038.html 注:这篇文章主要给新手看的,老手们可能会觉得没啥营养,就请绕过吧. ...

  2. Repair duplicate IDs on cloned Endpoint Protection 12.1 clients

    https://support.symantec.com/en_US/article.TECH163349.html

  3. 《GK101任意波发生器》升级固件发布(版本:1.0.2.build124)

    一.固件说明: 硬件版本:0,logic.3 固件版本:1.0.2.build124 编译日期:2014-08-19 ====================================== 二. ...

  4. MySQL表的创建和表中数据操作

    这篇文章主要介绍在navicat的命令界面操作mysql.主要涉及建立表结构,和对表中数据的增加删除修改查询等动作.站在一个新手角度的简单mysql表结构和数据操作. ☆ 准备工作 1,保证自己的电脑 ...

  5. JSP简单访问数据库

    Java代码 public class DBHelper { private String driverName; private String url; private String user; p ...

  6. [Zz] DX depth buffer

    声明:本文完全翻译自DX SDK Documentation depth buffer,通常被称为z-buffer或者w-buffer,是设备的一个属性,用来存储深度信息,被D3D使用.当D3D渲染一 ...

  7. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

  8. 时间函数 date strtotime

    date_default_timezone_set('Asia/Shanghai');echo strtotime('Today');echo strtotime(date('Y-m-d')); 获取 ...

  9. JDBC 增删查改

    public class MemberDaoImpl implements MemberDao { private Connection conn = null; public MemberDaoIm ...

  10. 【转】C#中HttpWebRequest的用法详解

    本文实例讲述了C#中HttpWebRequest的用法.分享给大家供大家参考.具体如下: HttpWebRequest类主要利用HTTP 协议和服务器交互,通常是通过 GET 和 POST 两种方式来 ...