preface

Started learning to write application, found that this platform can provide some kind of aggregated data free data interface, then wrote a personal application — — — — — the first JuheNews, the knowledge reserve slightly rough, while the current knowledge nor zha drops, but some progress relative to before, so decided to apply refactorings, Specifically referring to my second self-developed application, GankIOClient, the two applications are very similar in code structure after refactoring with similar technical ideas.

Technology selection

1. Pull down refresh + Load more

Using BGAreFreshLayout-Android, the supported drop-down refresh style can basically meet my needs, and it is relatively simple to use. Two interfaces can be implemented to set the refresh action and load more actions. This zhuo you other open source library is also very easy to use, interested can go to see.

Usage:

Private void initBGALayout () {/ / agents for BGARefreshLayout BGARefreshLayout setDelegate (this); // Set pull-down refresh and pull-up load with more style parameters 1: application context, parameter 2: Tensile loading on whether more BGANormalRefreshViewHolder refreshViewHolder = new BGANormalRefreshViewHolder (getContext (), true); RefreshViewHolder. SetLoadingMoreText (" load more "); refreshViewHolder.setLoadMoreBackgroundColorRes(R.color.white); refreshViewHolder.setRefreshViewBackgroundColorRes(R.color.white); bgaRefreshLayout.setRefreshViewHolder(refreshViewHolder); }Copy the code
@ Override public void onBGARefreshLayoutBeginRefreshing (BGARefreshLayout refreshLayout) {/ / execution drop-down refresh operation} @ Override public Boolean onBGARefreshLayoutBeginLoadingMore (BGARefreshLayout refreshLayout) {/ / execution load more operation, returns false representative does not support loading more return false; }Copy the code

2. Network request

Retrofit + RxJava2, which doesn’t need to be explained, is a post I read when I first learned about Retrofit and RxJava2:

RxJava best practices combined with Retrofit for Android Developers RxJava details a collection of my RxJava2 articles

Rxjava2 has been upgraded to Rxjava2.Copy the code

Usage:

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);
}Copy the code
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() {// Manually create an OkHttpClient and set the timeout 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 ="";} 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); } private static class SingletonHolder {private static final Retrofitance INSTANCE = new Retrofitance(); }}Copy the code

Responsive programming

RxJava2 + RxAndoid, say goodbye to Thread and AsyncTask, no need to write Handler.

Usage:

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);
}Copy the code

4. Realization of multi-type RecyclerView Item

Of course, you can also choose some open source libraries, but I am used to using this way, it is more comfortable to use. The way of thinking and implementation is also relatively simple, the use of interface data and generics, abstraction of abstract classes, clear structure, strong scalability, smart you should see it will understand. Refer to the project code or the above blog post for specific usage methods. There are many codes involved, which are mainly slightly structured and inconvenient to list.


5. Note

Butterknife, say goodbye to findViewById, but with Kotlin, I think we can say goodbye to butterknife, a knife after all. Usage:

@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);Copy the code

The effect will be better when used with plug-ins.


6. Image loading

I prefer Glide because I have GIF demand, Picasso doesn’t support GIF, even though the size is relatively small. Glide the use of reference to the official article, Glide has a large version of the latest upgrade, more changes, interested can pay attention to the method of use:

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

Glide has a higher level of use, according to the demand to learn it.


7. Data parsing

Gson, Google’s open source library, can basically meet my development needs, and I haven’t tried other ones for the time being. Use the process in conjunction with Retrofit

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

It works better with plug-ins: GsonFormat


8. Interface layout

TabHost + Framgnet can meet the daily needs, of course, using the open source library FlycoTabLayout can build a cool Tab page, with the Fragment, can basically meet the needs. Usage:

Switch (I) {case 0: textView.settext (" info "); imageView.setImageResource(R.drawable.news); tabHost.addTab(tabHost.newTabSpec("1").setIndicator(view).setContent( R.id.frag_news)); break; Case 1: TextView.settext (" joke "); 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 (" history "); imageView.setImageResource(R.drawable.history); tabHost.addTab(tabHost.newTabSpec("4").setIndicator(view).setContent( R.id.frag_history)); break; default: break; }Copy the code

FlycoTabLayout use method reference official or online such as seawater blog.


9. Content search

This is where the custom Toolbar comes into its own. A simple text box and a looming search button meet the needs. There are a few open source libraries, but not too many for me, so I basically implement them as above.

Usage:

<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 :background="@color/colorToolbar" android:background="@color/colorToolbar" android:textColor="@color/colorToolbar" android:textSize="14sp"/> </LinearLayout> </android.support.v7.widget.Toolbar>Copy the code

10. Version update

Third party services. I use Fir. Im, which is relatively easy to use, using the version interface provided to detect version updates. It’s a good idea to download the app locally or jump to the browser to download the app and install it. There are many similar platforms, you can search online.