zoukankan      html  css  js  c++  java
  • 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 = 1; 
    
        private static final int PULL_TO_REFRESH = 2; 
    
        private static final int RELEASE_TO_REFRESH = 3; 
    
        private static final int REFRESHING = 4; 
    
         
    
        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(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 = (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(50); 
    
             
    
            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(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); 
    
        } 
    
         
    
        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(1); 
    
        } 
    
     
    
        @Override 
    
        public void setAdapter(ListAdapter adapter) {  
    
            super.setAdapter(adapter); 
    
            setSelection(1); 
    
        } 
    
     
    
        @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() == 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()); 
    
                    } 
    
                } 
    
            } 
    
        } 
    
        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 == 0) { 
    
                    mRefreshViewImage.setVisibility(View.VISIBLE); 
    
                    if((mRefreshView.getBottom() > mRefreshViewHeight + 20 
    
                            || mRefreshView.getTop() >= 0) 
    
                            && 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 + 20){ 
    
                        mRefreshViewImage.setVisibility(View.GONE); 
    
                        resetHeader(); 
    
                    }else if(mRefreshView.getBottom() == mRefreshViewHeight  
    
                            && mRefreshState == TAP_TO_REFRESH){ 
    
                        //不作为 
    
                        mRefreshViewImage.setVisibility(View.GONE); 
    
                        resetHeader(); 
    
                    } else if(mRefreshView.getBottom() < mRefreshViewHeight + 20 
    
                            && 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 == 0 
    
                    && mRefreshState != REFRESHING) { 
    
                setSelection(1); 
    
            } 
    
     
    
            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() > 0) { 
    
                invalidateViews(); 
    
                setSelection(1); 
    
            } 
    
        } 
    
    } 

    使用时:

    expLV.setOnRefreshListener(new OnRefreshListener(){ 
    
                @Override 
    
                public void onRefresh() { 
    
                    //远程取数据机制 
    
            });   
  • 相关阅读:
    Nodejs下载和第一个Nodejs示例
    永久关闭Win10工具栏的TaskbarSearch控件
    对称加密,非对称加密,散列算法,签名算法
    【转】TTL和RS232之间的详细对比
    zlg核心板linux系统中查看系统内存等使用信息
    Power BI后台自动刷新数据报错 The operation was throttled by Power BI Premium because there were too many datasets being processed concurrently.
    剪切板和上传文件内容获取
    CSS, LESS, SCSS, SASS总结
    文字程序
    electron 打包“ERR_ELECTRON_BUILDER_CANNOT_EXECUTE”
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/6101785.html
Copyright © 2011-2022 走看看