Java 如何使用JazzyListView实现pullToRefreshListView?

Java 如何使用JazzyListView实现pullToRefreshListView?,java,android,listview,animation,jazzylistview,Java,Android,Listview,Animation,Jazzylistview,我给你一些提示链接: 我已经实现了JazzylistView,但我还想用PullToRefreshListView实现JazzylistView。这可能吗?谁知道这个答案,请帮助我?我找到了这个解决方案。只需在库中的PullToRefreshListView.java文件中复制下面的粘贴代码 package com.smartupdater.widget; import java.text.SimpleDateFormat; import java.util.Date; import a

我给你一些提示链接:


  • 我已经实现了
    JazzylistView
    ,但我还想用
    PullToRefresh
    ListView
    实现
    JazzylistView
    。这可能吗?谁知道这个答案,请帮助我?

    我找到了这个解决方案。只需在库中的PullToRefreshListView.java文件中复制下面的粘贴代码

    package com.smartupdater.widget;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.ViewTreeObserver;
    import android.view.ViewTreeObserver.OnGlobalLayoutListener;
    import android.view.animation.Animation;
    import android.view.animation.Animation.AnimationListener;
    import android.view.animation.LinearInterpolator;
    import android.view.animation.OvershootInterpolator;
    import android.view.animation.RotateAnimation;
    import android.view.animation.TranslateAnimation;
    import android.widget.AdapterView;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.ProgressBar;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    import com.notecrate.R;
    import com.smartupdater.utils.Constants;
    
    
    public class PullToRefreshListView extends ListView {
    
        private final JazzyHelper mHelper;
        private static final float PULL_RESISTANCE = 1.7f;
        private static final int BOUNCE_ANIMATION_DURATION = 700;
        private static final int BOUNCE_ANIMATION_DELAY = 100;
        private static final float BOUNCE_OVERSHOOT_TENSION = 1.4f;
        private static final int ROTATE_ARROW_ANIMATION_DURATION = 250;
    
        private static enum State {
            PULL_TO_REFRESH, RELEASE_TO_REFRESH, REFRESHING
        }
    
        /**
         * Interface to implement when you want to get notified of 'pull to refresh'
         * events. Call setOnRefreshListener(..) to activate an OnRefreshListener.
         */
        public interface OnRefreshListener {
    
            /**
             * Method to be called when a refresh is requested
             */
            public void onRefresh();
        }
    
        private static int measuredHeaderHeight;
    
        private boolean scrollbarEnabled;
        private boolean bounceBackHeader;
        private boolean lockScrollWhileRefreshing;
        private boolean showLastUpdatedText;
        private String pullToRefreshText;
        private String releaseToRefreshText;
        private String refreshingText;
        private String lastUpdatedText;
        private SimpleDateFormat lastUpdatedDateFormat = new SimpleDateFormat("dd/MM HH:mm");
    
        private float previousY;
        private int headerPadding;
        private boolean hasResetHeader;
        private long lastUpdated = -1;
        private State state;
        private LinearLayout headerContainer;
        private RelativeLayout header;
        private RotateAnimation flipAnimation;
        private RotateAnimation reverseFlipAnimation;
        private ImageView image;
        private ProgressBar spinner;
        private TextView text;
        private TextView lastUpdatedTextView;
        private OnItemClickListener onItemClickListener;
        private OnItemLongClickListener onItemLongClickListener;
        private OnRefreshListener onRefreshListener;
    
        public PullToRefreshListView(Context context) {
            super(context);
            mHelper = init(context, null);
            init();
        }
    
        public PullToRefreshListView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mHelper = init(context, attrs);
            init();
        }
    
        public PullToRefreshListView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            mHelper = init(context, attrs);
            init();
        }
    
        private JazzyHelper init(Context context, AttributeSet attrs) {
            JazzyHelper helper = new JazzyHelper(context, attrs);
            super.setOnScrollListener(helper);
            return helper;
        }
    
        @Override
        public final void setOnScrollListener(OnScrollListener l) {
            mHelper.setOnScrollListener(l);
        }
    
        public void setTransitionEffect(int transitionEffect) {
            mHelper.setTransitionEffect(transitionEffect);
        }
    
        public void setShouldOnlyAnimateNewItems(boolean onlyAnimateNew) {
            mHelper.setShouldOnlyAnimateNewItems(onlyAnimateNew);
        }
    
        public void setShouldOnlyAnimateFling(boolean onlyFling) {
            mHelper.setShouldOnlyAnimateFling(onlyFling);
        }
    
        public void setSimulateGridWithList(boolean simulateGridWithList) {
            mHelper.setSimulateGridWithList(simulateGridWithList);
            setClipChildren(!simulateGridWithList);
        }
    
        public void setMaxAnimationVelocity(int itemsPerSecond) {
            mHelper.setMaxAnimationVelocity(itemsPerSecond);
        }
    
        @Override
        public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
            this.onItemClickListener = onItemClickListener;
        }
    
        @Override
        public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
            this.onItemLongClickListener = onItemLongClickListener;
        }
    
        /**
         * Activate an OnRefreshListener to get notified on 'pull to refresh'
         * events.
         * 
         * @param onRefreshListener
         *            The OnRefreshListener to get notified
         */
        public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
            this.onRefreshListener = onRefreshListener;
        }
    
        /**
         * @return If the list is in 'Refreshing' state
         */
        public boolean isRefreshing() {
            return state == State.REFRESHING;
        }
    
        /**
         * Default is false. When lockScrollWhileRefreshing is set to true, the list
         * cannot scroll when in 'refreshing' mode. It's 'locked' on refreshing.
         * 
         * @param lockScrollWhileRefreshing
         */
        public void setLockScrollWhileRefreshing(boolean lockScrollWhileRefreshing) {
            this.lockScrollWhileRefreshing = lockScrollWhileRefreshing;
        }
    
        /**
         * Default is false. Show the last-updated date/time in the 'Pull ro
         * Refresh' header. See 'setLastUpdatedDateFormat' to set the date/time
         * formatting.
         * 
         * @param showLastUpdatedText
         */
        public void setShowLastUpdatedText(boolean showLastUpdatedText) {
            this.showLastUpdatedText = showLastUpdatedText;
            if (!showLastUpdatedText)
                lastUpdatedTextView.setVisibility(View.GONE);
        }
    
        /**
         * Default: "dd/MM HH:mm". Set the format in which the last-updated
         * date/time is shown. Meaningless if 'showLastUpdatedText == false
         * (default)'. See 'setShowLastUpdatedText'.
         * 
         * @param lastUpdatedDateFormat
         */
        public void setLastUpdatedDateFormat(SimpleDateFormat lastUpdatedDateFormat) {
            this.lastUpdatedDateFormat = lastUpdatedDateFormat;
        }
    
        /**
         * Explicitly set the state to refreshing. This is useful when you want to
         * show the spinner and 'Refreshing' text when the refresh was not triggered
         * by 'pull to refresh', for example on start.
         */
        public void setRefreshing() {
            state = State.REFRESHING;
            scrollTo(0, 0);
            setUiRefreshing();
            setHeaderPadding(0);
        }
    
        /**
         * Set the state back to 'pull to refresh'. Call this method when refreshing
         * the data is finished.
         */
        public void onRefreshComplete() {
            state = State.PULL_TO_REFRESH;
            resetHeader();
            lastUpdated = System.currentTimeMillis();
        }
    
        /**
         * Change the label text on state 'Pull to Refresh'
         * 
         * @param pullToRefreshText
         *            Text
         */
        public void setTextPullToRefresh(String pullToRefreshText) {
            this.pullToRefreshText = pullToRefreshText;
            if (state == State.PULL_TO_REFRESH) {
                text.setText(pullToRefreshText);
            }
        }
    
        /**
         * Change the label text on state 'Release to Refresh'
         * 
         * @param releaseToRefreshText
         *            Text
         */
        public void setTextReleaseToRefresh(String releaseToRefreshText) {
            this.releaseToRefreshText = releaseToRefreshText;
            if (state == State.RELEASE_TO_REFRESH) {
                text.setText(releaseToRefreshText);
            }
        }
    
        /**
         * Change the label text on state 'Refreshing'
         * 
         * @param refreshingText
         *            Text
         */
        public void setTextRefreshing(String refreshingText) {
            this.refreshingText = refreshingText;
            if (state == State.REFRESHING) {
                text.setText(refreshingText);
            }
        }
    
        private void init() {
            setVerticalFadingEdgeEnabled(false);
    
            headerContainer = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.layout_pulldown_header, null);
            header = (RelativeLayout) headerContainer.findViewById(R.id.ptr_id_header);
            text = (TextView) header.findViewById(R.id.ptr_id_text);
            lastUpdatedTextView = (TextView) header.findViewById(R.id.ptr_id_last_updated);
            image = (ImageView) header.findViewById(R.id.ptr_id_image);
            spinner = (ProgressBar) header.findViewById(R.id.ptr_id_spinner);
    
            pullToRefreshText = getContext().getString(R.string.ptr_pull_to_refresh);
            releaseToRefreshText = getContext().getString(R.string.ptr_release_to_refresh);
            refreshingText = getContext().getString(R.string.ptr_refreshing);
            lastUpdatedText = getContext().getString(R.string.ptr_last_updated);
    
            flipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
            flipAnimation.setInterpolator(new LinearInterpolator());
            flipAnimation.setDuration(ROTATE_ARROW_ANIMATION_DURATION);
            flipAnimation.setFillAfter(true);
    
            reverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
            reverseFlipAnimation.setInterpolator(new LinearInterpolator());
            reverseFlipAnimation.setDuration(ROTATE_ARROW_ANIMATION_DURATION);
            reverseFlipAnimation.setFillAfter(true);
    
            addHeaderView(headerContainer);
            setState(State.PULL_TO_REFRESH);
            scrollbarEnabled = isVerticalScrollBarEnabled();
    
            ViewTreeObserver vto = header.getViewTreeObserver();
            vto.addOnGlobalLayoutListener(new PTROnGlobalLayoutListener());
    
            super.setOnItemClickListener(new PTROnItemClickListener());
            super.setOnItemLongClickListener(new PTROnItemLongClickListener());
        }
    
        private void setHeaderPadding(int padding) {
            headerPadding = padding;
            // Log.d(Constants.TAG, "Header Container=" + headerContainer +
            // " Header=" + header + " Header Padding=" + headerPadding);
            if (header != null) {
                MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) header.getLayoutParams();
                mlp.setMargins(0, Math.round(padding), 0, 0);
                header.setLayoutParams(mlp);
            }
        }                                                                                                     
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (lockScrollWhileRefreshing && (state == State.REFRESHING || getAnimation() != null && !getAnimation().hasEnded())) {
                return true;
            }
    
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (getFirstVisiblePosition() == 0)
                    previousY = event.getY();
                else
                    previousY = -1;
                break;
    
            case MotionEvent.ACTION_UP:
                if (previousY != -1 && (state == State.RELEASE_TO_REFRESH || getFirstVisiblePosition() == 0)) {
                    switch (state) {
                    case RELEASE_TO_REFRESH:
                        setState(State.REFRESHING);
                        bounceBackHeader();
    
                        break;
    
                    case PULL_TO_REFRESH:
                        resetHeader();
                        break;
                    }
                }
                break;
    
            case MotionEvent.ACTION_MOVE:
                if (previousY != -1) {
                    float y = event.getY();
                    float diff = y - previousY;
                    if (diff > 0)
                        diff /= PULL_RESISTANCE;
                    previousY = y;
    
                    int newHeaderPadding = Math.max(Math.round(headerPadding + diff), -header.getHeight());
    
                    if (newHeaderPadding != headerPadding && state != State.REFRESHING) {
                        setHeaderPadding(newHeaderPadding);
    
                        if (state == State.PULL_TO_REFRESH && headerPadding > 0) {
                            setState(State.RELEASE_TO_REFRESH);
    
                            image.clearAnimation();
                            image.startAnimation(flipAnimation);
                        } else if (state == State.RELEASE_TO_REFRESH && headerPadding < 0) {
                            setState(State.PULL_TO_REFRESH);
    
                            image.clearAnimation();
                            image.startAnimation(reverseFlipAnimation);
                        }
    
                        return true;
                    }
                }
    
                break;
            }
    
            return super.onTouchEvent(event);
        }
    
        private void bounceBackHeader() {
            int yTranslate = state == State.REFRESHING ? header.getHeight() - headerContainer.getHeight() : -headerContainer.getHeight()
                    - headerContainer.getTop();
    
            TranslateAnimation bounceAnimation = new TranslateAnimation(TranslateAnimation.ABSOLUTE, 0, TranslateAnimation.ABSOLUTE, 0,
                    TranslateAnimation.ABSOLUTE, 0, TranslateAnimation.ABSOLUTE, yTranslate);
    
            bounceAnimation.setDuration(BOUNCE_ANIMATION_DURATION);
            bounceAnimation.setFillEnabled(true);
            bounceAnimation.setFillAfter(false);
            bounceAnimation.setFillBefore(true);
            bounceAnimation.setInterpolator(new OvershootInterpolator(BOUNCE_OVERSHOOT_TENSION));
            bounceAnimation.setAnimationListener(new HeaderAnimationListener(yTranslate));
    
            startAnimation(bounceAnimation);
        }
    
        private void resetHeader() {
            if (getFirstVisiblePosition() > 0) {
                setHeaderPadding(-header.getHeight());
                setState(State.PULL_TO_REFRESH);
                return;
            }
    
            if (getAnimation() != null && !getAnimation().hasEnded()) {
                bounceBackHeader = true;
            } else {
                bounceBackHeader();
            }
        }
    
        private void setUiRefreshing() {
            spinner.setVisibility(View.VISIBLE);
            image.clearAnimation();
            image.setVisibility(View.INVISIBLE);
            text.setText(refreshingText);
        }
    
        private void setState(State state) {
            this.state = state;
            switch (state) {
            case PULL_TO_REFRESH:
                spinner.setVisibility(View.INVISIBLE);
                image.setVisibility(View.VISIBLE);
                text.setText(pullToRefreshText);
    
                if (showLastUpdatedText && lastUpdated != -1) {
                    lastUpdatedTextView.setVisibility(View.VISIBLE);
                    lastUpdatedTextView.setText(String.format(lastUpdatedText, lastUpdatedDateFormat.format(new Date(lastUpdated))));
                }
    
                break;
    
            case RELEASE_TO_REFRESH:
                spinner.setVisibility(View.INVISIBLE);
                image.setVisibility(View.VISIBLE);
                text.setText(releaseToRefreshText);
                break;
    
            case REFRESHING:
                setUiRefreshing();
    
                lastUpdated = System.currentTimeMillis();
                if (onRefreshListener == null) {
                    setState(State.PULL_TO_REFRESH);
                } else {
                    onRefreshListener.onRefresh();
                }
    
                break;
            }
        }
    
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);
    
            if (!hasResetHeader) {
                if (measuredHeaderHeight > 0 && state != State.REFRESHING) {
                    setHeaderPadding(-measuredHeaderHeight);
                }
    
                hasResetHeader = true;
            }
        }
    
        private class HeaderAnimationListener implements AnimationListener {
    
            private int height, translation;
            private State stateAtAnimationStart;
    
            public HeaderAnimationListener(int translation) {
                this.translation = translation;
            }
    
            @Override
            public void onAnimationStart(Animation animation) {
                stateAtAnimationStart = state;
    
                android.view.ViewGroup.LayoutParams lp = getLayoutParams();
                height = lp.height;
                lp.height = getHeight() - translation;
                setLayoutParams(lp);
    
                if (scrollbarEnabled) {
                    setVerticalScrollBarEnabled(false);
                }
            }
    
            @Override
            public void onAnimationEnd(Animation animation) {
                setHeaderPadding(stateAtAnimationStart == State.REFRESHING ? 0 : -measuredHeaderHeight - headerContainer.getTop());
                setSelection(0);
    
                android.view.ViewGroup.LayoutParams lp = getLayoutParams();
                lp.height = height;
                setLayoutParams(lp);
    
                if (scrollbarEnabled) {
                    setVerticalScrollBarEnabled(true);
                }
    
                if (bounceBackHeader) {
                    bounceBackHeader = false;
    
                    postDelayed(new Runnable() {
    
                        @Override
                        public void run() {
                            resetHeader();
                        }
                    }, BOUNCE_ANIMATION_DELAY);
                } else if (stateAtAnimationStart != State.REFRESHING) {
                    setState(State.PULL_TO_REFRESH);
                }
            }
    
            @Override
            public void onAnimationRepeat(Animation animation) {
            }
        }
    
        private class PTROnGlobalLayoutListener implements OnGlobalLayoutListener {
    
            @Override
            public void onGlobalLayout() {
                int initialHeaderHeight = header.getHeight();
    
                if (initialHeaderHeight > 0) {
                    measuredHeaderHeight = initialHeaderHeight;
    
                    if (measuredHeaderHeight > 0 && state != State.REFRESHING) {
                        setHeaderPadding(-measuredHeaderHeight);
                        requestLayout();
                    }
                }
    
                getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
        }
    
        private class PTROnItemClickListener implements OnItemClickListener {
    
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                hasResetHeader = false;
    
                if (onItemClickListener != null && state == State.PULL_TO_REFRESH) {
                    // Passing up onItemClick. Correct position with the number of
                    // header views
                    onItemClickListener.onItemClick(adapterView, view, position - getHeaderViewsCount(), id);
                }
            }
        }
    
        private class PTROnItemLongClickListener implements OnItemLongClickListener {
    
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long id) {
                hasResetHeader = false;
    
                if (onItemLongClickListener != null && state == State.PULL_TO_REFRESH) {
                    // Passing up onItemLongClick. Correct position with the number
                    // of header views
                    return onItemLongClickListener.onItemLongClick(adapterView, view, position - getHeaderViewsCount(), id);
                }
    
                return false;
            }
        }
    }
    
    package com.smartupdater.widget;
    导入java.text.simpleDataFormat;
    导入java.util.Date;
    导入android.content.Context;
    导入android.util.AttributeSet;
    导入android.util.Log;
    导入android.view.LayoutInflater;
    导入android.view.MotionEvent;
    导入android.view.view;
    导入android.view.ViewGroup;
    导入android.view.ViewTreeObserver;
    导入android.view.ViewTreeObserver.OnGlobalLayoutListener;
    导入android.view.animation.animation;
    导入android.view.animation.animation.AnimationListener;
    导入android.view.animation.LinearInterpolator;
    导入android.view.animation.OvershootInterpolator;
    导入android.view.animation.RotateAnimation;
    导入android.view.animation.TranslateAnimation;
    导入android.widget.AdapterView;
    导入android.widget.ImageView;
    导入android.widget.LinearLayout;
    导入android.widget.ListView;
    导入android.widget.ProgressBar;
    导入android.widget.RelativeLayout;
    导入android.widget.TextView;
    进口com.notecrate.R;
    导入com.smartupdater.utils.Constants;
    公共类PullToRefreshListView扩展了ListView{
    私人决赛爵士舞曲;
    专用静态最终浮子拉力=1.7f;
    私有静态最终整数反弹\动画\持续时间=700;
    私有静态最终整数反弹\动画\延迟=100;
    私人静态最终浮动反弹\超调\张力=1.4f;
    私有静态最终整数旋转箭头动画持续时间=250;
    私有静态枚举状态{
    拉到刷新,释放到刷新,刷新
    }
    /**
    *当您希望获得“拉入刷新”通知时要实现的接口
    *调用setOnRefreshListener(..)以激活OnRefreshListener。
    */
    公共接口刷新侦听器{
    /**
    *请求刷新时要调用的方法
    */
    公共void onRefresh();
    }
    专用静态测量头高;
    私有布尔值被禁用;
    私有布尔值bounceBackHeader;
    私有布尔锁滚动,同时刷新;
    私有布尔值ShowLastUpdateText;
    私有字符串pullToRefreshText;
    私有字符串releaseToRefreshText;
    私有字符串刷新文本;
    私有字符串lastUpdateText;
    私有SimpleDataFormat LastUpdateDateFormat=新SimpleDataFormat(“dd/MM HH:MM”);
    私人持股优先;
    私人机构;
    私有布尔头;
    私有long lastUpdated=-1;
    私营国家;
    私人线路布局总承包商;
    私有相对性标题;
    私有旋转动画;
    私有旋转动画反转动画;
    私有图像查看图像;
    私人旋转棒;
    私有文本查看文本;
    私有文本视图lastUpdatedTextView;
    私有OnItemClickListener OnItemClickListener;
    专用OnItemLongClickListener OnItemLongClickListener;
    私有OnRefreshListener-OnRefreshListener;
    公共PullToRefreshListView(上下文){
    超级(上下文);
    mHelper=init(上下文,null);
    init();
    }
    公共PullToRefreshListView(上下文、属性集属性){
    超级(上下文,attrs);
    mHelper=init(上下文,attrs);
    init();
    }
    公共PullToRefreshListView(上下文上下文、属性集属性、int-defStyle){
    超级(上下文、属性、定义样式);
    mHelper=init(上下文,attrs);
    init();
    }
    私有JazzyHelper初始化(上下文上下文,属性集属性){
    JazzyHelper助手=新的JazzyHelper(上下文,属性);
    super.setOnScrollListener(助手);
    返回助手;
    }
    @凌驾
    公共最终无效设置OnScrollListener(OnScrollListener l){
    mHelper.setOnScrollListener(l);
    }
    public void setTransitionEffect(int-transitionEffect){
    mHelper.setTransitionEffect(transitionEffect);
    }
    public void setshouldnolyanimatenewimes(仅布尔值yanimatenew){
    mHelper.setShouldOnlyAnimateNewItems(onlyAnimateNew);
    }
    public void setshouldlonlyanimatefling(布尔onlyFling){
    mHelper.setShouldOnlyAnimateFling(onlyFling);
    }
    public void setSimulateGridWithList(布尔simulateGridWithList){
    mHelper.setSimulateGridWithList(simulateGridWithList);
    setClipChildren(!simulateGridWithList);
    }
    public void setMaxAnimationVelocity(int itemsPerSecond){
    mHelper.setMaxAnimationVelocity(itemsPerSecond);
    }
    @凌驾
    公共无效setOnItemClickListener(OnItemClickListener OnItemClickListener){
    this.onItemClickListener=onItemClickListener;
    }
    @凌驾
    公共无效设置OnItemLongClickListener(OnItemLongClickListener OnItemLongClickListener){
    this.onItemLongClickListener=onItemLongClickListener;
    }
    /**
    *激活OnRefreshListener以获得“拉入刷新”通知
    *事件。
    * 
    *@param onRefreshListener
    *OnRefreshListener将收到通知
    */
    公共void setOnRefreshListener(OnRefreshListener OnRefreshListener){
    this.onRefreshListener=onRefreshListener;
    }
    /**
    *@return如果列表处于“刷新”状态
    */
    公共布尔值isRefreshing(){
    返回状态==状态。正在刷新;
    }
    /**
    *默认值为false。当lockScrollWhileRefreshing设置为true时,列表
    *在“刷新”模式下无法滚动。刷新时已“锁定”。
    * 
    *@param lock scroll同时刷新
    */
    public void setLockScrollWhileRefreshing(布尔值lo
    
    public void setOnScrollListener(OnScrollListener listener) {
        mOnScrollListener = listener;
    }
    
    /*******************************************************************************
     * Copyright 2011, 2012 Chris Banes.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     *******************************************************************************/
    package com.handmark.pulltorefresh.library;
    
    import com.example.jazzydemo.R;
    import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor;
    import com.handmark.pulltorefresh.library.internal.LoadingLayout;
    import com.xp.lvbh.others.jazzylistview.JazzyEffect;
    import com.xp.lvbh.others.jazzylistview.JazzyHelper;
    
    import android.annotation.TargetApi;
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.os.Build.VERSION;
    import android.os.Build.VERSION_CODES;
    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.FrameLayout;
    import android.widget.ListAdapter;
    import android.widget.ListView;
    import android.widget.AbsListView.OnScrollListener;
    
    public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView> {
    
        private final JazzyHelper mHelper;
    
        private LoadingLayout mHeaderLoadingView;
        private LoadingLayout mFooterLoadingView;
    
        private FrameLayout mLvFooterLoadingFrame;
    
        private boolean mListViewExtrasEnabled;
    
        public PullToRefreshListView(Context context) {
            super(context);
            mHelper = init(context, null);
        }
    
        public PullToRefreshListView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mHelper = init(context, null);
        }
    
        public PullToRefreshListView(Context context, Mode mode) {
            super(context, mode);
            mHelper = init(context, null);
        }
    
        public PullToRefreshListView(Context context, Mode mode, AnimationStyle style) {
            super(context, mode, style);
            mHelper = init(context, null);
        }
    
        @Override
        public final Orientation getPullToRefreshScrollDirection() {
            return Orientation.VERTICAL;
        }
    
        @Override
        protected void onRefreshing(final boolean doScroll) {
            /**
             * If we're not showing the Refreshing view, or the list is empty, the
             * the header/footer views won't show so we use the normal method.
             */
            ListAdapter adapter = mRefreshableView.getAdapter();
            if (!mListViewExtrasEnabled || !getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {
                super.onRefreshing(doScroll);
                return;
            }
    
            super.onRefreshing(false);
    
            final LoadingLayout origLoadingView, listViewLoadingView, oppositeListViewLoadingView;
            final int selection, scrollToY;
    
            switch (getCurrentMode()) {
                case MANUAL_REFRESH_ONLY:
                case PULL_FROM_END:
                    origLoadingView = getFooterLayout();
                    listViewLoadingView = mFooterLoadingView;
                    oppositeListViewLoadingView = mHeaderLoadingView;
                    selection = mRefreshableView.getCount() - 1;
                    scrollToY = getScrollY() - getFooterSize();
                    break;
                case PULL_FROM_START:
                default:
                    origLoadingView = getHeaderLayout();
                    listViewLoadingView = mHeaderLoadingView;
                    oppositeListViewLoadingView = mFooterLoadingView;
                    selection = 0;
                    scrollToY = getScrollY() + getHeaderSize();
                    break;
            }
    
            // Hide our original Loading View
            origLoadingView.reset();
            origLoadingView.hideAllViews();
    
            // Make sure the opposite end is hidden too
            oppositeListViewLoadingView.setVisibility(View.GONE);
    
            // Show the ListView Loading View and set it to refresh.
            listViewLoadingView.setVisibility(View.VISIBLE);
            listViewLoadingView.refreshing();
    
            if (doScroll) {
                // We need to disable the automatic visibility changes for now
                disableLoadingLayoutVisibilityChanges();
    
                // We scroll slightly so that the ListView's header/footer is at the
                // same Y position as our normal header/footer
                setHeaderScroll(scrollToY);
    
                // Make sure the ListView is scrolled to show the loading
                // header/footer
                mRefreshableView.setSelection(selection);
    
                // Smooth scroll as normal
                smoothScrollTo(0);
            }
        }
    
        @Override
        protected void onReset() {
            /**
             * If the extras are not enabled, just call up to super and return.
             */
            if (!mListViewExtrasEnabled) {
                super.onReset();
                return;
            }
    
            final LoadingLayout originalLoadingLayout, listViewLoadingLayout;
            final int scrollToHeight, selection;
            final boolean scrollLvToEdge;
    
            switch (getCurrentMode()) {
                case MANUAL_REFRESH_ONLY:
                case PULL_FROM_END:
                    originalLoadingLayout = getFooterLayout();
                    listViewLoadingLayout = mFooterLoadingView;
                    selection = mRefreshableView.getCount() - 1;
                    scrollToHeight = getFooterSize();
                    scrollLvToEdge = Math.abs(mRefreshableView.getLastVisiblePosition() - selection) <= 1;
                    break;
                case PULL_FROM_START:
                default:
                    originalLoadingLayout = getHeaderLayout();
                    listViewLoadingLayout = mHeaderLoadingView;
                    scrollToHeight = -getHeaderSize();
                    selection = 0;
                    scrollLvToEdge = Math.abs(mRefreshableView.getFirstVisiblePosition() - selection) <= 1;
                    break;
            }
    
            // If the ListView header loading layout is showing, then we need to
            // flip so that the original one is showing instead
            if (listViewLoadingLayout.getVisibility() == View.VISIBLE) {
    
                // Set our Original View to Visible
                originalLoadingLayout.showInvisibleViews();
    
                // Hide the ListView Header/Footer
                listViewLoadingLayout.setVisibility(View.GONE);
    
                /**
                 * Scroll so the View is at the same Y as the ListView
                 * header/footer, but only scroll if: we've pulled to refresh, it's
                 * positioned correctly
                 */
                if (scrollLvToEdge && getState() != State.MANUAL_REFRESHING) {
                    mRefreshableView.setSelection(selection);
                    setHeaderScroll(scrollToHeight);
                }
            }
    
            // Finally, call up to super
            super.onReset();
        }
    
        @Override
        protected LoadingLayoutProxy createLoadingLayoutProxy(final boolean includeStart, final boolean includeEnd) {
            LoadingLayoutProxy proxy = super.createLoadingLayoutProxy(includeStart, includeEnd);
    
            if (mListViewExtrasEnabled) {
                final Mode mode = getMode();
    
                if (includeStart && mode.showHeaderLoadingLayout()) {
                    proxy.addLayout(mHeaderLoadingView);
                }
                if (includeEnd && mode.showFooterLoadingLayout()) {
                    proxy.addLayout(mFooterLoadingView);
                }
            }
    
            return proxy;
        }
    
        protected ListView createListView(Context context, AttributeSet attrs) {
            final ListView lv;
            if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
                lv = new InternalListViewSDK9(context, attrs);
            } else {
                lv = new InternalListView(context, attrs);
            }
            return lv;
        }
    
        @Override
        protected ListView createRefreshableView(Context context, AttributeSet attrs) {
            ListView lv = createListView(context, attrs);
    
            // Set it to this so it can be used in ListActivity/ListFragment
            lv.setId(android.R.id.list);
            return lv;
        }
    
        @Override
        protected void handleStyledAttributes(TypedArray a) {
            super.handleStyledAttributes(a);
    
            mListViewExtrasEnabled = a.getBoolean(R.styleable.PullToRefresh_ptrListViewExtrasEnabled, true);
    
            if (mListViewExtrasEnabled) {
                final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                        FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL);
    
                // Create Loading Views ready for use later
                FrameLayout frame = new FrameLayout(getContext());
                mHeaderLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_START, a);
                mHeaderLoadingView.setVisibility(View.GONE);
                frame.addView(mHeaderLoadingView, lp);
                mRefreshableView.addHeaderView(frame, null, false);
    
                mLvFooterLoadingFrame = new FrameLayout(getContext());
                mFooterLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_END, a);
                mFooterLoadingView.setVisibility(View.GONE);
                mLvFooterLoadingFrame.addView(mFooterLoadingView, lp);
    
                /**
                 * If the value for Scrolling While Refreshing hasn't been
                 * explicitly set via XML, enable Scrolling While Refreshing.
                 */
                if (!a.hasValue(R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) {
                    setScrollingWhileRefreshingEnabled(true);
                }
            }
        }
    
        @TargetApi(9)
        final class InternalListViewSDK9 extends InternalListView {
    
            public InternalListViewSDK9(Context context, AttributeSet attrs) {
                super(context, attrs);
            }
    
            @Override
            protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
                    int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
    
                final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
                        scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    
                // Does all of the hard work...
                OverscrollHelper.overScrollBy(PullToRefreshListView.this, deltaX, scrollX, deltaY, scrollY, isTouchEvent);
    
                return returnValue;
            }
        }
    
        protected class InternalListView extends ListView implements EmptyViewMethodAccessor {
    
            private boolean mAddedLvFooter = false;
    
            public InternalListView(Context context, AttributeSet attrs) {
                super(context, attrs);
            }
    
            @Override
            protected void dispatchDraw(Canvas canvas) {
                /**
                 * This is a bit hacky, but Samsung's ListView has got a bug in it
                 * when using Header/Footer Views and the list is empty. This masks
                 * the issue so that it doesn't cause an FC. See Issue #66.
                 */
                try {
                    super.dispatchDraw(canvas);
                } catch (IndexOutOfBoundsException e) {
                    e.printStackTrace();
                }
            }
    
            @Override
            public boolean dispatchTouchEvent(MotionEvent ev) {
                /**
                 * This is a bit hacky, but Samsung's ListView has got a bug in it
                 * when using Header/Footer Views and the list is empty. This masks
                 * the issue so that it doesn't cause an FC. See Issue #66.
                 */
                try {
                    return super.dispatchTouchEvent(ev);
                } catch (IndexOutOfBoundsException e) {
                    e.printStackTrace();
                    return false;
                }
            }
    
            @Override
            public void setAdapter(ListAdapter adapter) {
                // Add the Footer View at the last possible moment
                if (null != mLvFooterLoadingFrame && !mAddedLvFooter) {
                    addFooterView(mLvFooterLoadingFrame, null, false);
                    mAddedLvFooter = true;
                }
    
                super.setAdapter(adapter);
            }
    
            @Override
            public void setEmptyView(View emptyView) {
                PullToRefreshListView.this.setEmptyView(emptyView);
            }
    
            @Override
            public void setEmptyViewInternal(View emptyView) {
                super.setEmptyView(emptyView);
            }
    
        }
        //add jazzy listview
        /**
         * Sets the desired transition effect.
         *
         * @param transitionEffect The non-bundled transition provided by the client.
         */
        public void setTransitionEffect(JazzyEffect transitionEffect) {
            mHelper.setTransitionEffect(transitionEffect);
        }
    
        @Override
        public void setOnScrollListener(OnScrollListener l) {
            mHelper.setOnScrollListener(l);
        }
    
        private JazzyHelper init(Context context, AttributeSet attrs) {
            JazzyHelper helper = new JazzyHelper(context, attrs);
            super.setOnScrollListener(helper);
            return helper;
        }
    }