我一次性为 Wanandroid 开发了Java与Kotlin两个版本

1. 介绍

最近基于 Wanandroid开放API 开发了一款十分简单的APP,, 采用 Androidx + MVVM + Retrofit + dataBinding 的模式进行开发。App的主要功能是就是浏览各类 Android 文章,效果图如下所示:

1.1 功能效果图展示

主页项目微信公众号知识体系
文章详情我的注册导航

1.2 项目设计模式

该项目采用 MVVM 的开发模式,关于 MVVM 开发模式,可以参考:美团 如何构建Android MVVM 应用框架 ,如果你觉得不易理解,可以参考一下 Android MVC MVP MVVM简单例子

MVVM 的经典架构图:
MVVM的经典架构图
项目中的架构图为:
项目架构图

2. 代码解析

举个例子:比如我们的主页,有 banner广告图以及首页文章,如下所示:

主页
所以要实现这样的功能,我们需要为 HomeFragment 创建 HomeViewModel、HomeRepository、HomeBeanFiles,如下所示:
主页功能实现架构图
具体代码见:Wanandroid_Learning

HomeFragment.java

public class HomeFragment extends Fragment {
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //创建 ViewModel
        HomeViewModel homeVm = ViewModelProviders.of(this, new ViewModelFactory()).get(HomeViewModel.class);
        //观察 banner data
        homeVm.getHomeBannerListLd().observe(getViewLifecycleOwner(), bannerListDataObserver);
        homeVm.setHomeBannerListLd();
        //观察 Article data
        homeVm.getHomeArticleListBeanLd().observe(getViewLifecycleOwner(), articleListBeanObserver);
        homeVm.setHomeArticleListBeanLd();
    }

    ···略···
}

HomeViewModel.java

public class HomeViewModel extends ViewModel {
    private static final String TAG = "HomeViewModel";
    private MutableLiveData<HomeBannerListBean> homeBannerListLd;
    private MutableLiveData<HomeArticleListBean> homeArticleListBeanLd;

    public HomeViewModel() {
        this.homeBannerListLd = new MutableLiveData<>();
        this.homeArticleListBeanLd = new MutableLiveData<>();
    }

    public MutableLiveData<HomeBannerListBean> getHomeBannerListLd() {
        return homeBannerListLd;
    }

    public void setHomeBannerListLd() {
        HomeRepository.newInstance().getHomeBannerList(new GetWebDataListener() {
            @Override
            public void getDataSuccess(Object object) {
                HomeBannerListBean homeBannerListBean = (HomeBannerListBean) object;
                homeBannerListLd.postValue(homeBannerListBean);
            }

            @Override
            public void getDataFailed(String failedMsg) {
                Log.e(TAG, "getDataFailed: " + failedMsg);
            }
        });
    }

    public MutableLiveData<HomeArticleListBean> getHomeArticleListBeanLd() {
        return homeArticleListBeanLd;
    }

    public void setHomeArticleListBeanLd() {
        HomeRepository.newInstance().getHomeArticleList(0, new GetWebDataListener() {
            @Override
            public void getDataSuccess(Object object) {
                HomeArticleListBean homeArticleListBean = (HomeArticleListBean) object;
                homeArticleListBeanLd.postValue(homeArticleListBean);
            }

            @Override
            public void getDataFailed(String failedMsg) {
                Log.e(TAG, "getDataFailed: " + failedMsg);
            }
        });
    }
}

HomeRepository.java

public class HomeRepository {
    /**
     * 为了防止出现DCL失效问题,所以用 volatile 关键字来修饰 instance。
     */
    private volatile static HomeRepository instance;

    public static HomeRepository newInstance() {
        if (instance == null) {
            synchronized (HomeRepository.class) {
                if (instance == null) {
                    instance = new HomeRepository();
                }
            }
        }
        return instance;
    }

    public void getHomeBannerList(final GetWebDataListener listener) {
        ApiService apiService = ApiWrapper.getRetrofitInstance().create(ApiService.class);
        apiService.getHomeBannerList().enqueue(new AbstractRetrofitCallback() {
            @Override
            public void getSuccessful(String responseBody) {
                Gson gson = new Gson();
                HomeBannerListBean homeBannerListBean = gson.fromJson(responseBody, HomeBannerListBean.class);
                listener.getDataSuccess(homeBannerListBean);
            }

            @Override
            public void getFailed(String failedMsg) {
                listener.getDataFailed(failedMsg);
            }
        });
    }

    public void getHomeArticleList(int pageNumber, final GetWebDataListener listener) {
        ApiService apiService = ApiWrapper.getRetrofitInstance().create(ApiService.class);
        apiService.getHomeArticleList(pageNumber).enqueue(new AbstractRetrofitCallback() {
            @Override
            public void getSuccessful(String responseBody) {
                Gson gson = new Gson();
                HomeArticleListBean homeArticleListBean = gson.fromJson(responseBody, HomeArticleListBean.class);
                listener.getDataSuccess(homeArticleListBean);
            }

            @Override
            public void getFailed(String failedMsg) {
                listener.getDataFailed(failedMsg);
            }
        });
    }

}

具体代码见:Wanandroid_Learning

3. Kotlin 版本

同时,为了学习 Kotlin,我也开发了 Kotlin 版本,也是采用MVVM的开发模式,具体代码见:Wanandroid_Learning_Kotlin

项目效果截图展示

主页项目微信公众号知识体系
文章详情我的登入导航

再次说明: 该项目的 API 都是来自泓洋老师的 Wanandroid开放API ,再次感谢泓洋老师的开源分享。

4. Flutter 版本

现在 Flutter 版本也开发完毕了,具体看我的另一篇博客 Wanandroid Flutter 版本

效果展示:
在这里插入图片描述

其实分享文章的最大目的正是等待着有人指出我的错误,如果你发现哪里有错误,请毫无保留的指出即可,虚心请教。

欢迎一起学习讨论,peace~

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值