Android LCE架构设计

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z2464342708m/article/details/79037006

Android LCE架构设计

LCE架构,按拆字法解析:L:Loading加载,C:Content加载内容,E:Error加载失败。
LCE架构使用最为常见的场景是做列表数据的加载,在加载时,如果隔壁老王占用了你的带宽,那么数据加载会变的很慢,为了不让用户觉得等待漫长,可以出现一个加载场景;当数据加载成功时,将数据显示在UI上;如果数据加载失败,可以显示一个加载失败的页面或者图片,这就是LCE的使用场景。
根据上面的需求分析,可以大概的了解到LCE需要的组成部分:动画,场景体现(不同场景的UI显示)。动画主要在三个方便体现:加载中,加载成功,加载失败。场景体现主要有五个方面的体现:显示loading,显示数据内容,显示加载失败,加载数据和绑定数据。那么久先来定义两个接口:
动画接口:

public interface ILceAnimator {
    void showLoading(View loadingView, View contentView, View errorView);

    void showErrorView(View loadingView, View contentView, View errorView);

    void showContent(View loadingView, View contentView, View errorView);
}

场景接口:

public interface LceView<M> extends IView {

    /**
     * 显示loading页面 pullToRefresh:true代表你用的是下拉刷新组件
     * 
     * @param pullToRefresh
     */
    void showLoading(boolean pullToRefresh);

    /**
     * 显示ContentView
     */
    void showContent();

    /**
     * 显示异常界面
     */
    void showError();

    /**
     * 绑定数据
     * 
     * @param data
     */
    void bindData(M data);

    /**
     * 加载数据
     *
     * @param pullToRefresh
     */
    void loadData(boolean pullToRefresh);

}

为了方便使用,可以提供一个默认的动画和场景实现。
默认的LCE场景实现:

public class LceViewImpl<M> implements LceView<M> {

    private View loadingView;
    private View contentView;
    private View errorView;

    private ILceAnimator lceAnimator;

    /**
     * 初始化视图
     * 
     * @param v
     */
    public void initLceView(View v) {
        if (loadingView == null) {
            loadingView = v.findViewById(R.id.loadingView);
        }
        if (contentView == null) {
            contentView = v.findViewById(R.id.contentView);
        }
        if (errorView == null) {
            errorView = v.findViewById(R.id.errorView);
        }
        if (loadingView == null) {
            throw new NullPointerException("loadingView is not null!");
        }
        if (contentView == null) {
            throw new NullPointerException("contentView is not null!");
        }
        if (errorView == null) {
            throw new NullPointerException("errorView is not null!");
        }
    }

    /**
     * 添加重写加载监听
     * 
     * @param onClickListener
     */
    public void setOnErrorViewClickListener(OnClickListener onClickListener) {
        if (this.errorView != null) {
            this.errorView.setOnClickListener(onClickListener);
        }
    }

    private ILceAnimator getLceAnimator() {
        if (lceAnimator == null) {
            lceAnimator = DefaultLceAnimator.getInstance();
        }
        return lceAnimator;
    }

    /**
     * 绑定动画执行策略
     * 
     * @param lceAnimator
     */
    public void setLceAnimator(ILceAnimator lceAnimator) {
        this.lceAnimator = lceAnimator;
    }

    /**
     * 注意:记得加判断,因为下拉刷新组件有正在加载头部视图,不需要显示加载过程了
     * @param pullToRefresh
     */
    @Override
    public void showLoading(boolean pullToRefresh) {
        if(!pullToRefresh){
            getLceAnimator().showLoading(loadingView, contentView, errorView);
        }
    }

    @Override
    public void showContent() {
        getLceAnimator().showContent(loadingView, contentView, errorView);
    }

    @Override
    public void showError() {
        getLceAnimator().showErrorView(loadingView, contentView, errorView);
    }

    @Override
    public void bindData(M data) {

    }

    @Override
    public void loadData(boolean pullToRefresh) {

    }

}

默认的动画实现:

@SuppressLint("NewApi")
public class DefaultLceAnimator implements ILceAnimator {

    private volatile static DefaultLceAnimator lceAnimator;

    public DefaultLceAnimator() {
    }

    public static DefaultLceAnimator getInstance() {
        if (lceAnimator == null) {
            synchronized (AnimatorUtils.class) {
                if (lceAnimator == null) {
                    lceAnimator = new DefaultLceAnimator();
                }
            }
        }
        return lceAnimator;
    }

