Great transitions

If you click on any of the cards it will display the entry view again with the comments and a preview of the picture that we took previously.

We do not just want to move from the list view to the detail view. Material design also takes care of great natural transitions. This recipe is going to apply just that.

Getting ready

To go through this recipe, you will need to have the previous recipes up and running. This recipe is going to add some animations to it.

How to do it…

The following steps will help us to add the animations to our app:

  1. Add a mDrink member to ViewHolder in the MainAdapter class:
    public Drink mDrink;
  2. In the same file in the onBindViewHolder method inform the view holder about the actual drink, just after the initialization of currentDrink:
    Drink currentDrink = mDrinks.get(position);
    holder.mDrink = currentDrink;
  3. In the onCreateViewHolder method, add an OnClickListener to the end:
    v.setTag(viewHolder);
    v.setOnClickListener(new View.OnClickListener() {
        @Override
    	    public void onClick(View view) {
            ViewHolder holder = (ViewHolder) view.getTag();
            if (view.getId() == holder.itemView.getId()) 
            {
            }
        }
    });
  4. If the view is being clicked on, we want the EntryActivity class to display the selected drink entry. In order to be able to inform the entry about the selection, we need to make the Drink model a parcelable class:
    public class Drink implements Parcelable
  5. We need to implement a couple of methods for that:
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeLong(dateAndTime.getTime());
        out.writeString(comments);
        out.writeString(imageUri);
    }
    public static final Parcelable.Creator<Drink> CREATOR = new 
     Parcelable.Creator<Drink>() {
        public Drink createFromParcel(Parcel in) {
            return new Drink(in);
        }
        public Drink[] newArray(int size) {
            return new Drink[size];
        }
    };
  6. Add two constructors for the Drink class—a default one and one that takes a parcel—so we can recreate the object and populate it with the appropriate values:
    public Drink(){
    }
    public Drink(Parcel in) {
        dateAndTime = new Date(in.readLong());
        comments = in.readString();
        imageUri = in.readString();
    }
  7. In the MainAdapter class, add a private variable for the request. This approach makes your code more readable:
    private int REQUEST_EDIT_ENTRY = 2;

    Tip

    The so-called magical numbers are easy to misunderstand and should be avoided as much as possible. This and other recipes are just for demo purposes but in the real world, you should use self-explaining constants where possible. Here, REQUEST_EDIT_ENTRY makes much more sense than just putting the number 2 in your code somewhere.

  8. Now within the onClick method that we created previously in the onCreateViewHolder method of the MainAdapter, we can start a new entry activity and pass the selected drink as a parameter. The implementation of the onClick method will now look like this:
    v.setOnClickListener(new View.OnClickListener() {
        @Override
    	    public void onClick(View view) {
            ViewHolder holder = (ViewHolder) view.getTag();
            if (view.getId() == holder.itemView.getId()) {
                Intent intent = new Intent(mContext,    
                 EntryActivity.class);
                intent.putExtra("edit_drink", holder.mDrink);
        ((Activity)mContext).startActivityForResult(intent,  
                  REQUEST_EDIT_ENTRY); }
        }
    });
  9. In the onCreate method of the EntryActivity class, we will retrieve and display the properties of the selected drink. Add this implementation to the end of the method:
    Intent intent = getIntent();
    if (intent.hasExtra("edit_drink")) {
        Drink editableDrink = intent.getParcelableExtra("edit_drink");
        EditText editComment =    
         (EditText)findViewById(R.id.entry_edit_text_comment);
        editComment.setText(editableDrink.comments);
        if (editableDrink.imageUri != null) {
            mUri = Uri.parse(editableDrink.imageUri);
            Bitmap bitmap = getBitmapFromUri();
            ImageView preview = (ImageView) 
             findViewById(R.id.entry_image_view_preview);
            preview.setImageBitmap(bitmap);
        }
    }

