Android 灵活切换下拉刷新(策略模式+反射)

Posted 大雄童鞋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 灵活切换下拉刷新(策略模式+反射)相关的知识,希望对你有一定的参考价值。

最近想换下拉刷新了,但是不想舍弃以前的,就想能不能两个都并存,在使用之前配置一下,配置A就使用A,配置B就使用B。(原理就是通过反射来控制使用相应的策略)
使用很简单,只需要修改模式类型就可以直接切换下拉刷新的模式了:

//模式一
private int refreshMode = RefreshContext.SWIPE_REFRESH;
//模式二
private int refreshMode = RefreshContext.PTR_REFRESH;


下面开始改造吧

1、定义接口

public interface IRefresh 
    void onRefresh(AppCompatActivity activity, OnRefreshListener onRefreshListener);
 //自动刷新
    void autoRefresh();
  //刷新完成
    void onRefreshComplete();

2、定义注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Mode 
    int value() default RefreshContext.SWIPE_REFESH;

3、定义供外部调用的回调

public interface OnRefreshListener 
    void onRefresh();

4、具体的实现类(有几个刷新模式就定义几个,这里是2个)

@Mode(RefreshContext.SWIPE_REFRESH)
public class SwipeRefresh implements IRefresh 

    private SwipeRefreshLayoutFinal swipeRefreshLayoutFinal;

    @Override
    public void onRefresh(AppCompatActivity activity, final OnRefreshListener onRefreshListener) 
        //activity.setContentView(R.layout.layout_swipe);
        swipeRefreshLayoutFinal = (SwipeRefreshLayoutFinal) activity.findViewById(R.id.swl_layout);
        swipeRefreshLayoutFinal.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() 
            @Override
            public void onRefresh() 
                if (null != onRefreshListener) 
                    onRefreshListener.onRefresh();
                
            
        );
    

    @Override
    public void autoRefresh() 
        swipeRefreshLayoutFinal.autoRefresh();
    

    @Override
    public void onRefreshComplete() 
        swipeRefreshLayoutFinal.onRefreshComplete();
    
@Mode(RefreshContext.PTR_REFRESH)
public class PtrRefresh implements IRefresh 

    private PtrClassicFrameLayout ptrClassicFrameLayout;

    @Override
    public void onRefresh(AppCompatActivity activity, final OnRefreshListener onRefreshListener) 
        ptrClassicFrameLayout = (PtrClassicFrameLayout) activity.findViewById(R.id.ptr_rv_layout);
        setHeaderView(activity, ptrClassicFrameLayout);
        ptrClassicFrameLayout.setLastUpdateTimeRelateObject(this);
        ptrClassicFrameLayout.disableWhenHorizontalMove(true);
        ptrClassicFrameLayout.setOnRefreshListener(new OnDefaultRefreshListener() 
            @Override
            public void onRefreshBegin(PtrFrameLayout frame) 
                if (null != onRefreshListener) 
                    onRefreshListener.onRefresh();
                
            
        );
    

    @Override
    public void autoRefresh() 
        ptrClassicFrameLayout.autoRefresh();
    

    @Override
    public void onRefreshComplete() 
        ptrClassicFrameLayout.onRefreshComplete();
    

    private void setHeaderView(AppCompatActivity activity, PtrClassicFrameLayout ptrRvLayout) 
        StoreHouseHeader header = new StoreHouseHeader(activity);
        header.setPadding(0, (int) ScreenUtils.dpToPxInt(activity, 20), 0, (int) ScreenUtils.dpToPxInt(activity, 10));
        header.setTextColor(activity.getResources().getColor(R.color.colorPrimary));
        header.initWithString("LOADING", 20);
        ptrRvLayout.setLoadingMinTime(1000);
        ptrRvLayout.setDurationToClose(50);
        ptrRvLayout.setDurationToCloseHeader(1000);
        ptrRvLayout.setHeaderView(header);
        ptrRvLayout.addPtrUIHandler(header);
    

5、上下文

public class RefreshContext 

    public static final int SWIPE_REFRESH = 1;
    public static final int PTR_REFRESH = 2;

    private int refreshMode;
    private OnRefreshListener onRefreshListener;

    private List<Class<? extends IRefresh>> refreshList;
    private IRefresh iRefresh;
    private final WeakReference<AppCompatActivity> weakReference;

    public RefreshContext(AppCompatActivity activity, int refreshMode) 

        weakReference = new WeakReference<>(activity);
        this.refreshMode = refreshMode;
    


    public void setOnRefreshListener(OnRefreshListener onRefreshListener) 
        this.onRefreshListener = onRefreshListener;
        init();
    

    //自动刷新
    public void autoRefresh() 
        iRefresh.autoRefresh();

    
    //刷新完成
    public void onRefreshComplete() 
        iRefresh.onRefreshComplete();
    

