重构(一)

重构的原因:

代码拓展困难,重复代码多,逻辑复杂,不容易理解,在持续迭代的项目开发中可测试性丧失。

重构的目的;

显然就是解决上述的问题


目前在项目中遇到的一个案例;

项目中用到一个开源控件PullToRefresh,在版本迭代中,使用方式是需要调用的页面直接在布局文件中直接调用,然后在Actvity和fragment中获取这个View,设置监听等。

引起的问题;

在布局中需要重复的定义一些属性,在代码中需要重复的设置监听,最重要的是,此开源控件已经不能满足项目的需要,需要替换成新的合适的PullToRefresh开源控件,这将导致修改大量的代码和布局文件。

解决的思路

1.首先要总结出一套PullToRefresh的共同特性

2.将这些特性使用一套接口封装起来,然后使用一个Impl类来实现它,代码中只需要调用这些接口,而不需要关心具体的实现类。

3.以后若再需要替换新的控件,只需要修改Impl类,还有一些其他的少量代码,这是重构的目标。



PullToRefresh的特性:支持上拉和下拉刷新,支持手动停止刷新,支持设置刷新的模式(未来还需要支持自动刷新)

支持常用的三个控件:ListView,ScrollView,GridView,需要封装这三种类型的View,以便在布局中直接引用,以后若需要替换新的开源控件,则可针对此三个自定义的View操作,而不需要修改调用的布局。

拓展:封装 fragment和activity,只需要少量的代码即可使用PullToRefresh,简化代码。


PtrBase接口:设置监听,设置刷新模式,获取刷新的view,获取包装刷新的View

import android.view.View;

/**
 * Created by whuthm on 2015/12/2.
 */
public interface PtrBase {
    
    void setPtrMode(PtrMode mode);
    
    void setOnRefreshListener(OnRefreshListener l);
    
    View getRefreshableView();
    
    View getRefreshableViewWrapper();
    
    void finishRefresh(boolean success);

    public enum PtrMode {
        DISABLED, PULL_FROM_START, PULL_FROM_END, BOTH
    }
    
}

OnRefreshListener:下拉或者上拉刷新监听

package com.whuthm.base.view.ptr;

/**
 * Created by whuthm on 2015/12/2.
 */
public interface OnRefreshListener {

    public void onRefreshFromStart();

    public void onRefreshFromEnd();
}


PtrBaseView:针对View定义的接口,获取PtrBase

package com.whuthm.base.view.ptr;

/**
 * Created by whuthm on 2015/12/2.
 */
public interface PtrBaseView {

    PtrBase getPtrBase();
}

PtrBaseImpl:具体的实现类,和第三方控件具体关联的地方,方便替换新的控件

import android.content.Context;
import android.text.format.DateUtils;
import android.view.View;
import android.widget.LinearLayout;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.whutm.base.NetworkTime;

/**
 * Created by whuthm on 2015/12/2.
 */
class PtrBaseImpl implements PtrBase {
    
    PullToRefreshBase mPullToRefreshBase;
    
    long mLastUpdateTime;
    
    OnRefreshListener mOnRefreshListener;
    
    PtrBaseImpl(PullToRefreshBase pullToRefreshBase) {
        mPullToRefreshBase = pullToRefreshBase;
        mPullToRefreshBase.setOrientation(LinearLayout.VERTICAL);
        mLastUpdateTime = NetworkTime.currentTimeMillis();
        mPullToRefreshBase.setPullToRefreshOverScrollEnabled(false);
        mPullToRefreshBase
                .setOnRefreshListener(new PullToRefreshBase.OnRefreshListener() {
                    @Override
                    public void onRefresh(PullToRefreshBase refreshView) {
                        final Context context = refreshView.getContext();
                        String label = DateUtils.formatDateTime(context, mLastUpdateTime,
                                DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_TIME
                                        | DateUtils.FORMAT_SHOW_DATE
                                        | DateUtils.FORMAT_ABBREV_ALL);
                        
                        // Update the LastUpdatedLabel
                        refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(
                                context.getString(R.string.last_update_time_text, label));
                        PullToRefreshBase.Mode curMode = refreshView.getCurrentMode();
                        if (curMode == PullToRefreshBase.Mode.PULL_FROM_START) {
                            if (mOnRefreshListener != null) {
                                mOnRefreshListener.onRefreshFromStart();
                            }
                        }
                        else if (curMode == PullToRefreshBase.Mode.PULL_FROM_END) {
                            if (mOnRefreshListener != null) {
                                mOnRefreshListener.onRefreshFromEnd();
                            }
                        }
                    }
                });
    }
    
