打造通用下拉刷新上拉加載更多組件

android開(kāi)發(fā)中最常用的就是列表組件,如ListView,recycleView,用到它們感覺(jué)就會(huì)涉及到數(shù)據(jù)更新,分頁(yè)加載。

最開(kāi)始的時(shí)候,刷新組件我是在技術(shù)群里頭找了一個(gè)被人綁定好的庫(kù),是綁定的github上一個(gè)星星很多的java原生組件。但是demo很簡(jiǎn)單,對(duì)于當(dāng)時(shí)小白的我懵逼了,不曉得咋個(gè)用,而且一直覺(jué)得banding的庫(kù)總感覺(jué)有問(wèn)題,就想著直接找一個(gè)java的庫(kù)翻譯成C#版本的。功夫不負(fù)苦心人,在csdn上找到了一篇http://blog.csdn.net/zhongkejingwang/article/details/38868463

寫(xiě)的很詳細(xì),翻譯起來(lái)也省了不少力,也很感謝原作者。

突然想起一句話(huà),叫做我們不生產(chǎn)代碼,只是代碼的搬運(yùn)工!

Android培訓(xùn),安卓培訓(xùn),手機(jī)開(kāi)發(fā)培訓(xùn),移動(dòng)開(kāi)發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

 這里貼上我翻譯好的其中幾個(gè)很重要的組件的代碼:

1.PullToRefreshLayout

