Welcome nuggets friends to visit myThe blog site, original link:Wensibo. Top / 2017/05/15 /…Shall not be reproduced without permission!

Today, I want to share with you an app — Dry goods Concentration camp client, which I developed in a week in May. I cannot share my previous article with you because I have already got the column of Nuggets. Actually online have many similar projects, code home in his dry camp also recommend several good films, I also learn from some of them, their client, developed a dry concentration camps now project has been released to making, if you want to know the specific content of the whole project, so you can fork or clone, If you think I can do well, please give me a STAR! Your support will be my motivation to try.

preface

Slowly has developed each article will come to a foreword, but also slowly will write articles subtly into writing stories, so every story will have a foreword, there will be a result, this is no exception. It has been a month since the last article which aroused warm response was published. Thanks to the support and suggestions from netizens, of course, as a post-90s, I also humbly accept the ridicule from all sides. After all, I am not excellent, but I have been running hard on the road of excellence. I’d like to share with you what I have done in the past month and what I plan to do in the coming months.

Have Done List

  • continuous22Days are popping up on Github. Check out the contribution tree below


    contributions
  • Blog traffic breaks through35000


    blog
  • Read a good book — How the Internet Is Connected
  • Research the source code for Retrofit and RxJava (I’ll post this article when the grapes are ripe, it’s too young for everyone to read)
  • 2 times as keynote speaker (I will write an article about my presentation skills later)
  • I watched the launch conference of Smartisan New products (I am luo fan, but also cheer, love Luo for a second)
  • Trying to find an internship (sent out a lot of resumes but none of them got away from me can anyone recommend one? If not, I’ll ask later)
  • A new dry cargo Concentration camp client app(the reason for writing this article)

Todo List

  • Xposed plug-in development (this flash is one night woke up the idea)
  • Continue to write good articles to share with you, not only the technical aspects, but also many useful articles I think will be provided for you, thank you for your support
  • To continue reading
  • Continue to look for internships (woo woo woo~ ~ (> _ <)~~, realized that the job is difficult to find, especially in the winter of Internet)
Cut the crap, old iron


Project introduction

logo



Dry goods concentration camp API

  • Faster loading speed
  • A smoother page experience
  • More interesting refresh effects
  • Better web browsing
  • More beautiful visual enjoyment

This is just my personal feeling, please say: Joy:, but I still hope that you can like this project, and actively pull request and feedback bugs to me, I hope that you can support. Give it a star if you can.

preview

No one said they didn’t

Show me all the renderings

screenshot
screenshot
screenshot


screenshot
screenshot
screenshot

I’m embarrassed to talk without giFs

gif

download

Cool Ann gay group

If you use Kuan, then hard click here, or in Kuan search dry goods concentration camp, look for my icon oh

Dry goods concentration camp

fir.im

If you don’t have Kuan installed, you can scan the QR code below to download it

QRCode

test

If you want to test this project, clone manually

Functions & Features

√ represents implemented features, and X represents features that have not been implemented or need to be improved. (For fun, the Nuggets’ MarkDown editor still doesn’t implement some basic syntax, such as checking a box)

√ Obtain the latest data of the server in real time and use CardView layout to better display the data. √ Refresh effect is very fun, really exquisite, thanks Phoenix. √ If you have Chrome and set it as your default browser, your web browsing will look pretty cool. Thank you for the Custom Tabs – Client! Chrome is recommended. If you don’t have Chrome installed, that’s ok. Use a traditional WebView instead. √ More unified transition animation, I believe you will love it. √ Save and share images and links, or open links directly using your browser. √ Better Material Design style. √ Girls are beautiful!


X optimizes webView video playback. X Added the option to use the system browser. X Fixed data display error when loading data to main screen around 4/20, 2016. X Enhanced sharing.

decomposition

Finally, the pure dry step, don’t talk first look!

How to use MVP’s design architecture

Let me show you the structure of the project below, so that you have an idea

  • http
    • GankRetrofit.java
    • GankRetrofitClient.java
  • mvp
    • model
      • BaseModel.java
    • presenter
      • BasePresenter.java
    • view
      • IBaseView.java
  • ui
    • activity
    • adapter
    • base
    • chromeviews
    • fragment
    • widget

