Use Retrofit+RxJava+MVP to create a Material Design style APP

Use Retrofit+RxJava+MVP to create a Material Design style APP

In order to get familiar with the use of some open source frameworks, I decided to use my spare time to write an APP to get familiar with the use of these frameworks. Step on the pits in advance to facilitate future use in the company's projects. The interfaces used are aggregated data and dry goods concentration camp, thank you very much.

Rendering

Mainstream frameworks used

  • The home page side slide bar is implemented using DrawerLayout+NavigationView
  • Using Realm database to implement local collection
  • Use Retrofit+RxJava+RxAndroid to implement network requests and simply encapsulate the returned results
  • Encapsulate the Adapter and ViewHolder of RecyclerView to achieve pull-up loading
  • Use CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout to achieve a cool sliding animation
  • Use Glide to load pictures
  • Use PhotoView to achieve image zoom
  • The calendar uses the open source material-calendarview
  • Implemented SwipeRefreshLayout to automatically refresh for the first time

1. Use DrawerLayout+NavigationView to implement the side slide bar

  1. <?xml version= "1.0" encoding= "utf-8" ?><android.support.v4.widget.DrawerLayout
  2. xmlns:android= "http://schemas.android.com/apk/res/android"  
  3. xmlns:app= "http://schemas.android.com/apk/res-auto"  
  4. android:id= "@+id/drawerLayout"  
  5. android:layout_width= "match_parent"  
  6. android:layout_height= "match_parent" >
  7.  
  8. <LinearLayout
  9. android:layout_width= "match_parent"  
  10. android:layout_height= "match_parent"  
  11. android:orientation= "vertical" >
  12.  
  13. <android.support.v7.widget.Toolbar
  14. android:id= "@+id/toolbar"  
  15. android:layout_width= "match_parent"  
  16. android:layout_height= "wrap_content"  
  17. app:titleTextColor= "@android:color/white" />
  18.  
  19. <FrameLayout
  20. android:id= "@+id/fl_main"  
  21. android:layout_width= "match_parent"  
  22. android:layout_height= "match_parent" ></FrameLayout>
  23. </LinearLayout>
  24.  
  25. <android.support.design.widget.NavigationView
  26. android:id= "@+id/navigation"  
  27. android:layout_width= "match_parent"  
  28. android:layout_height= "match_parent"  
  29. android:layout_gravity= "start"  
  30. android:fitsSystemWindows= "true"  
  31. app:headerLayout= "@layout/drawer_header"  
  32. app:menu= "@menu/drawer_menu" >
  33. </android.support.design.widget.NavigationView></android.support.v4.widget.DrawerLayout>

DrawerLayout is a built-in control in the Androidv4 package, which supports left and right sliding. android:layout_gravity="leftt" represents the left sliding interface (or start), android:layout_gravity="right" represents the right sliding interface (or end), and the main interface is the one without layout_gravity. You can add ActionBarDrawerToggle in the code to control the display and hiding of the side sliding bar.

  1. ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolBar, R.string. open , R.string. close );
  2. mDrawerToggle.syncState();
  3. mDrawer.addDrawerListener(mDrawerToggle);

NavigationView is a control launched by Google after 5.0. It is mainly used as a menu control. It is divided into upper and lower parts. The upper part is headerLayout, which can customize the layout, and the lower part is menu, which is used as the menu item of the navigation menu.

  1. <?xml version= "1.0" encoding= "utf-8" ?><menu xmlns:android= "http://schemas.android.com/apk/res/android" >
  2. <item
  3. android:id= "@+id/drawer_todayInHistory"  
  4. android:checkable= "true"  
  5. android:icon= "@drawable/ic_history"  
  6. android:title= "Today in History" />
  7. <item
  8. android:id= "@+id/drawer_gril"  
  9. android:checkable= "true"  
  10. android:icon= "@drawable/icon_gril"  
  11. android:title= "Girl" />
  12. <item
  13. android:id= "@+id/drawer_like"  
  14. android:checkable= "true"  
  15. android:icon= "@drawable/ic_unlike"  
  16. android:title= "Collection" />
  17. <item
  18. android:id= "@+id/drawer_about"  
  19. android:checkable= "true"  
  20. android:icon= "@drawable/ic_about"  
  21. android:title= "About" /></menu>

Click event:

  1. navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
  2. @Override
  3. public boolean onNavigationItemSelected(MenuItem item) {
  4. //Handle the item click event here
  5. return   true ;
  6. }
  7. });

Get the controls in the header (headerLayout):

  1. View headView=navigationView.getHeaderView(0);

Set the menu list icon color:

By default, the menu icon color is gray. You can set the icon color by

  1. app:itemIconTint= ""  

Add a dividing line:

Just divide the menu into multiple groups, set an ID for each group, and there will be a dividing line between the groups:

  1. <menuxmlns:android= "http://schemas.android.com/apk/res/android" >
  2. <groupandroid:id= "@+id/g1" >
  3. <item
  4. android:id= "@+id/favorite"  
  5. android:icon= "@mipmap/ic_launcher"  
  6. android:title= "Today in History" />
  7. <item
  8. android:id= "@+id/wallet"  
  9. android:icon= "@mipmap/ic_launcher"  
  10. android:title= "Collection" />
  11. </ group >
  12. <groupandroid:id= "@+id/g2" >
  13. <item
  14. android:id= "@+id/photo"  
  15. android:icon= "@mipmap/ic_launcher"  
  16. android:title= "Girl" />
  17. </ group >
  18. <item
  19. android:id= "@+id/file"  
  20. android:icon= "@mipmap/ic_launcher"  
  21. android:title= "About" />
  22. </menu>

