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() { 

                    //远程取数据机制 

            });   

  • 相关阅读:
    [转]自定义ASP.NET AJAX拖放功能示例程序:实现IDragSource和IDropTarget接口将商品拖放至购物车中
    MySQL远程连接不上的解决方法
    Office 2007无法修复、卸载、重装
    使用Outlook Connector收发HOTMAIL邮件
    U盘数据恢复
    ISA假死现象
    SharePoint Server 2007序列号
    IBM x3650安装笔记机柜支架及RAID
    在产品的价值中售后服务也不能忽略
    彩信增强MMS.IT 增强S60手机彩信功能
  • 原文地址:https://www.cnblogs.com/exmyth/p/4456028.html
Copyright © 2011-2022 走看看