//------------------------------反射获取注解-----------------------------------

    private void init() 
        refreshList = new ArrayList<>();

        try 
            String packageName = getClass().getPackage().getName();
            Class<?> getRequestParams = Class.forName(packageName + ".PtrRefresh");
            Class<?> postRequestParams = Class.forName(packageName + ".SwipeRefresh");
            List<Class<?>> classList = new ArrayList<>();
            classList.add(getRequestParams);
            classList.add(postRequestParams);

            for (int i = 0; i < classList.size(); i++) 
                Class<?> clazz = classList.get(i);
                //判断clazz是否是IRequestParam的实现类
                if (IRefresh.class.isAssignableFrom(clazz)) 
                    refreshList.add((Class<? extends IRefresh>) clazz);
                
            


         catch (ClassNotFoundException e) 
            e.printStackTrace();
        
        iRefresh = chooseRequest(refreshMode);
        AppCompatActivity activity = weakReference.get();
        if (null != activity) 
            iRefresh.onRefresh(activity, onRefreshListener);
        
    


    //根据返回的method产生相应的方法
    public IRefresh chooseRequest(int refreshMode) 

        //在策略列表中查找策略
        for (Class<? extends IRefresh> clazz : refreshList) 
            //获取该策略的注解
            Mode method = clazz.getAnnotation(Mode.class);
            if (refreshMode == method.value()) 
                try 
                    return clazz.newInstance();
                 catch (Exception e) 
                    throw new RuntimeException("策略获得失败");
                
            
        

        throw new RuntimeException("策略获得失败");
    



最后,客户端调用

package com.zx.rxjava;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;

import com.zhy.adapter.recyclerview.CommonAdapter;
import com.zhy.adapter.recyclerview.base.ViewHolder;
import com.zx.rxjava.bean.Vip;
import com.zx.rxjava.refresh.OnRefreshListener;
import com.zx.rxjava.refresh.RefreshContext;
import com.zx.rxjava.service.RetrofitService;
import com.zx.rxjava.tools.ListUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import cn.finalteam.loadingviewfinal.OnLoadMoreListener;
import cn.finalteam.loadingviewfinal.RecyclerViewFinal;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

public class VipListActivity extends AppCompatActivity 

    private RefreshContext refreshContext;
    private int mPage = 1;
    private RecyclerViewFinal mRvList;
    private List<Vip> mVipList = new ArrayList<>();
    private CommonAdapter mCommonAdapter;

    public static final int PAGE_SIZE = 20;

    HashMap<Integer, Integer> modeList = new HashMap<>();
    private int refreshMode = RefreshContext.PTR_REFRESH;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        initRefresh();
        setContentView(modeList.get(refreshMode));
        initView();
    

    private void initRefresh() 
        refreshContext = new RefreshContext(this, refreshMode);
        modeList.put(RefreshContext.PTR_REFRESH, R.layout.layout_ptr);
        modeList.put(RefreshContext.SWIPE_REFRESH, R.layout.layout_swipe);
    

    private void initView() 
        mRvList = (RecyclerViewFinal) findViewById(R.id.rv_list);
        mRvList.setLayoutManager(new LinearLayoutManager(this));
        mCommonAdapter = new CommonAdapter<Vip>(this, R.layout.listitem_vip, mVipList) 
            @Override
            protected void convert(ViewHolder holder, Vip vip, int position) 
                holder.setText(R.id.tv_name, vip.getCustomerName());
            

        ;
        mRvList.setAdapter(mCommonAdapter);
        refreshContext.setOnRefreshListener(new OnRefreshListener() 
            @Override
            public void onRefresh() 
                request(1);
            
        );
        refreshContext.autoRefresh();

        mRvList.setOnLoadMoreListener(new OnLoadMoreListener() 
            @Override
            public void loadMore() 
                request(mPage);
            
        );
    


    private void request(final int page) 
        Retrofit retrofit = AppClient.retrofit(getApplicationContext());
        RetrofitService retrofitService = retrofit.create(RetrofitService.class);
        HashMap<String, Object> map = new HashMap<>();
        map.put("pageSize", PAGE_SIZE);
        map.put("pageNum", page);

        Call<GetVipListRespons> call = retrofitService.getVipListBody(map);
        call.enqueue(new Callback<GetVipListRespons>() 
            @Override
            public void onResponse(Call<GetVipListRespons> call, Response<GetVipListRespons> response) 
                List<Vip> vipList = response.body().getData().getRows();

                if (ListUtils.isEmpty(vipList)) 
                    vipList = new ArrayList<>();
                
                if (page == 1) 
                    mVipList.clear();
                
                mPage = page + 1;
                mVipList.addAll(vipList);
                mRvList.setHasLoadMore(vipList.size() < PAGE_SIZE ? false : true);
                mCommonAdapter.notifyDataSetChanged();
                refreshContext.onRefreshComplete();
                mRvList.onLoadMoreComplete();

            

            @Override
            public void onFailure(Call<GetVipListRespons> call, Throwable t) 

            
        );
    

代码很简单,不多解释了,把refreshContext当做下拉刷新的View来用就好了。

附:使用到的开源项目

https://github.com/hongyangAndroid/baseAdapter
https://github.com/pengjianbo/LoadingViewFinal

以上是关于Android 灵活切换下拉刷新(策略模式+反射)的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Android之下拉刷新

Java中的“反射泛型容器”你了解多少?

android性能测试

策略模式

Android 下拉列表Spinner

iOS11+Xcode9适配踩坑大全(下拉刷新,编译错误, Swift第三方等)