2. Glide loading pictures

Setting the binding lifecycle

  1. Glide. with (Context context); // Bind Context
  2. Glide. with (Activity activity); // Bind Activity
  3. Glide. with (FragmentActivity activity);// Bind FragmentActivity
  4. Glide. with (Fragment fragment);// Bind Fragment

General usage:

  1. Glide. with (context)
  2. .load (imageUrl) //image path
  3. .placeholder(R.drawable.ic_launcher) //Set the loading image
  4. .error(R.drawable.ic_launcher) //Set the image that failed to load
  5. .skipMemoryCache( true ) //Set to skip memory cache
  6. .diskCacheStrategy(DiskCacheStrategy. ALL ) //Set cache strategy: all : cache source resources and converted resources / none: do not cache any disk resources / source: cache source resources / result: cache converted resources
  7. .priority(Priority.NORMAL) //Set download priority
  8. .animate(R.anim.item_alpha_in) //Set loading animation
  9. .thumbnail(0.1f) //Set thumbnail support (load thumbnails first, then load full images)
  10. .override(400,400) //Set loading size
  11. .centerCrop() //Set dynamic transformation
  12. . into (imageView);

Load the Git image:

  1. Glide. with (this). load (imageUrl).asGif(). into (imageView);

Dynamic cache cleaning:

  1. Glide.get(this).clearDiskCache(); //Clear the disk cache. Need to be executed in the child thread. Glide.get(this).clearMemory(); //Clear the memory cache. Can be done in the UI main thread.

Load rounded corner images or circular images:

  1. Glide. with (this). load (imageUrl).transform(new GlideRoundTransform(this)). into (imageView);

A custom Transform is required. Here is a Transform for rounded corners and a circle:

Round Corner Conversion:

  1. public class GlideRoundTransform extends BitmapTransformation {
  2.  
  3. private static   float radius = 0f;
  4.  
  5. public GlideRoundTransform(Context context) {
  6. this(context, 4);
  7. }
  8.  
  9. public GlideRoundTransform(Context context, int dp) {
  10. super(context);
  11. this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
  12. }
  13.  
  14. @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
  15. return roundCrop(pool, toTransform);
  16. }
  17.  
  18. private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {
  19. if (source == null ) return   null ;
  20.  
  21. Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
  22. if (result == null ) {
  23. result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
  24. }
  25.  
  26. Canvas canvas = new Canvas(result);
  27. Paint paint = new Paint();
  28. paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
  29. paint.setAntiAlias( true );
  30. RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
  31. canvas.drawRoundRect(rectF, radius, radius, paint);
  32. return result;
  33. }
  34.  
  35. @Override public String getId() {
  36. return getClass().getName() + Math.round(radius);
  37. }
  38. }

Circular image conversion:

  1. public class GlideCircleTransform extends BitmapTransformation {
  2. public GlideCircleTransform(Context context) {
  3. super(context);
  4. }
  5.  
  6. @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
  7. return circleCrop(pool, toTransform);
  8. }
  9.  
  10. private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
  11. if (source == null ) return   null ;
  12.  
  13. int   size = Math. min (source.getWidth(), source.getHeight());
  14. int x = (source.getWidth() - size ) / 2;
  15. int y = (source.getHeight() - size ) / 2;
  16.  
  17. // TODO this could be acquired from the pool too
  18. Bitmap squared = Bitmap.createBitmap(source, x, y, size , size );
  19.  
  20. Bitmap result = pool.get( size , size , Bitmap.Config.ARGB_8888);
  21. if (result == null ) {
  22. result = Bitmap.createBitmap( size , size , Bitmap.Config.ARGB_8888);
  23. }
  24.  
  25. Canvas canvas = new Canvas(result);
  26. Paint paint = new Paint();
  27. paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
  28. paint.setAntiAlias( true );
  29. float r = size / 2f;
  30. canvas.drawCircle(r, r, r, paint);
  31. return result;
  32. }
  33.  
  34. @Override public String getId() {
  35. return getClass().getName();
  36. }
  37. }

Get Bitmap

  1. Glide.with ( this)
  2. .load (imageUrl)
  3. .asBitmap()
  4. . into (new SimpleTarget<Bitmap>() {
  5. @Override
  6. public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
  7. imageView.setImageBitmap(mBitmap);
  8. }
  9. });

<<:  MVP architecture in Android development

>>:  Android obfuscation from entry to mastery

Recommend

Taking a census of galaxies? China's sky survey helps resolve the Hubble crisis!

The English version of Science China Physics, Mec...

How to establish effective promotion channels for university marketing?

University marketing is mainly targeted at studen...

Where does pufferfish's toxicity come from, and how can we eat them safely?

Hilsa shad, razor fish and puffer fish are collec...