    @Override
    public void showLoading(View loadingView, View contentView, View errorView) {
        contentView.setVisibility(View.GONE);
        errorView.setVisibility(View.GONE);
        loadingView.setVisibility(View.VISIBLE);
    }

    @Override
    public void showErrorView(final View loadingView,final View contentView,final View errorView) {
        contentView.setVisibility(View.GONE);

        final Resources resources = loadingView.getResources();
        // Not visible yet, so animate the view in
        AnimatorSet set = new AnimatorSet();
        ObjectAnimator in = ObjectAnimator.ofFloat(errorView, "alpha", 1f);
        ObjectAnimator loadingOut = ObjectAnimator.ofFloat(loadingView,
                "alpha", 0f);

        set.playTogether(in, loadingOut);
        set.setDuration(resources
                .getInteger(R.integer.lce_error_view_show_animation_time));

        set.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                errorView.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                loadingView.setVisibility(View.GONE);
                loadingView.setAlpha(1f); // For future showLoading calls
            }
        });

        set.start();
    }

    @Override
    public void showContent(final View loadingView,final View contentView,final View errorView) {
        if (contentView.getVisibility() == View.VISIBLE) {
            errorView.setVisibility(View.GONE);
            loadingView.setVisibility(View.GONE);
        } else {

            errorView.setVisibility(View.GONE);

            final Resources resources = loadingView.getResources();
            final int translateInPixels = resources
                    .getDimensionPixelSize(R.dimen.lce_content_view_animation_translate_y);
            // Not visible yet, so animate the view in
            AnimatorSet set = new AnimatorSet();
            ObjectAnimator contentFadeIn = ObjectAnimator.ofFloat(contentView,
                    "alpha", 0f, 1f);
            ObjectAnimator contentTranslateIn = ObjectAnimator.ofFloat(
                    contentView, "translationY", translateInPixels, 0);

            ObjectAnimator loadingFadeOut = ObjectAnimator.ofFloat(loadingView,
                    "alpha", 1f, 0f);
            ObjectAnimator loadingTranslateOut = ObjectAnimator.ofFloat(
                    loadingView, "translationY", 0, -translateInPixels);

            set.playTogether(contentFadeIn, contentTranslateIn, loadingFadeOut,
                    loadingTranslateOut);
            set.setDuration(resources
                    .getInteger(R.integer.lce_content_view_show_animation_time));

            set.addListener(new AnimatorListenerAdapter() {

                @Override
                public void onAnimationStart(Animator animation) {
                    contentView.setTranslationY(0);
                    loadingView.setTranslationY(0);
                    contentView.setVisibility(View.VISIBLE);
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    loadingView.setVisibility(View.GONE);
                    loadingView.setAlpha(1f); // For future showLoading calls
                    contentView.setTranslationY(0);
                    loadingView.setTranslationY(0);
                }
            });

            set.start();
        }
    }

}

在集成LCE的时候,如果没有提供自定的实现,那么就是用默认的实现。
Fragment LCE集成实现:

public abstract class LceFragment<M> extends Fragment implements LceView<M> {

    // 初始化Lce UI布局(规定你的Lce布局文件的id)
    private LceViewImpl<M> lceViewImpl;

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (lceViewImpl == null) {
            lceViewImpl = new MvpLceViewImpl<M>();
        }
        initLceView(view);
    }

    private void initLceView(View v) {
        lceViewImpl.initLceView(v);
        lceViewImpl.setOnErrorViewClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                onErrorClick();
            }
        });
    }

    public void setLceAnimator(ILceAnimator lceAnimator){
        lceViewImpl.setLceAnimator(lceAnimator);
    }

    @Override
    public void showLoading(boolean pullToRefresh) {
        lceViewImpl.showLoading(pullToRefresh);
    }

    @Override
    public void showContent() {
        lceViewImpl.showContent();
    }

    @Override
    public void showError() {
        lceViewImpl.showError();
    }

    @Override
    public void loadData(boolean pullToRefresh) {
        lceViewImpl.loadData(pullToRefresh);
    }

    @Override
    public void bindData(M data) {
        lceViewImpl.bindData(data);
    }

    public void onErrorClick() {
        loadData(false);
    }

}

当然也可以将LCE集成到Activity中。

猜你喜欢

转载自blog.csdn.net/z2464342708m/article/details/79037006