Tag: Smartphone

Programming Stuff

Android Updatable Swipe Navigation with FragmentStatePagerAdapter

Android Studio makes adding swipe navigation to your Android apps easy through the “Scrollable Tabs + Swipe” option of the Navigation Type selection in the New Project Wizard. Choosing this option works great as long as you have a static list of screens that the user “swipes” between.

3095_05_03

When Static Screen Lists Aren’t Enough

The way swipe navigation works is that each screen is represented by an instance of a Fragment-derived class. These Fragment classes are then managed by a PagerAdapter-derived class which makes them, in effect, a scrollable list. Passing that PagerAdapter to a ViewPager presents that list in a way that the user can use a swipe-motion to move between screens.

The code generated by Android Studio provides a custom PagerAdapter class that derives from  FragmentPagerAdapter. Basically all one has to do is override the getItem method and return the desired Fragment for each screen position (you’ll also need to override getCount and getPageTitle but those are super simple). What happens though is that the FragmentPagerAdapter class is designed such that once a Fragment instance is returned for a given position that Fragment is permanently in that position. Once this happens, you can, of course, make changes to the contents of the Fragment but there’s no way to provide a different Fragment instance for that position which is often what’s necessary.

The comments in the generated class indicate that using FragmentStatePagerAdapter instead of FragmentPagerAdapter as the base class allows for more dynamic management of the Fragment instances. Reading the FragmentStatePagerAdapter documentation indicates that we can notify our FragmetStatePagerAdapter instance of a change in the list of screens (in other words that we’d like to use new Fragment instances) by calling the notifyDataSetChanged method. But that’s only part of the story.

Once you call this method what you’ll normally see is that screens that were previously visited still have the old Fragment instances but screens being visited for the first time have the new Fragment instances. If you have a large number of screens and scroll back and forth between them you may see some of the older screens eventually show a new Fragment instance.

Not really the consistent user experience we’re looking for 🙂

So what’s the problem?

What’s happening is that FragmentStatePagerAdapter is trying to be efficient and only create new Fragment instances when necessary. To determine when to request new Fragment instances after a call to the notifyDataSetChanged method, FragmentStatePagerAdapter calls its getItemPosition method to see if an existing Fragment can be used in its current or possibly a different position without having to recreate it. What we have to do is tell the FragmentStatePagerAdapter instance that we don’t want to use the existing Fragment instance.

To do that we need to override getItemPosition as follows

public int getItemPosition(Object object) {
 // Causes adapter to reload all Fragments when
 // notifyDataSetChanged is called
 return POSITION_NONE;
}

By returning POSITION_NONE we’re telling the FragmentStatePagerAdapter instance to discard that Fragment and just create new ones for every screen position.

Summary: How To Create Updatable Swipe Navigation

To summarize what to do, here’s the list of steps…

  1. Select “Scrollable tabs + swipe” as the Navigation Type when generating your project in Android Studio
  2. Change the FragmentPagerAdapter base class to FragmentStatePagerAdapter
  3. Override the getItemPosition method to return POSITION_NONE
  4. Call notifyDataSetChanged in your code when you’d like to load new Fragment instances.

And with that, you have the ease of swipe navigation with the ability to reload Fragments instances as needed

Adapted from Jim’s Pluralsight course Android for .NET Developers: Adopting the Android Mindset

AndroidMindsetBanner_WithLogo

Checkout Jim’s latest book: Creating Dynamic UI with Android Fragments

Creating Dynamic UI with Fragments

Programming Stuff

Creating Dynamic UI with Android Fragments … or…

What I did on my Summer Vacation 🙂

Creating Dynamic UI with Fragments

It’s been a crazy busy Summer. Since May I’ve released 3 new Android courses for Pluralsight with a 4th coming out in a few weeks and wrote a book on Android Fragments titled Creating Dynamic UI with Android Fragments.

I’m excited to announce that the book just became available for pre-order today!!

I need to take a minute to thank my beautiful wife, Bonnie. As you might imagine, I’ve been putting in a lot of hours these past few months and would never have been able to get through it all without her. Her patience and support never end. Bonnie I love you!!

My life is so blessed, I can barely believe it.

Programming Stuff

Switch to Android Studio 0.2.0 a little bumpy

Android Studio 0.2.0 update … encountering issues with both new AND existing projects.

I’m fortunate that  using the latest and (sometimes not so) greatest is actually my job. With that I’ve been able to heavily use Android Studio ever since it was first released. To my knowledge, I’ve installed and heavily used every public update since the release.

Everyone of those updates went pretty smooth … until this one.

The switch to Android Studio 0.2.0 has, by far, been the bumpiest upgrade yet. After installing it…

  • I can’t generate new projects
  • I can’t build existing projects.

Not much I can get done without being able to do one or the other. 🙂

The good news is that resolving these issues was pretty easy.