The EditText for the comments will be filled with the comments so that the user can edit them. If an image is attached to the drink entry, it will be shown in the preview image view. Now if only we had an easy and cool way of animating the thumbnail of the image into the preview:

  1. Surprise! There is. Add a new string resource in the strings.xml (in the res/values folder) file:
    <string name="transition_preview">transition_preview 
      </string>
  2. In the onCreateViewHolder method in the MainAdapter class, within the onClick implementation, and right before the startActivityForResult method, we will use the ActivityOptionsCompat class to create a transition from the thumbnail (the holder's mImageView member) to the preview image in the layout for the entry activity:
    ActivityOptionsCompat options =  
     ActivityOptionsCompat.makeSceneTransitionAnimation(
      ((Activity)mContext), holder.mImageView,    
       mContext.getString (R.string.transition_preview));
  3. Supply these options by replacing the startActivityForResult call on the next line with this implementation:
    ActivityCompat.startActivityForResult(((Activity) mContext),  
     intent, REQUEST_EDIT_ENTRY, options.toBundle());
  4. Open the adapter_main_card_view.xml layout file and add this line to the image view (the one with the main_image_view ID):
    android:transitionName="@string/transition_preview"
  5. In the activity_entry.xml layout, add this line as well to the ImageView widget (the one with the entry_image_view_preview ID). This way Android knows where the transition of the thumbnail into the larger preview image has to go).

Note

It is good practice to use string resources. We can use these resources here to make sure we are talking about the same transition everywhere in the code but it will also be great for localization purposes.

Now if you run your app and click on any of the cards in the MainActivity class, you will see that the thumbnail is enlarged and fits into the place holder for the preview image in the layout of the EntryActivity class. The reversed transition is shown if you choose the back button. In previous versions we could not do this with only a few lines of code!

Theming

As a bonus, let's do some theming using the following steps:

  1. Visit http://www.materialpalette.com and pick two colors. Theming comes up with a color set that we can use for a theme as shown in the following screenshot:
    Theming
  2. Create a color.xml file in the res/values folder and add the suggested color names and values. I have chosen blue and indigo on the website so my color resource file looks like this:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="primary_dark">#1976d2</color><color name="primary">#2193f3</color>
        <color name="light_primary">#bbdefb</color>
        <color name="text">#ffffff</color>
        <color name="accent">#536dfe</color>
        <color name="primary_text">#212121</color>
        <color name="secondary_text">#727272</color>
        <color name="divider_color">#b6b6b6</color>
    </resources>
  3. Edit the styles.xml file in the res/values folder and make it look like this:
    <resources><style name="AppTheme" parent="Theme.AppCompat.Light">
          <item name="android:colorPrimary">@color/primary</item>
          <item name="android:colorPrimaryDark">@color/primary_dark 
          /item>
          <item name="android:colorAccent">@color/accent</item>
          <item name="android:textColor">@color/text</item>
          <item name="android:textColorPrimary">@color/primary_text 
          </item>
         <item name="android:textColorSecondary">
            @color/secondary_text
          </item>
      </style></resources>

    The output of the preceding code is as shown in the following screenshot:

    Theming
  4. Modify your layout files and change text views and other elements so that it can reflect the color scheme. Run the app.

How it works...

Android's activity transitions will take care of everything. We just need to tell what, where, and how. With just a few lines of code the API allows you to create meaningful transitions between activities, which will heavily improve the User Experience (UX) of your application.

With each new step, the looks of your app become better and better! Unfortunately, this is where this introduction to material design ends. Make improvements wherever you want. Play with it and have fun! Animations, UX, and layouts are important elements of high-quality apps.

For wearable apps, this may be even more important as we will see in the next chapter. But how can we enable a great user experience on such as small screen?

There's more...

We have seen only a few aspects of Material Design. There is so much more to discover.

Improve the looks and UX of the app further, add the implementation in the MainActivity class to handle the data of drink entries that you have added, and make enhancements wherever you want them. Or, you can have a look at your existing apps and see how you can materialize them.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset