Android

来源:互联网 发布:livin on a prayer知乎 编辑:程序博客网 时间:2024/05/21 13:59

最近项目已经接近尾声了,由于一些原因,我可能又要找新的工作了,啊啊啊,有点忧伤。

之前有在新浪写过一写博客,现在准备在CSDN上写博客了,CSDN博客-最大IT写作分享平台,很多资料都可以在这找到,所有我也搬家了。

自己也写了好几个项目了,但是博客还没有多少,其实有很多东西都需要记记得,温故而知新嘛!趁不忙,就记录记录。

好了 ,上面的可以忽略,下面正式开始了!


下拉刷新,上拉加载更多

地址:https://github.com/captainbupt/android-Ultra-Pull-To-Refresh-With-Load-More


优点:

这个框架的扩展性还是很强的,头部和底部都可以自定义,

它其中可以嵌套任何控件,ListView、GridView、ScrollView、RecyclerView,甚至TextView。

更多样式参照GitHub中的源码


一.jar包的引用

开发工具是AS

在gradle添加到项目中,我这里是1.0.6,最新版可以到githup上看

compile 'in.srain.cube:ptr-load-more:1.0.6'

二、使用方法

首先在你需要刷新和加载的地方,最外层加入

in.srain.cube.views.ptr.PtrClassicFrameLayout


以我的为例,我这是给gridview加刷新和加载更多


在xml中

  <!--      ptr:ptr_duration_to_close_either:头部和底部回弹时间      ptr:ptr_keep_header_when_refresh:刷新过程中是否保留头部      ptr:ptr_pull_to_fresh:下拉刷新/释放刷新,默认是释放刷新      ptr:ptr_ratio_of_header_height_to_refresh:触发刷新时移动的位置比例,指的是与头部的比例      ptr:ptr_resistance:阻尼系数,越大下拉越吃力  -->
<in.srain.cube.views.ptr.PtrClassicFrameLayout android:id="@+id/rotate_header_grid_view_frame" android:layout_width="match_parent" android:layout_height="match_parent" app:ptr_duration_to_close_either="1000" app:ptr_keep_header_when_refresh="true" app:ptr_pull_to_fresh="false" app:ptr_ratio_of_header_height_to_refresh="1.2" app:ptr_resistance="1.7"> <GridView android:id="@+id/myPoints_gridview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="@dimen/margin_ten" android:layout_marginLeft="@dimen/margin_ten" android:layout_marginRight="@dimen/margin_ten" android:layout_marginTop="@dimen/margin_ten" android:fadingEdge="none" android:horizontalSpacing="@dimen/margin_ten" android:listSelector="@android:color/transparent" android:numColumns="2" android:overScrollMode="never" android:scrollbars="none" android:verticalSpacing="@dimen/margin_ten"></GridView></in.srain.cube.views.ptr.PtrClassicFrameLayout>


在Activity中


使用默认样式

//初始化

@ViewInject(R.id.rotate_header_grid_view_frame)private PtrClassicFrameLayout mPtrFrame;

//在oncreate中

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_my_points);    initReFresh();}