Can’t generate new projects

This issue appears to be specific to folks using Android Studio on Windows.

I initially let Android Studio handle the install as I had always done previously. Once the install completed, any attempt to create a new project resulted in the following error…

CantGenProjectBadDependencyMSg

Basically, the message indicates that Android Studio can’t find a dependency.

The solution turned out to be that a fresh install is requried ….

  1. I exited all instances of Android Studio
  2. I changed the name of the existing installation folder
    • The default installation folder is
      C:\Users\[user name]\AppData\Local\Android\android-studio
  3. I then downloaded and installed the latest Android Studio installer

And that took care of the problem

Can’t build existing projects

This turned out to be a two-fold problem for me.

The first issue has to do with a fairly well documented change that’s been made to Android Studio. They’ve changed to a new version of Gradle that’s not backward compatible. As a result an attempt to build a project that was created with a prior version of Android Studio shows the following error.

GradleBuildIssue

The fix is to change the version of Gradle that’s referenced in your project’s build.gradle file (located in top-level of project folder). If you click on the “Search in build.gradle files” link in the above dialog it’ll open the build.gradle file for you. Or you can just open the build.gradle file yourself. It’s quite small and easy to navigate.

To fix the problem simply change the line that reads

classpath ‘com.android.tools.build:gradle:0.4

to

classpath ‘com.android.tools.build:gradle:0.5.+’

This will cause Android Studio to use the required version of Gradle.

But trouble continues…

With that fix made, I would then get an error indicating

FAILURE:Could not determine which tasks to execute

The problem is related to extraneous entries that were added to the [ProjectName].iml file (in your project’s top-level folder) by earlier versions of Android Studio.

To fix the problem, exit Android Studio and open the [ProjectName].iml file in an editor and delete the entire component element with the name “FacetManager”.

This changes the file from…

<?xml version="1.0" encoding="UTF-8"?>
<module external.system.id="GRADLE" type="JAVA_MODULE" version="4">
  <!-- *** Remove From here *** -->
  <component name="FacetManager">
    <facet type="android-gradle" name="Android-Gradle">
      <configuration>
        <option name="GRADLE_PROJECT_PATH" value=":" />
      </configuration>
    </facet>
  </component>
  <!-- ***  To Here   *** -->
  <component name="NewModuleRootManager" inherit-compiler-output="true">
    <exclude-output />
    <content url="file://$MODULE_DIR$">
      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
      <excludeFolder url="file://$MODULE_DIR$/build" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
</module>

to

<?xml version="1.0" encoding="UTF-8"?>
<module external.system.id="GRADLE" type="JAVA_MODULE" version="4">
  <component name="NewModuleRootManager" inherit-compiler-output="true">
    <exclude-output />
    <content url="file://$MODULE_DIR$">
      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
      <excludeFolder url="file://$MODULE_DIR$/build" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
</module>

And with that … SUCCESS!!  … I’m now able to build the project without difficulty.

Wrap Up

So the cleanup isn’t too difficult but does require some work. If you’re encountering issues other than those I’ve mentioned above the Android Studio folks have posted a couple of helpful pages addressing a variety of issues

To Learn more about Android programming, checkout Jim’s courses at Pluralsight.

PSAndroid_216x155

Programming Stuff

Android “Master Key” Security Patch Check Available

Odds are that you’ve heard about the security hole that was found to exist in virtually all Android devices that would allow someone to take control of the device.

The good news is that Google has created a patch for the issue and sent it to OEMs. The challenge always comes down to the OEMs getting the patch distributed to our phones and, as always, that is taking time.

It turns out that we can all check to see if we have the patch installed thanks to Bluebox (the folks who discovered the problem) releasing a free app that will check your phone to see if you have the patch.

Although the app is not able to apply the patch because that’s up to the OEM of your device you can at least know where you stand and if you are so inclined start complaining to your carrier that you’d like them to work with the OEM and hurry to get it distributed.

Programming Stuff

Android Studio 0.1.9 Brings the New Resource Directory Dialog Back

If you’ve been working with the last few builds of Android Studio you know that the ability to create new resource directories was broken. The only work-around was a hacky process of going into some of the settings dialogs and creating the folder from there.

Well the 0.1.9 patch just came out and the New Resource Directory dialog is back (actually it came back in the short-lived 0.1.7 release from a few days ago).

NewResourceFolderDlg

I love the way that this is implemented because it takes care of all of that subtle folder naming that goes into resource specialization.

Android’s support for resource specialization is one of the real powers of the platform in my opinion but manually building those names can be easy to mess up. With this dialog you simply select the resource type, the qualifiers and then enter or select (depending on the qualifier) the value to qualify by.

This is a great feature and goes a long way to making one’s life simpler.

For more information on working with Android Studio, check out Jim’s latest course:

Apps with Android Studio