    @Override
    public void setPtrMode(PtrMode mode) {
        mPullToRefreshBase.setMode(getMode(mode));
    }
    
    @Override
    public void setOnRefreshListener(OnRefreshListener l) {
        mOnRefreshListener = l;
    }
    
    @Override
    public View getRefreshableView() {
        return mPullToRefreshBase.getRefreshableView();
    }
    
    @Override
    public View getRefreshableViewWrapper() {
        return mPullToRefreshBase;
    }
    
    @Override
    public void finishRefresh(boolean success) {
        if (success) {
            mLastUpdateTime = NetworkTime.currentTimeMillis();
        }
        mPullToRefreshBase.onRefreshComplete();
    }
    
    private static PullToRefreshBase.Mode getMode(PtrMode mode) {
        switch (mode) {
            case DISABLED:
                return PullToRefreshBase.Mode.DISABLED;
            case PULL_FROM_END:
                return PullToRefreshBase.Mode.PULL_FROM_END;
            case BOTH:
                return PullToRefreshBase.Mode.BOTH;
            case PULL_FROM_START:
            default:
                return PullToRefreshBase.Mode.PULL_FROM_START;
        }
    }
}

PtrListView:供布局中使用,此处也和第三方控件关联,而且定义一个PtrBase

package com.whuthm.base.view.ptr;

import android.content.Context;
import android.util.AttributeSet;

import com.handmark.pulltorefresh.library.PullToRefreshListView;

/**
 * Created by whuthm on 2015/12/2.
 */
public class PtrListView extends PullToRefreshListView implements PtrBaseView{

    private PtrBase mPtrBase;

    public PtrListView(Context context) {
        this(context, null);
    }

    public PtrListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPtrBase = new PtrBaseImpl(this);
    }

    @Override
    public PtrBase getPtrBase() {
        return mPtrBase;
    }
}

PtrScrollView

package com.whuthm.base.view.ptr;

import android.content.Context;
import android.util.AttributeSet;
import com.whuthm.base.R;

/**
 * Created by whuthm on 2015/11/19.
 */
public class PtrScrollView extends
        com.handmark.pulltorefresh.library.PullToRefreshScrollView implements PtrBaseView {
    
    private int mMaximumPullScroll;

    private PtrBase mPtrBase;
    
    public PtrScrollView(Context context) {
        this(context, null);
    }
    
    public PtrScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPtrBase = new PtrBaseImpl(this);
    }
    
    @Override
    protected int getMaximumPullScroll() {
        if (mMaximumPullScroll <= 0) {
            mMaximumPullScroll = getResources().getDimensionPixelSize(
                    R.dimen.maximum_default_pull_scroll);
        }
        return mMaximumPullScroll;
    }

    @Override
    public PtrBase getPtrBase() {
        return mPtrBase;
    }
}


PtrGridView

package com.whuthm.base.view.ptr;

import android.content.Context;
import android.util.AttributeSet;

import com.handmark.pulltorefresh.library.PullToRefreshGridView;

/**
 * Created by whuthm on 2015/12/2.
 */
public class PtrGridView extends PullToRefreshGridView implements PtrBaseView{

    private PtrBase mPtrBase;

    public PtrGridView(Context context) {
        this(context, null);
    }

    public PtrGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPtrBase = new PtrBaseImpl(this);
    }

    @Override
    public PtrBase getPtrBase() {
        return mPtrBase;
    }
}

若需要引用新的控件,只需要具体 修改PtrBaseImpl或者创建新的实现类,少量修改PtrListView三个控件。


使用方式

在布局中引用后,在Activity中  PtrBaseView view = (PtrBaseView) findViewById(R.id.ptr_list);

然后就可获得PtrBase,通过PtrBase设置监听,设置刷新模式,控制手动停止,获取具体的刷新view,操作简化


待拓展;进一步简化代码,封装到fragment或者activity,每次使用时直接用,不需要获取和设置监听

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值