/** * 设置下拉刷新上拉加载 */private void initReFresh() {    //设置下拉刷新上拉加载    mPtrFrame.disableWhenHorizontalMove(true);//解决横向滑动冲突    mPtrFrame.setPtrHandler(new PtrDefaultHandler2() {                                @Override                                public void onRefreshBegin(PtrFrameLayout frame) {                                    mPtrFrame.postDelayed(new Runnable() {                                        @Override                                        public void run() {                                          //刷新数据                                        }                                    }, 1000);                                }                                @Override                                public void onLoadMoreBegin(PtrFrameLayout frame) {                                    mPtrFrame.postDelayed(new Runnable() {                                        @Override                                        public void run() {                                       //加载更多                                        }                                    }, 1000);                                }                                @Override                                public boolean checkCanDoLoadMore(PtrFrameLayout frame, View content, View footer) {                                    return super.checkCanDoLoadMore(frame, gridView, footer);                                }                                @Override                                public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {                                    return super.checkCanDoRefresh(frame, gridView, header);                                }                            }    );}
//结束刷新和加载更多的动画,在你成功请求到数据后写入

mPtrFrame.refreshComplete();

默认样式就是这样了


自定义头的部和底部

自定时都继承PtrUIHandler


自定义的头部文件

MyHeadView

package com.example.ruidun.ShanXunApplication.view;import android.content.Context;import android.os.Handler;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.TextView;import com.example.ruidun.ShanXunApplication.R;import in.srain.cube.views.ptr.PtrFrameLayout;import in.srain.cube.views.ptr.PtrUIHandler;import in.srain.cube.views.ptr.indicator.PtrIndicator;/** *  * 项目名称:¥{PROJECT_NAME} * 创建人:潇潇 *  */public class MyHeadView extends FrameLayout implements PtrUIHandler {    private TextView tvLoading;    private View view;    //箭头    private ImageView mArrowImageView;    //开始加载的动画    private ProgressBar mProgressBar;    //动画    private Animation mRotateUpAnim;    //显示当前进度的textview    private TextView mHintTextView;    private Animation mRotateDownAnim;    private final int ROTATE_ANIM_DURATION = 180;    public MyHeadView(Context context) {        this(context, null);    }    public MyHeadView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MyHeadView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    //实例化控件    private void init() {        view = LayoutInflater.from(getContext()).inflate(R.layout.xlistview_header, this, false);        addView(view);        tvLoading = (TextView) view.findViewById(R.id.xlistview_header_hint_textview);        mArrowImageView = (ImageView) view.findViewById(R.id.xlistview_header_arrow);        mProgressBar = (ProgressBar) view.findViewById(R.id.xlistview_header_progressbar);        mHintTextView = (TextView) view.findViewById(R.id.xlistview_header_hint_textview);// 初始情况,设置下拉刷新view高度为0        mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,                0.5f);        mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);        mRotateUpAnim.setFillAfter(true);        mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,                0.5f);        mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);        mRotateDownAnim.setFillAfter(true);    }    //重写方法    @Override    public void onUIReset(PtrFrameLayout frame) {        //重置    }    @Override    public void onUIRefreshPrepare(PtrFrameLayout frame) {        //准备刷新    //重置时,将动画置为初始状态        mArrowImageView.clearAnimation();        mArrowImageView.startAnimation(mRotateUpAnim);        mHintTextView.setText(R.string.xlistview_header_hint_ready);    }    @Override    public void onUIRefreshBegin(PtrFrameLayout frame) {        //开始刷新 显示刷新进度跟文本   //开始刷新,启动动画        mArrowImageView.setVisibility(View.INVISIBLE);        mProgressBar.setVisibility(View.VISIBLE);        tvLoading.setText("正在加载");    }    @Override    public void onUIRefreshComplete(PtrFrameLayout frame, boolean isHeader) {        //刷新完成  设置文本 设置进度隐藏        tvLoading.setText("加载完毕");        Handler handler = new Handler();        handler.postDelayed(new Runnable() {            @Override            public void run() {                mArrowImageView.setVisibility(View.VISIBLE);                mProgressBar.setVisibility(View.INVISIBLE);            }        }, 500);    }    @Override    public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {        final int mOffsetToRefresh = frame.getOffsetToRefresh();        final int currentPos = ptrIndicator.getCurrentPosY();        final int lastPos = ptrIndicator.getLastPosY();        if (currentPos < mOffsetToRefresh) {            //未到达刷新线            if (status == PtrFrameLayout.PTR_STATUS_PREPARE) {                mArrowImageView.startAnimation(mRotateDownAnim);                tvLoading.setText("下拉刷新");            }        } else if (currentPos > mOffsetToRefresh) {            //到达或超过刷新线            if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) {                mArrowImageView.clearAnimation();                tvLoading.setText("释放刷新");            }        }    }    //设置背景色    public void setHeadColor(int color) {        view.setBackgroundColor(color);    }}


自定义底部布局跟自定义头布局都是一样


MyFooterView

package com.example.ruidun.ShanXunApplication.view;import android.content.Context;import android.content.SharedPreferences;import android.content.res.TypedArray;import android.text.TextUtils;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.animation.LinearInterpolator;import android.view.animation.RotateAnimation;import android.widget.FrameLayout;import android.widget.TextView;import com.example.ruidun.ShanXunApplication.R;import java.text.SimpleDateFormat;import java.util.Date;import in.srain.cube.views.ptr.PtrFrameLayout;import in.srain.cube.views.ptr.PtrUIHandler;import in.srain.cube.views.ptr.indicator.PtrIndicator;/** *  * 项目名称:¥{PROJECT_NAME} * 创建人:潇潇 *  */public class MyFooterView extends FrameLayout implements PtrUIHandler {    private final static String KEY_SharedPreferences = "cube_ptr_classic_last_update";    private static SimpleDateFormat sDataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    private int mRotateAniTime = 150;    protected RotateAnimation mFlipAnimation;    protected RotateAnimation mReverseFlipAnimation;    //当前加载进度描述    protected TextView mTitleTextView;    //加载动画    private View mProgressBar;    private long mLastUpdateTime = -1;    private String mLastUpdateTimeKey;    private boolean mShouldShowLastUpdate;    private MyFooterView.LastUpdateTimeUpdater mLastUpdateTimeUpdater = new MyFooterView.LastUpdateTimeUpdater();    public MyFooterView(Context context) {        super(context);        initViews(null);    }    public MyFooterView(Context context, AttributeSet attrs) {        super(context, attrs);        initViews(attrs);    }    public MyFooterView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initViews(attrs);    }    //初始化布局    protected void initViews(AttributeSet attrs) {        TypedArray arr = getContext().obtainStyledAttributes(attrs, in.srain.cube.views.ptr.R.styleable.PtrClassicHeader, 0, 0);        if (arr != null) {            mRotateAniTime = arr.getInt(in.srain.cube.views.ptr.R.styleable.PtrClassicHeader_ptr_rotate_ani_time, mRotateAniTime);        }        buildAnimation();        View header = LayoutInflater.from(getContext()).inflate(R.layout.xlistview_footer, this);        mTitleTextView = (TextView) header.findViewById(R.id.xlistview_footer_hint_textview);        mProgressBar = header.findViewById(R.id.xlistview_footer_progressbar);        resetView();    }    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        if (mLastUpdateTimeUpdater != null) {            mLastUpdateTimeUpdater.stop();        }    }    public void setRotateAniTime(int time) {        if (time == mRotateAniTime || time == 0) {            return;        }        mRotateAniTime = time;        buildAnimation();    }    /**     * Specify the last update time by this key string     *     * @param key     */    public void setLastUpdateTimeKey(String key) {        if (TextUtils.isEmpty(key)) {            return;        }        mLastUpdateTimeKey = key;    }    /**     * Using an object to specify the last update time.     *     * @param object     */    public void setLastUpdateTimeRelateObject(Object object) {        setLastUpdateTimeKey(object.getClass().getName() + "footer");    }    //加载时的动画效果    protected void buildAnimation() {        mFlipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);        mFlipAnimation.setInterpolator(new LinearInterpolator());        mFlipAnimation.setDuration(mRotateAniTime);        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(mRotateAniTime);        mReverseFlipAnimation.setFillAfter(true);    }    private void resetView() {        hideRotateView();        mProgressBar.setVisibility(INVISIBLE);    }    private void hideRotateView() {//        mRotateView.clearAnimation();//        mRotateView.setVisibility(INVISIBLE);    }    @Override    public void onUIReset(PtrFrameLayout frame) {        //重置        resetView();        mShouldShowLastUpdate = true;        tryUpdateLastUpdateTime();    }    @Override    public void onUIRefreshPrepare(PtrFrameLayout frame) {        //准备加载更多   //重置时,将动画置为初始状态        mShouldShowLastUpdate = true;        tryUpdateLastUpdateTime();        mLastUpdateTimeUpdater.start();        mProgressBar.setVisibility(INVISIBLE);//        mRotateView.setVisibility(VISIBLE);        mTitleTextView.setVisibility(VISIBLE);        if (frame.isPullToRefresh()) {            //释放加载            mTitleTextView.setText("松开载入更多");        } else {            //上拉            mTitleTextView.setText("查看更多");        }    }    @Override    public void onUIRefreshBegin(PtrFrameLayout frame) {        //开始加载        mShouldShowLastUpdate = false;        hideRotateView();        mProgressBar.setVisibility(VISIBLE);        //正在加载中        mTitleTextView.setVisibility(GONE);        mTitleTextView.setText(in.srain.cube.views.ptr.R.string.cube_ptr_loading);        tryUpdateLastUpdateTime();        mLastUpdateTimeUpdater.stop();    }    @Override    public void onUIRefreshComplete(PtrFrameLayout frame, boolean isHeader) {        //加载完成        if (isHeader) {            return;        }        hideRotateView();        mProgressBar.setVisibility(INVISIBLE);        //加载完成        mTitleTextView.setVisibility(VISIBLE);        mTitleTextView.setText(getResources().getString(in.srain.cube.views.ptr.R.string.cube_ptr_load_complete));        // update last update time        SharedPreferences sharedPreferences = getContext().getSharedPreferences(KEY_SharedPreferences, 0);        if (!TextUtils.isEmpty(mLastUpdateTimeKey)) {            mLastUpdateTime = new Date().getTime();            sharedPreferences.edit().putLong(mLastUpdateTimeKey, mLastUpdateTime).commit();        }    }    private void tryUpdateLastUpdateTime() {        if (TextUtils.isEmpty(mLastUpdateTimeKey) || !mShouldShowLastUpdate) {        } else {            String time = getLastUpdateTime();            if (TextUtils.isEmpty(time)) {            } else {            }        }    }    private String getLastUpdateTime() {        if (mLastUpdateTime == -1 && !TextUtils.isEmpty(mLastUpdateTimeKey)) {            mLastUpdateTime = getContext().getSharedPreferences(KEY_SharedPreferences, 0).getLong(mLastUpdateTimeKey, -1);        }        if (mLastUpdateTime == -1) {            return null;        }        long diffTime = new Date().getTime() - mLastUpdateTime;        int seconds = (int) (diffTime / 1000);        if (diffTime < 0) {            return null;        }        if (seconds <= 0) {            return null;        }        StringBuilder sb = new StringBuilder();        sb.append(getContext().getString(in.srain.cube.views.ptr.R.string.cube_ptr_last_update));        if (seconds < 60) {            sb.append(seconds + getContext().getString(in.srain.cube.views.ptr.R.string.cube_ptr_seconds_ago));        } else {            int minutes = (seconds / 60);            if (minutes > 60) {                int hours = minutes / 60;                if (hours > 24) {                    Date date = new Date(mLastUpdateTime);                    sb.append(sDataFormat.format(date));                } else {                    sb.append(hours + getContext().getString(in.srain.cube.views.ptr.R.string.cube_ptr_hours_ago));                }            } else {                sb.append(minutes + getContext().getString(in.srain.cube.views.ptr.R.string.cube_ptr_minutes_ago));            }        }        return sb.toString();    }    @Override    public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {        final int mOffsetToRefresh = frame.getOffsetToRefresh();        final int currentPos = ptrIndicator.getCurrentPosY();        final int lastPos = ptrIndicator.getLastPosY();        if (currentPos < mOffsetToRefresh && lastPos >= mOffsetToRefresh) {            if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) {                crossRotateLineFromBottomUnderTouch(frame);//                if (mRotateView != null) {//                    mRotateView.clearAnimation();//                    mRotateView.startAnimation(mReverseFlipAnimation);//                }            }        } else if (currentPos > mOffsetToRefresh && lastPos <= mOffsetToRefresh) {            if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) {                crossRotateLineFromTopUnderTouch(frame);//                if (mRotateView != null) {//                    mRotateView.clearAnimation();//                    mRotateView.startAnimation(mFlipAnimation);//                }            }        }    }    private void crossRotateLineFromTopUnderTouch(PtrFrameLayout frame) {        if (!frame.isPullToRefresh()) {            mTitleTextView.setVisibility(VISIBLE);            mTitleTextView.setText("松开载入更多");        }    }    private void crossRotateLineFromBottomUnderTouch(PtrFrameLayout frame) {        mTitleTextView.setVisibility(VISIBLE);        if (frame.isPullToRefresh()) {            mTitleTextView.setText("松开载入更多");        } else {            mTitleTextView.setText("查看更多");        }    }    private class LastUpdateTimeUpdater implements Runnable {        private boolean mRunning = false;        private void start() {            if (TextUtils.isEmpty(mLastUpdateTimeKey)) {                return;            }            mRunning = true;            run();        }        private void stop() {            mRunning = false;            removeCallbacks(this);        }        @Override        public void run() {            tryUpdateLastUpdateTime();            if (mRunning) {                postDelayed(this, 1000);            }        }    }}





在Activity中使用吧头布局和底部加上就ok了


/** * 设置下拉刷新上拉加载 */private void initReFresh() {    MyFooterView fView = new MyFooterView(MyPointsActivity.this);//自定义底部加载更多    mPtrFrame.setFooterView(fView);    mPtrFrame.addPtrUIHandler(fView);    MyHeadView hView = new MyHeadView(MyPointsActivity.this); //自定义头部 刷新    mPtrFrame.setKeepHeaderWhenRefresh(true);//刷新时保留头部    mPtrFrame.setHeaderView(hView);    mPtrFrame.addPtrUIHandler(hView);    //设置下拉刷新上拉加载    mPtrFrame.disableWhenHorizontalMove(true);//解决横向滑动冲突    mPtrFrame.setPtrHandler(new PtrDefaultHandler2() {                                @Override                                public void onRefreshBegin(PtrFrameLayout frame) {                                    mPtrFrame.postDelayed(new Runnable() {                                        @Override                                        public void run() {                                           //刷新                                                                                   }                                    }, 1000);                                }                                @Override                                public void onLoadMoreBegin(PtrFrameLayout frame) {                                    mPtrFrame.postDelayed(new Runnable() {                                        @Override                                        public void run() {                                            //加载更多                                        }                                    }, 1000);                                }                                @Override                                public boolean checkCanDoLoadMore(PtrFrameLayout frame, View content, View footer) {                                    return super.checkCanDoLoadMore(frame, gridView, footer);                                }                                @Override                                public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {                                    return super.checkCanDoRefresh(frame, gridView, header);                                }                            }    );}










原创粉丝点击