Android-MVP+Retrofit+Rxjava实现一个知乎日报客户端
来源:互联网 发布:四维设计软件 编辑:程序博客网 时间:2024/06/05 09:34
使用MVP+Retrofit+Rxjava实现一个知乎日报客户端,界面基于Material design,还没有全部完成orz,,放假太懒
效果图
开源项目
使用Material Design
可以参考我的另外一篇文章Android-Material Design的使用
列表使用的为recyclerView,这个就不解释了
tabs标题栏的实现采用了开源项目neokree/MaterialTabs
需和ViewPager一起使用。在ViewPager中添加Fragment
Activity需要 implements MaterialTabListener
fragmentList = new ArrayList<>(); fragmentList.add(new NewsFragment()); fragmentList.add(new TestFragment()); fragmentList.add(new TestFragment()); tabHost = (MaterialTabHost) this.findViewById(R.id.materialTabHost); pager = (ViewPager) this.findViewById(R.id.viewpager); // init view pager fragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), fragmentList); pager.setAdapter(fragmentPagerAdapter); pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { // when user do a swipe the selected tab change tabHost.setSelectedNavigationItem(position); } }); // insert all tabs from pagerAdapter data List<String> tabsNames = new ArrayList<>(); tabsNames.add("zhihu"); tabsNames.add("schedule"); tabsNames.add("timeTable"); for (int i = 0; i < fragmentPagerAdapter.getCount(); i++) { tabHost.addTab( tabHost.newTab() .setText(tabsNames.get(i)) .setTabListener(this) ); }
点击fab出现日历来选择时间,用来查询过往的日报
日历的实现来自wdullaer/MaterialDateTimePicker
返回的日期需要格式化,使用在知乎日报的API中
String date = String.format("%d%02d%02d", year, monthOfYear + 1, dayOfMonth);
知乎日报的数据
来自知乎日报 API 分析
最新消息
URL: http://news-at.zhihu.com/api/4/news/latest
过往消息
URL: http://news-at.zhihu.com/api/4/news/before/20131119
响应为
{ date: "20140523", stories: [ { title: "中国古代家具发展到今天有两个高峰,一个两宋一个明末(多图)", ga_prefix: "052321", images: [ "http://p1.zhimg.com/45/b9/45b9f057fc1957ed2c946814342c0f02.jpg" ], type: 0, id: 3930445 }, ... ], ...}
消息内容获取与离线下载
URL: http://news-at.zhihu.com/api/4/news/{id}
利用Android studio的插件GsonFormat,来解析返回的json数据
MVP+Retrofit+Rxjava
MVP
可以参考
java-mvp模式简单实现
浅谈Andorid开发中的MVP模式
Retrofit
Android网络请求库 - Say hello to retrofit
RxJava 与 Retrofit 结合的最佳实践
Rxjava
给 Android 开发者的 RxJava 详解
定义接口
public interface ZhiHuService { @GET("api/4/news/latest") Observable<LatestNews> getLatestNews(); @GET("api/4/news/before/{date}") Observable<LatestNews> getBeforeNews(@Path("date") String dateString); @GET("api/4/news/{id}") Observable<News> getNews(@Path("id") int id); @GET("api/4/story/{id}/long-comments") Observable<Comment> getComments(@Path("id") int id); @GET("api/4/story-extra/{id}") Observable<StoryExtra> getStroyExtra(@Path("id") int id);}
基础url
public class Config { public final static String ZHIHU_URL = "http://news-at.zhihu.com/";}
进行封装
public class ZhiHuApi { private static final int DEFAULT_TIMEOUT = 5; private ZhiHuService zhiHuService; private static ZhiHuApi zhiHuApi; private Retrofit retrofit; private ZhiHuApi() { //设置超时时间 OkHttpClient.Builder httpcientBuilder = new OkHttpClient.Builder(); Retrofit retrofit = new Retrofit.Builder() .client(httpcientBuilder.build())// .baseUrl(Config.ZHIHU_URL) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); zhiHuService = retrofit.create(ZhiHuService.class); } public static ZhiHuApi getInstance(){ if (zhiHuApi == null) { synchronized (ZhiHuApi.class){ if (zhiHuApi == null){ zhiHuApi = new ZhiHuApi(); } } } return zhiHuApi; } public void getLatestNews(Subscriber<LatestNews> subscriber){ zhiHuService.getLatestNews() .subscribeOn(Schedulers.io()) .unsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(subscriber); }...}
把列表的界面作为例子
定义Contract接口
public interface NewsContract { interface View{ void refreshRecyclerVew(List<LatestNews.StoriesBean> storiesList); } interface Presenter{ void getBeforeNews(String date); void getLatestNews(); } interface model{ void getBeforeNews(CallBackLatestNews callback, String date); void getLatestNews(CallBackLatestNews callback); }}
View层
public class NewsFragment extends Fragment implements NewsContract.View, DatePickerDialog.OnDateSetListener { private static final String TAG = "NewsFragment"; RecyclerView recyclerView; private NewsContract.Presenter presenter; public NewsFragment() { presenter = new NewsPresenter(this); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_zhihu_daily, container, false); FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fab); fab.setImageResource(R.drawable.add); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //显示日历选项 Calendar now = Calendar.getInstance(); DatePickerDialog dpd = DatePickerDialog.newInstance( NewsFragment.this, now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH) ); dpd.show(getActivity().getFragmentManager(), "Datepickerdialog"); } }); recyclerView = (RecyclerView) view.findViewById(R.id.latest_news_recyclerview); //StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); recyclerView.setLayoutManager(layoutManager); presenter.getLatestNews(); return view; } @Override public void refreshRecyclerVew(List<LatestNews.StoriesBean> storiesList) { Log.d(TAG, "refreshRecyclerVew: "); NewsSummaryAdapter adapter = new NewsSummaryAdapter(storiesList); recyclerView.setAdapter(adapter); } @Override public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { //String date = "You picked the following date: "+dayOfMonth+"/"+(monthOfYear+1)+"/"+year; String date = String.format("%d%02d%02d", year, monthOfYear + 1, dayOfMonth); presenter.getBeforeNews(date); }}
定义一个回调接口
public interface CallBackLatestNews { public void result(List<LatestNews.StoriesBean> list);}
Presenter层
public class NewsPresenter implements NewsContract.Presenter { private static final String TAG = "NewsPresenter"; private NewsContract.View view; private NewsContract.model model; public NewsPresenter(NewsContract.View view) { this.view = view; model = new NewsModel(); } @Override public void getBeforeNews(String date) { model.getBeforeNews(new CallBackLatestNews() { @Override public void result(List<LatestNews.StoriesBean> list) { view.refreshRecyclerVew(list); } }, date); } @Override public void getLatestNews() { Log.d(TAG, "getLatestNews: "); model.getLatestNews(new CallBackLatestNews() { @Override public void result(List<LatestNews.StoriesBean> list) { view.refreshRecyclerVew(list); } }); }}
model层
public class NewsModel implements NewsContract.model { private static final String TAG = "NewsModel"; @Override public void getBeforeNews(final CallBackLatestNews callback, String date) { Subscriber subscriber = new Subscriber<LatestNews>() { @Override public void onCompleted() { Log.d(TAG, "onCompleted: "); } @Override public void onError(Throwable e) { } @Override public void onNext(LatestNews latestNews) { callback.result(latestNews.getStories()); } }; ZhiHuApi.getInstance().getBeforeNews(subscriber, date); } @Override public void getLatestNews(final CallBackLatestNews callback) { Subscriber subscriber = new Subscriber<LatestNews>() { @Override public void onCompleted() { Log.d(TAG, "onCompleted: "); } @Override public void onError(Throwable e) { } @Override public void onNext(LatestNews latestNews) { Log.d(TAG, "onNext: "); callback.result(latestNews.getStories()); } }; ZhiHuApi.getInstance().getLatestNews(subscriber); }}
暂时只实现了知乎日报的功能,schedule和timetable还未实现。
添加了便签的功能,具体实现可以看 Android-使用LitePal实现一个便笺功能
github:https://github.com/linsawako/oneDay
- Android-MVP+Retrofit+Rxjava实现一个知乎日报客户端
- Android--MVP+Retrofit+Rxjava的实现
- Android MVP +Retrofit+RxJava
- Labview实现简单知乎日报客户端
- 知乎日报客户端
- Android 客户端 MVP+Dagger2+Databinding+Rxjava+Retrofit+Okhttp3
- Rxjava+Retrofit+okhttp+mvp实现
- MVP+Retrofit+RxJava实现分类
- Android Mvp+Rxjava+Retrofit实战
- Android Mvp+RxJava+Retrofit 实战
- Android Retrofit+RxJava+MVP封装
- 手把手教你仿一个知乎日报Android客户端(一)多图
- 手把手教你仿一个知乎日报Android客户端(二)前期准备
- 手把手教你仿一个知乎日报Android客户端(三)主页面设计
- React Native for Android 实践 — 实现知乎日报客户端
- 高仿知乎日报(Material Design + MVP + RxJava + Retrofit)
- 知乎日报客户端的模拟实现(进行时)
- 使用MVP+Retrofit+RxJava实现的的Android Demo (上)使用Nuclues库实现MVP
- codeforces 229C Triangles
- 洛谷 数论T2 1134
- [南阳OJ-No.4]ASCII码排序|输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符。
- 241. Different Ways to Add Parentheses**
- 隐公元年(2)
- Android-MVP+Retrofit+Rxjava实现一个知乎日报客户端
- Android Activity生命周期
- bellman-ford算法模板
- 11.4
- 数据结构——队列的使用(二)
- 136. Single Number
- merchant story
- git遇到的一点小问题
- 活学活用,打开/重启Tomcat的小程序~