前言

最开始学习写应用的时候,发现类聚合数据这个平台可以提供一些免费数据接口,于是写了个人的第一个应用—– JuheNews,当时的知识储备稍显粗糙,虽然现在的知识也不咋滴,但是相对之前而言还是有些进步的,所以决定将应用重构一下,具体参考我的第二个个人开发的应用— GankIOClient,采用类似的技术思路,重构后两个应用在代码结构上是很相似的。

技术选型

1. 下拉刷新 + 加载更多

采用BGARefreshLayout-Android,支持的下拉刷新样式基本可以满足我的需求,使用起来也比较简单,实现两个接口即可设置刷新动作和加载更多的动作。这位卓友的其他开源库也很好用,有兴趣的可以去看下。

使用方法:

private void initBGALayout() {    // 为BGARefreshLayout 设置代理    bgaRefreshLayout.setDelegate(this);    // 设置下拉刷新和上拉加载更多的风格 参数1:应用程序上下文,参数2:是否具有上拉加载更多功能    BGANormalRefreshViewHolder refreshViewHolder =            new BGANormalRefreshViewHolder(getContext(), true);    refreshViewHolder.setLoadingMoreText("加载更多");    refreshViewHolder.setLoadMoreBackgroundColorRes(R.color.white);    refreshViewHolder.setRefreshViewBackgroundColorRes(R.color.white);    bgaRefreshLayout.setRefreshViewHolder(refreshViewHolder);}
    @Override    public void onBGARefreshLayoutBeginRefreshing(BGARefreshLayout refreshLayout) {    //执行下拉刷新操作    }    @Override    public boolean onBGARefreshLayoutBeginLoadingMore(BGARefreshLayout refreshLayout) {        //执行加载更多操作,返回false代表不支持加载更多        return false;    }

2. 网络请求

Retrofit + RxJava2,这个就不用多做介绍了,最开始学习这两个内容的时候读过的文章分享一下:

RxJava 与 Retrofit 结合的最佳实践
给 Android 开发者的 RxJava 详解
我的一个RxJava2文章收藏集

这位朋友写的通俗易懂,不看Rxjava2的官文应该也能很快的了解Rxjava升级到2之后的变化。

使用方法:

public interface JuheApi {    @GET    Observable<NewsBean> getNews(@Url String url);    @GET    Observable<FunnyBean> getFunny(@Url String url);    @GET    Observable<JokeBean> getJoke(@Url String url);    @GET    Observable<HistoryBean> getTodayInHistory(@Url String url);    @GET    Observable<QueryNewsBean> getQueryNews(@Url String url);}
public class Retrofitance {    public static final String BASE_URL = "http://gank.io/api/";    private static final int DEFAULT_TIMEOUT = 5;    private Retrofit retrofit;    private JuheApi mJuheApi;    private OkHttpClient mOkHttpClient;    //构造方法私有    private Retrofitance() {        //手动创建一个OkHttpClient并设置超时时间        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();        httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);        mOkHttpClient = httpClientBuilder.build();        retrofit = new Retrofit.Builder().client(mOkHttpClient)                .addConverterFactory(GsonConverterFactory.create())                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                .baseUrl(BASE_URL)                .build();        mJuheApi = retrofit.create(JuheApi.class);    }    //获取单例    public static Retrofitance getInstance() {        return SingletonHolder.INSTANCE;    }    /** * 根据类型获取新闻信息 */    public void getNews(Observer<NewsBean> subscriber, String type) {        String URL = "";        commonOp(mJuheApi.getNews(URL),subscriber);    }    /** * 获取趣图信息 */    public void getFunny(Observer<FunnyBean> subscriber, int pagenum) {        String URL ="";        commonOp(mJuheApi.getFunny(URL), subscriber);    }    /** * 获取历史上的今天 */    public void getHistory(Observer<HistoryBean> subscriber) {        Calendar now = Calendar.getInstance();        String URL = "";        commonOp(mJuheApi.getTodayInHistory(URL),subscriber);    }    /** * 获取笑话大全 */    public void getJoke(Observer<JokeBean> subscriber, int pagenum) {        String URL ="";        commonOp(mJuheApi.getJoke(URL), subscriber);    }    public void getQueryNews(Observer<QueryNewsBean> subscriber, String keyword) {        String URL = "";        commonOp(mJuheApi.getQueryNews(URL), subscriber);    }    private void commonOp(Observable observable, Observer subscriber) {        observable.subscribeOn(Schedulers.io())                .unsubscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(subscriber);    }    //在访问HttpMethods时创建单例    private static class SingletonHolder {        private static final Retrofitance INSTANCE = new Retrofitance();    }}

3. 响应式编程

不二选择,RxJava2 + RxAndoid,告别Thread和AsyncTask,不用写Handler了。

使用方法:

public void getContent(int pagenum) {    Observer<FunnyBean> observer = new Observer<FunnyBean>() {        @Override        public void onComplete() {            endLoading();        }        @Override        public void onError(Throwable e) {            e.printStackTrace();            endLoading();            onNetworkError();        }        @Override        public void onSubscribe(Disposable d) {        }        @Override        public void onNext(FunnyBean funnyBean) {            if (bgaRefreshLayout.isLoadingMore()) {            } else {                mVisitableList.clear();            }            if (funnyBean.getResult() == null || funnyBean.getResult().getData() == null                    || funnyBean.getResult().getData().size() == 0) {                onDataEmpty();            } else {                mVisitableList.addAll(funnyBean.getResult().getData());            }            mMultiRecyclerAdapter.setData(mVisitableList);        }    };    Retrofitance.getInstance().getFunny(observer, pagenum);}

4. 多类型RecyclerView Item实现

参考博文RecyclerView多类型Item的正确实现姿势
当然你也可以选择一些开源库,只是我习惯了使用这种方式,用起来也比较顺手。思路和实现方式也比较简单,使用接口化的数据和泛型,抽取抽象类,结构分明,扩展性强,聪明的你应该一看就会懂。
具体使用方法参考项目代码或者是上面这篇博文,涉及的代码比较多,主要是稍微有点结构化,不便列举。

5. 注解

butterknife,告别findViewById,但是有了Kotlin,我觉得我们也可以告别butterknife了,毕竟一把小刀。
使用方法:

@BindView(R.id.tl_web)Toolbar tlWeb;@BindView(R.id.wv_content)WebView wvContent;@BindView(R.id.activity_web)LinearLayout activityWeb;@BindView(R.id.progressbar)ProgressBar progressbar;....ButterKnife.bind(this);

配合插件使用效果会更好喔。

6. 图片加载

我首选Glide,因为我有GIF的需求,Picasso不支持GIF,虽然体量比较小。
Glide的使用方法参考官文,最近Glide有大版本升级,改动比较多,有兴趣的可以关注下
使用方法:

Glide.with(itemView.getContext()).load(pic1path).placeholder(R.mipmap.empty_data).into(imageView);

Glide有更高阶的使用方法,根据需求学习吧。

7. 数据解析

Gson,Google的开源库,基本可以满足我的开发需求,暂时没有尝试过其他的。
使用的过程中配合Retrofit使用

compile 'com.squareup.retrofit2:converter-gson:2.1.0'
retrofit = new Retrofit.Builder().client(mOkHttpClient)                /*This is the key*/                .addConverterFactory(GsonConverterFactory.create())         .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                .baseUrl(BASE_URL)                .build();

配合插件使用效果会更好:GsonFormat

8. 界面布局

采用TabHost + Framgnet可以满足日常需求,当然使用开源库FlycoTabLayout更是可以构建出炫酷的Tab页面,配合上Fragment,基本可以满足需求。
使用方法:

switch (i) {    case 0:        textView.setText("资讯");        imageView.setImageResource(R.drawable.news);        tabHost.addTab(tabHost.newTabSpec("1").setIndicator(view).setContent(                R.id.frag_news));        break;    case 1:        textView.setText("笑话");        imageView.setImageResource(R.drawable.joke);        tabHost.addTab(tabHost.newTabSpec("2").setIndicator(view).setContent(                R.id.frag_joke));        break;    case 2:        textView.setText("趣图");        imageView.setImageResource(R.drawable.funny);        tabHost.addTab(tabHost.newTabSpec("3").setIndicator(view).setContent(                R.id.frag_funny));        break;    case 3:        textView.setText("历史");        imageView.setImageResource(R.drawable.history);        tabHost.addTab(tabHost.newTabSpec("4").setIndicator(view).setContent(                R.id.frag_history));        break;    default:        break;}

FlycoTabLayout的使用方法参考官文或者网上如海水般的博文。

9. 内容搜索

自定义Toolbar这个时候就显示出来威力。简单的一个文本框和一个若隐若现的搜索按钮,满足需求。开源库也有一些,但是适合我自己的不太多,所以基本上我都是如上实现。

使用方法:

<android.support.v7.widget.Toolbar    android:id="@+id/toolbar_search"    android:layout_width="match_parent"    android:layout_height="40dp"    android:fitsSystemWindows="true"    android:background="@color/colorToolbar">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent">        <EditText            android:id="@+id/et_search"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_marginBottom="8dp"            android:layout_marginTop="8dp"            android:layout_weight="6"            android:background="@drawable/search_edittext_bg"            android:padding="2dp"            android:textColor="@color/colorBlack"            android:textSize="12sp"/>        <Button            android:id="@+id/bt_search"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="2"            android:clickable="false"            android:gravity="center"            android:text="搜索"            android:background="@color/colorToolbar"            android:textColor="@color/colorToolbar"            android:textSize="14sp"/>    </LinearLayout></android.support.v7.widget.Toolbar>

10. 版本更新

第三方服务 。我使用的是Fir.im,相对比较好用,利用提供的版本接口检测版本更新。然后本地下载或者跳转到浏览器下载应用,完成安装,都是不错的选择。类似的平台还有很多,可以网上搜索一下。

更多相关文章

  1. Android常用技术-热修复解析
  2. System.Lazy延迟加载 在很多情况下,有些对象需要在使用时加载或根
  3. 手把手教你用android studio创建第一个安卓程序加载html5页面(一)
  4. Android动态加载第三方APK的View研究过程
  5. Android中插件开发篇之----类加载器
  6. Android的GridView和Gallery结合Demo
  7. Android中的动态加载机制
  8. Android集结号
  9. Android中Fragment的用法总结

随机推荐

  1. android文件管理器--文件操作
  2. 如何制作Ext4文件系统镜像
  3. android 之Dialog的多种Dialog对话框(以
  4. 安卓事件分发流程
  5. mac下 JNI-Hello world
  6. android之简易画板(涂鸦)实例(透明背景)
  7. Android CompoundButton
  8. android 面试题锦集
  9. android 获取上一个activity的返回值
  10. android 调用系统的图片选择