It can be seen that the structure of the whole project is relatively clear. The overall architecture is determined in the MVP directory. The MVP architecture is divided into three layers, the Model layer, which is used to define some data types. Presenter layer, which handles view layer logic; View display layer, here are defined interface, the real implementation of their activities, these activities as long as the corresponding interface, can be their own copy of the method. I said so, of course, you must be a face of meng force, and I also have to tell you, I this is not the most pure MVP patterns, the purest of writing should be of programming to an interface, is in the model, the presenter, and are under the view defines the interface, and by the use of specific scenarios, it defines the specific classes to implement these interfaces. Of course, to give you a better understanding of how MVP is implemented, I will use the following code to show you, for example, I want to write the MainActivity code, first of all, we already know that the Activity needs to do the following:

  • Initialize components
  • Load the fragments
  • Click event of FloatingActionButton — go to DailyActivity
  • Drawer menu click event — go to AboutActivity

In order for an Activity to focus on the interface and not worry about its logical operations, which is called decoupling, we can put the logical operations in presenter and the interface operations in view. I have modified the code in the project appropriately, if you want to see more specific logic, take a closer look at the code) :

  • IBaseView
public interface IBaseView {
        // Initialize the interface
        void init(a);
}Copy the code
  • BasePresenter&MainPresenter
/** * Integrate the common operations of presenter into BasePresenter */
public abstract class BasePresenter <T extends IBaseView>{
        protected Disposable disposable;
        protected Context context;
        protected T iView;      // Get the view object

        public BasePresenter(Context context, T iView) {
                this.context = context;
                this.iView = iView;
        }

        public void init(a) {
                iView.init();
        }

        public abstract void release(a);
        public abstract void initPresenter(a);
}

/** * Each interface can write its own Presenter and specify the View's generic */
public class MainPresenter extends BasePresenter<IBaseView> {

        public MainPresenter(Context context, IBaseView iView) {
                super(context, iView);
        }

        @Override
        public void release(a) {}public void toDailyActivity(a) {
                Intent intent = new Intent(context, DailyActivity.class);
                context.startActivity(intent);
        }

        public void toAboutActivity(a) {
                Intent intent = new Intent(context, AboutActivity.class);
                context.startActivity(intent);
        }

        public void toSettingActivity(a) {
                Intent intent = new Intent(context, SettingActivity.class);
                context.startActivity(intent);
        }Copy the code
  • MainActivity
public class MainActivity <MainPresenter> extends AppCompatActivity implements IBaseView{

        @OnClick(R.id.fab_main)
        void fabClick(a) {
                presenter.toDailyActivity();
        }

        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        }


        @Override
        protected void initPresenter(a) {
                presenter = new MainPresenter(this.this);
                presenter.init();
        }

        @Override
        public void init(a) {
                // All initialization operations
        }

        @Override
        protected void onDestroy(a) {
                super.onDestroy(); presenter.release(); }}Copy the code

Probably is one such routines, really I say so you must be confused, I was learning this time also is very messy, later found that only yourself personally to knock the code to understand the whole train of thought, and everyone in the process of learning the MVP should be good at drawing, whether in paper or use a mind map will do, This gives you a broader view of the order of calls and the relationships between classes than you can get from reading a single article.

Are you really using RxJava

When I ask this question, WHAT I’m really trying to say is that RxJava is so useful that we assume that if RxJava works with Retrofit, we’re done, but in reality it’s just time-consuming operations, thread switching: You can use RxJava for web requests, image parsing, database reading, and other tasks that require multiple threads, and if you’re still using RxJava1, you’re OUT of date. Rxjava2.x is much more powerful when you get to know it. I’ll write about RxJava in a future article, but here’s an example of how much RxJava can be used:

/** * Save the image locally */
public void openWebView(final Gank gank) {
    disposable=Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(@NonNull ObservableEmitter e) throws Exception {
                    e.onNext(android.R.drawable.ic_menu_share);
            }
    }).subscribeOn(Schedulers.newThread())// Start a new thread for time-consuming operations
            .map(new Function<Integer, Bitmap>() {
                    @Override
                    public Bitmap apply(@NonNull Integer integer) throws Exception {
                            // Resolving the resource ID to a bitmap is a time-consuming operation
                            return BitmapFactory.decodeResource(activity.getResources(), integer);
                    }
            }).observeOn(AndroidSchedulers.mainThread())// go back to the main thread to manipulate bitmap
            .subscribe(new Consumer<Bitmap>() {
                    @Override
                    public void accept(@NonNull Bitmap bitmap) throws Exception {
                            // Interface updates made after getting the bitmap}}); }// Release resources
public void release(a) {
                if(disposable ! =null&&!disposable.isDisposed()) {
                        disposable.dispose();
                }
        }Copy the code

Frank Retrofit

Remember that I wrote a series of articles about Volley, which I thought was a pretty good open source framework, but Volley was pretty small compared to Retrofit, so let’s see how we could use it in our projects:

  • 1, Create an interface with annotations to define the network request method:
public interface GankRetrofit {
        // Obtain MainActivity interface data, the specific request path should be detailed to the official API description,
        // Retrofit becomes more powerful when combined with RxJava
        @GET("data/{type}/40/{page}")
        Observable<MainData> getMainData(@Path("type") String type, @Path("page") int page);
}Copy the code
  • 2. Obtain examples:
Gson date_gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create();
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://gank.io/api/")         // Specify the server address
        .addConverterFactory(GsonConverterFactory.create(date_gson))    // Add a gson parser
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())          // If you want to use RxJava, you need to add this adapter
        .build();
GankRetrofit gankRetrofit;
gankRetrofit = retrofit.create(GankRetrofit.class);            // Get GankRetrofit objectsCopy the code
  • 3. Data acquisition:
// The returned Observable
      
        can be parsed using RxJava
      
gankRetrofit.getMainData("Android".40);Copy the code

Better web browsing experienceCustom-Tabs-Client

If you’ve ever used Chrome, you’ll probably love it. When we use WebView for development, we find that webView has a lot of limitations, and developers don’t have complete control over webView. So the Chrome team designed this open source library to solve these problems for developers. As long as you have Chrome installed on your phone and set it as the default browser, you’ll see something like this when you open a web link:

custom-tabs-client



Transition animations
ActionButton above the ToolBar

CustomTabsIntent.Builder customTabsIntent;
 customTabsIntent = new CustomTabsIntent.Builder();     // Get the CustomTabsIntent instance
 // A series of Settings
customTabsIntent.setToolbarColor(activity.getResources().getColor(R.color.colorPrimaryDark));   // Set the ToolBar color
customTabsIntent.setShowTitle(true);    // Sets whether to display the title of the page
customTabsIntent.setStartAnimations(activity, R.anim.slide_in_right, R.anim.slide_out_left);    // Set the incoming animation
customTabsIntent.setExitAnimations(activity, R.anim.slide_in_left,R.anim.slide_out_right);      // Set the exit animation
// Open the page
CustomTabActivityHelper.openCustomTab(
    activity,       // The current activity
    customTabsIntent.build(),
    view,
    gank,   // Gank with the URL of the page to open
    new CustomFallback() { // If the user does not have Chrome installed and set it as the default browser, this should be done
            @Override
            public void openUri(Activity activity, View view,Gank gank) {
                    Log.d("Gank", gank.toString());
                    super.openUri(activity, view,gank); }});Copy the code

The above is to share with you about some important points in this project, maybe some places are not so clear, but I think only practice can tell the truth, so brother or quietly open AS masturbation code!

Version control

The current version of app is V1.0.0. I will use the following timetable to record the iterations of the version. If there is an updated version, I will update this table in time.

Version Date
V1.0.0 2017/5/14

Thank you

As Android developers, we should all appreciate the open source world as Luo did. What we can do now is to contribute to the open source world, whether we write articles or programs, remember to always be grateful. Many thanks to codener and his Work Camp, and many of the work camp apps that have come before us.

  • Code,
  • Dry goods concentration camp
  • Gank.lu

Afterword.

In the last month, I felt exhausted and joked about the unreasonable curriculum arrangement of my major. It is really boring to take courses that I am not interested in every day. However difficult life is, we should be grateful for it. See you in the next article!