The Busy Coder's Guide to Android Development Version 6.5 Released

Subscribers now have access to the latest release of The Busy Coder’s Guide to Android Development, known as Version 6.5, in all formats. Just log into your Warescription page and download away, or set up an account and subscribe!

This update is dominated by a rather large chapter on RecyclerView. It covers how to get back all of the stuff that RecyclerView lost from ListView and GridView, plus some things that RecyclerView can do that its predecessors cannot. Basically, it covers the RecyclerView equivalents of pretty much everything the book has on ListView and GridView, including how to support choice modes (e.g., checklists, activated states) and action modes. It also demonstrates CardView along the way.

In addition, there is a new chapter on Parcelable (what it is, how to make your own classes Parcelable, and Parcelable problems) and various other minor improvements.

The next update is tentatively scheduled for the second half of April.

Mar 02, 2015


Webinars Woster

(with suitable apologies to Elmer J. Fudd for the blog post title)

Here is the current set of webinars that I am running the next couple of months:

  • Android Studio for Eclipse Users is a quick tour of Android Studio, pointing out key differences between how Eclipse worked and how Android Studio works.

  • What’s New with Notifications covers some of the changes that arose in 2014 related to the use of Notifications, such as customizing them for Android Wear and Android 5.0’s new behaviors.

  • The Leanback BrowseFragment is a short presentation on how to use the leanback-v17 library to create a TV-centric UI, focusing on the BrowseFragment for a two-dimensional nested-list UI for browsing categories of content.

  • Much Manifest Merging will sift through the rules for how your Android app’s manifest is generated from your Gradle build files, your main sourceset, your sourcesets for build types and product flavors, and your third-party library projects and AARs.

Subscribers should visit the “Other Services > Webinars” link in the Warescription site for 80% discounts on these webinars.

Feb 11, 2015


Ripples from a Touch Point

Google has started to point out to app developers when they use ripple animations in Material Design-styled UIs, where those ripples do not seem to emanate from the touch point that triggered the animation.

Using Google’s search engine, the only thing that I found that seemed to explain how to make this work was a comment on an issue on Lucas Rocha’s TwoWayView library. Fortunately, that comment was enough for me to create something that seems to work.

As Mr. Butcher hints in his tweet, the key appears to be the setHotspot() method on Drawable. Added in API Level 21, this teaches the drawable a “hot spot”, and RippleDrawable apparently uses this as the emanation point for the ripple effect. setHotspot() take a pair of float values, presumably with an eye towards using setHotspot() inside of an OnTouchListener, as the MotionEvent reports X/Y positions of the touch event with float values.

This sample app demonstrates the use of setHotspot() in the context of a RecyclerView, as part of a 50+ page chapter that I am working on for the next book update. This RecyclerView is using a LinearLayoutManager, to replicate the basic structure of a classic ListView. My rows are based on a CardView:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:cardview="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_margin="4dp"
  cardview:cardCornerRadius="4dp">

  <LinearLayout
    android:id="@+id/row_content"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="?android:attr/selectableItemBackground">

    <!-- other widgets in here -->

    </LinearLayout>

  </LinearLayout>

</android.support.v7.widget.CardView>

The LinearLayout that the CardView wraps has ?android:attr/selectableItemBackground as its background, pulling in a theme attribute. If this app runs on API Level 21, that background will be a RippleDrawable.

When I set up the row, I attach an OnTouchListener to set the hotspot, but only on API Level 21+ devices (as setHotspot() does not exist before then):

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  row.setOnTouchListener(new View.OnTouchListener() {
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      v
        .findViewById(R.id.row_content)
        .getBackground()
        .setHotspot(event.getX(), event.getY());

      return(false);
    }
  });
}

So, if the user touches a row, I propagate the touch point to the background as its hotspot. I specifically return false to indicate that we are not consuming the touch event, so it will continue on to the rest of the event handlers, if needed.

Without this setHotspot() call, the RippleDrawable seems to default to the drawable’s center. So, in the case of a row for a list-style RecyclerView, the ripple effect would emanate from the center of the row. setHotspot(), tied to the touch event, changes the emanation point.

This seems to work. I have no idea if it is the official right answer, insofar as I have not seen any code from Google for how to implement this (e.g., a search of the SDK samples for setHotspot() turns up nothing). In particular, calling setHotspot() directly on the background worries me (should we be calling mutate() first?). So, imagine a grain of salt, measuring approximately 15cm on a side, and take that grain of salt with this implementation.

Feb 06, 2015


Webinars for Meetups

While I am still on my presentation sabbatical, there are still ways that I can help your meetup, GDG, or similar collection of Android developers: webinars.

I hold webinars several times a month, each usually lasting an hour. While there is a nominal fee for attending, that fee is per connection, not per person. A collection of people are welcome to attend via some shared connection to the Dozeo web conference, whether that collection represents a team at a firm in a conference room or an independent group like a meetup in an, um, larger conference room. :-)

For groups, I can schedule additional webinars — on current or past topics — at times that fit your group’s schedule. So, for example, if your meetup meets on the third Tuesday of every month, we can set up a webinar fitting that time slot. Times from 8am to 8pm (US Eastern) are available.

If you are interested in scheduling a webinar as part of an event for your group, contact me and we can work out the details.

Jan 22, 2015


The Busy Coder's Guide to Android Development Version 6.4 Released

Subscribers now have access to the latest release of The Busy Coder’s Guide to Android Development, known as Version 6.4, in all formats. Just log into your Warescription page and download away, or set up an account and subscribe!

This update is focused on a bunch of TV-related stuff that I had worked on prior to Android Studio 1.0 shipping, causing the TV stuff to get put aside temporarily. The TV material includes:

  • Preliminary coverage of the leanback-v17 library, focused on BrowseFragment for providing a two-dimensional, D-pad-friendly navigation option for browsing a content catalog

  • A chapter on Android TV, converted from the Google TV chapter

  • Mention of the Fire TV Stick in the coverage of Fire TV

  • A new chapter reviewing a large sample app, Decktastic, which presents conference-style presentations using an external display (HDMI, MHL, Miracast, etc.), Chromecast (and other RemotePlaybackDevice devices), and direct-to-TV devices (Android TV, Fire TV, etc.)

This update also contains:

  • A new chapter on AndroidJUnitRunner and JUnit4 support. Espresso support should be covered in some future edition of the book.

  • A revised VideoList sample in the chapter on the MediaStore, switching out SmartImageView with the Universal Image Loader for asynchronously loading video thumbnails.

  • A merged chapter on the basics of Gradle and the manifest, as having those spread over two chapters was too confusing.

  • Updated material on publishing AARs, focusing now on the official maven plugin.

  • Various bug fixes and such.

The next update is tentatively slated for mid-March 2015.

Jan 20, 2015


Older Posts