该控件的修改时根据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. Nodejs - windows的系统变量(环境变量)

    我的电脑-属性-高级-环境变量-系统变量(s)-Path 将Node.exe所在的路径插入Path的变量值(V)中 如 ;E:\nodejs\ 最终效果 C:\Windows\system32;C:\ ...

  2. C# - Lee 公共类库

    我的公共类库 using System; using System.IO; using System.Net; using System.Security.Cryptography; using Sy ...

  3. io资料

    jitsi red5 apache meeting2 openmeeting2 openfire http://www.onlycoder.net/ 在视频会议领域,有许多可以值得参考的开源项目,这些 ...

  4. Sql Server 常用方法、存储过程备用

    常用方法 --字符串转换成数字 --CAST("1" AS int) --CONVERT(int,"1") --截取字符串 SUBSTRING(OccurreA ...

  5. Javascript 笔记与总结(2-10)删除节点,创建节点

    [删除节点] 步骤: ① 找到对象 ② 找到他的父对象 parentObj ③ parentObj.removeChild(子对象); [例] <!DOCTYPE html> <ht ...

  6. selenium 使用笔记

    下面一段代码是使用selenium访问网页一个小实例 #!/usr/bin/python# -*- coding: utf-8 -*- '''Created on Dec 6, 2013 @autho ...

  7. System.Data.OracleClient.OracleConnection已过时

    解决办法如下: 1.把原来的using System.Data.OracleClient;去掉 2.在oracle安装目录下找到Oracle.DataAccess.dll 添加引用:using Ora ...

  8. Bootstrap页面布局12 - BS表单元素的排版

    首先看看这行代码: <label for='account'>帐 号</label> <input id='account' name='account' type='t ...

  9. Python操作MySQL以及中文乱码的问题

    Python操作MySQL需要安装Python-MySQL可以从网上搜索一下,和一般的Python包一样安装 安装好之后,模块名字叫做MySQLdb ,在Window和Linux环境下都可以使用,试验 ...

  10. 【php学习】mysql数据库操作

    //建立数据库连接,数据库地址127.0.0,用户名root,密码root $dbConn = mysql_connect('127.0.0.1', 'root', 'root'); mysql_qu ...