using System;using System.Threading.Tasks;using Android.Content;using Android.OS;using Android.Util;using Android.Views;using Android.Views.Animations;using Android.Widget;using CNBlog.Droid.Utils;namespace CNBlog.Droid.PullableView
{    public class PullToRefreshLayout : RelativeLayout
    {        // 初始狀態(tài)  
        private const int initStatus = 0;        // 釋放刷新  
        private const int releaseToRefresh = 1;        // 正在刷新  
        private const int refreshing = 2;        // 釋放加載  
        private const int releaseToLoad = 3;        // 正在加載  
        private const int loading = 4;        // 操作完畢  
        private const int complete = 5;        // 當(dāng)前狀態(tài)  
        private int currentStatus = 0;        // 刷新回調(diào)接口  
        private OnRefreshListener mListener;        // 刷新成功  
        private const int succeed = 0;        // 刷新失敗  
        private const int failed = 1;        // 按下Y坐標(biāo),上一個(gè)事件點(diǎn)Y坐標(biāo)  
        private float downY, lastY;        // 下拉的距離。注意:pullDownY和pullUpY不可能同時(shí)不為0  
        private float pullDownY = 0;        // 上拉的距離  
        private float pullUpY = 0;        // 釋放刷新的距離  
        private float refreshDist = 200;        // 釋放加載的距離  
        private float loadmoreDist = 200;        private UIScheduling uScheduling;        // 回滾速度  
        private float moveSpeed = 8;        // 第一次執(zhí)行布局  
        private bool isLayout = false;        // 在刷新過(guò)程中滑動(dòng)操作  
        private bool isTouch = false;        // 手指滑動(dòng)距離與下拉頭的滑動(dòng)距離比,中間會(huì)隨正切函數(shù)變化  
        private float radio = 2;        // 下拉箭頭的轉(zhuǎn)180°動(dòng)畫(huà)  
        private RotateAnimation rotateAnimation;        // 均勻旋轉(zhuǎn)動(dòng)畫(huà)  
        private RotateAnimation refreshingAnimation;        // 下拉頭  
        private View refreshView;        // 下拉的箭頭  
        public View pullView;        // 正在刷新的圖標(biāo)  
        private View refreshingView;        // 刷新結(jié)果圖標(biāo)  
        private View refreshStateImageView;        // 刷新結(jié)果:成功或失敗  
        private TextView refreshStateTextView;        // 上拉頭  
        private View loadmoreView;        // 上拉的箭頭  
        public View pullUpView;        // 正在加載的圖標(biāo)  
        private View loadingView;        // 加載結(jié)果圖標(biāo)  
        private View loadStateImageView;        // 加載結(jié)果:成功或失敗  
        private TextView loadStateTextView;        //請(qǐng)求加載錯(cuò)誤View
        private View errorView;        // 實(shí)現(xiàn)了Pullable接口的View  
        private View pullableView;        // 過(guò)濾多點(diǎn)觸碰  
        private int mEvents;        // 這兩個(gè)變量用來(lái)控制pull的方向,如果不加控制,當(dāng)情況滿(mǎn)足可上拉又可下拉時(shí)沒(méi)法下拉  
        private bool canPullDown = true;        private bool canPullUp = true;        private Context mContext;        private Handler updateUIHandler;        public void setOnRefreshListener(OnRefreshListener listener)
        {
            mListener = listener;
        }        public PullToRefreshLayout(Context context)
            : base(context)
        {
            initView(context);
        }        public PullToRefreshLayout(Context context, IAttributeSet attrs)
            : base(context, attrs)
        {
            initView(context);
        }        public PullToRefreshLayout(Context context, IAttributeSet attrs, int defStyle)
            : base(context, attrs, defStyle)
        {
            initView(context);
        }        private void initView(Context context)
        {
            mContext = context;
            updateUIHandler = new Handler((Message msg) =>
            {                    // 回彈速度隨下拉距離moveDeltaY增大而增大
                    moveSpeed = (float)(8 + 5 * Math.Tan(Math.PI / 2 / MeasuredHeight * (pullDownY + Math.Abs(pullUpY))));                    if (!isTouch)
                    {                        // 正在刷新,且沒(méi)有往上推的話(huà)則懸停,顯示"正在刷新..."
                        if (currentStatus == refreshing && pullDownY <= refreshDist)
                        {
                            pullDownY = refreshDist;
                            uScheduling.Cancel();
                        }                        else if (currentStatus == loading && -pullUpY <= loadmoreDist)
                        {
                            pullUpY = -loadmoreDist;
                            uScheduling.Cancel();
                        }
                    }                    if (pullDownY > 0)
                        pullDownY -= moveSpeed;                    else if (pullUpY < 0)
                        pullUpY += moveSpeed;                    if (pullDownY < 0)
                    {                        // 已完成回彈
                        pullDownY = 0;
                        pullView.ClearAnimation();                        // 隱藏下拉頭時(shí)有可能還在刷新,只有當(dāng)前狀態(tài)不是正在刷新時(shí)才改變狀態(tài)
                        if (currentStatus != refreshing && currentStatus != loading)
                            changeStatus(initStatus);
                        uScheduling.Cancel();
                        RequestLayout();
                    }                    if (pullUpY > 0)
                    {                        // 已完成回彈
                        pullUpY = 0;
                        pullUpView.ClearAnimation();                        // 隱藏上拉頭時(shí)有可能還在刷新,只有當(dāng)前狀態(tài)不是正在刷新時(shí)才改變狀態(tài)
                        if (currentStatus != refreshing && currentStatus != loading)
                            changeStatus(initStatus);
                        uScheduling.Cancel();
                        RequestLayout();
                    }                    // 刷新布局,會(huì)自動(dòng)調(diào)用onLayout                    RequestLayout();                    // 沒(méi)有拖拉或者回彈完成
                    if (pullDownY + Math.Abs(pullUpY) == 0)
                    {
                        uScheduling.Cancel();
                    }
            });
            uScheduling = new UIScheduling(updateUIHandler);
            rotateAnimation = (RotateAnimation)AnimationUtils.LoadAnimation(
                context, Resource.Animator.reverse_anim);
            refreshingAnimation = (RotateAnimation)AnimationUtils.LoadAnimation(
                context, Resource.Animator.rotating);            // 添加勻速轉(zhuǎn)動(dòng)動(dòng)畫(huà)
            LinearInterpolator lir = new LinearInterpolator();
            rotateAnimation.Interpolator = lir;
            refreshingAnimation.Interpolator = lir;
        }        private void initView()
        {            // 初始化下拉布局
            pullView = refreshView.FindViewById<View>(Resource.Id.pull_icon);
            refreshStateTextView = refreshView.FindViewById<TextView>(Resource.Id.state_tv);
            refreshingView = refreshView.FindViewById<View>(Resource.Id.refreshing_icon);
            refreshStateImageView = refreshView.FindViewById<View>(Resource.Id.state_iv);            // 初始化上拉布局
            pullUpView = loadmoreView.FindViewById<View>(Resource.Id.pullup_icon);
            loadStateTextView = loadmoreView.FindViewById<TextView>(Resource.Id.loadstate_tv);
            loadingView = loadmoreView.FindViewById<View>(Resource.Id.loading_icon);
            loadStateImageView = loadmoreView.FindViewById<View>(Resource.Id.loadstate_iv);
        }        /// <summary>
        /// 完成刷新操作,顯示刷新結(jié)果。注意:刷新完成后一定要調(diào)用這個(gè)方法        /// </summary>
        /// <param name="refreshResult">succeed代表成功, failed代表失敗</param>
        public void refreshFinish(int refreshResult)
        {
            refreshingView.ClearAnimation();
            refreshingView.Visibility = ViewStates.Gone;            switch (refreshResult)
            {                case 0:                    // 刷新成功
                    refreshStateImageView.Visibility = ViewStates.Visible;
                    refreshStateTextView.Text = "刷新成功";
                    refreshStateImageView.SetBackgroundResource(Resource.Mipmap.refresh_succeed);                    break;                case 1:                default:                    // 刷新失敗
                    refreshStateImageView.Visibility = ViewStates.Visible;
                    refreshStateTextView.Text = "刷新失敗";
                    refreshStateImageView.SetBackgroundResource(Resource.Mipmap.refresh_failed);                    break;
            }            if (pullDownY > 0)
            {                // 刷新結(jié)果停留1秒
                new Handler((Message msg) =>
                {
                    changeStatus(complete);
                    hide();
                }).SendEmptyMessageDelayed(0, 1000);
            }            else
            {
                changeStatus(complete);
                hide();
            }
        }        /// <summary>
        /// 加載完畢,顯示加載結(jié)果。注意:刷新完成后一定要調(diào)用這個(gè)方法        /// </summary>
        /// <param name="refreshResult">succeed代表成功, failed代表失敗</param>
        public void loadmoreFinish(int refreshResult)
        {
            loadingView.ClearAnimation();
            loadingView.Visibility = ViewStates.Gone;            switch (refreshResult)
            {                case 0:                    // 加載成功
                    loadStateImageView.Visibility = ViewStates.Visible;
                    loadStateTextView.Text = "加載成功";
                    loadStateImageView.SetBackgroundResource(Resource.Mipmap.load_succeed);                    break;                case 1:                default:                    // 加載失敗
                    loadStateImageView.Visibility = ViewStates.Visible;
                    loadStateTextView.Text = "加載失敗";
                    loadStateImageView.SetBackgroundResource(Resource.Mipmap.load_failed);
                    pullableView.Visibility = ViewStates.Gone;                    break;
            }            if (pullUpY < 0)
            {                // 刷新結(jié)果停留1秒
                new Handler((Message msg) =>
                {
                    changeStatus(complete);
                    hide();
                }).SendEmptyMessageDelayed(0, 1000);
            }            else
            {
                changeStatus(complete);
                hide();
            }
        }        /// <summary>
             break;