Tag: Android software development

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

How to Clean an Android Studio Project

You’ve probably noticed that Android Studio doesn’t have a “clean” menu option. But we know that, like any build environment, there are intermediate files created that we may want to occasionally remove.

It turns out the solution is the command line. Simply open a command line in your project’s root folder (Usually named something like MyAppProject) and run the following command

gradlew clean

You’ll see something like this…

gradlew_clean

Notice that you get a bit of an unexpected message, “BUILD SUCCESSFUL”. This simply indicates that it has gone through and successfully cleaned out the intermediate files. I’ve found that when dealing with larger projects its not uncommon to reduce the amount of disk space used by the project by 70% or more.

So a bit of an unexpected solution (especially for those who’ve been in a Windows environment for a long time) but an easy one.

To learn more about Android programming, checkout Jim’s Android courses on Pluralsight.

Jim's Android courses on Pluralsight

Jim’s latest book, “Creating Dynamic UI with Android Fragments” is now available on amazon.

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 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

Programming Stuff

Building Apps with Android Studio

My latest Pluralsight course is live today…

Apps with Android Studio

This is part 2 of my series focused on helping developers move from the more traditional development space of Web-based or desktop apps to the world of Mobile on Android.

The series is written from the perspective of a developer coming from a .NET background but is really for anyone with programming experience wanting to learn to program on Android.

Many years ago when I first started teaching and writing training materials, my work was focused on students who were new to programming but for the last decade or so, I’ve been much more focused on advanced and intermediate-to-advanced topics. I had forgotten the joy of breaking concepts down so that they are easily understood by someone new to the environment. Getting to do that again, makes this series is great fun to write.

I feel everything came together on this course and I’m really proud of it. I hope you enjoy it. Part 3 should be available in about a month.

BTW: If you missed the first course in the series, I encourage you to check it out as well. Android for .NET Developers: Getting Started.

Programming Stuff

Android Studio Bug Workaround V2 – Project breaks when copied or moved

As you’ll recall, I posted yesterday about working around the issue in Android Studio where copying a project to a new folder creates problems because the Android Studio project keeps references to the original folder. After my post yesterday, I figured out an easier way to work around the problem.

You still have to modify just as many files but the steps are easier to follow and perform than my suggestion from yesterday.

So the new workaround…

We’ll use the same assumptions as yesterday.

  • The project name is:
    AndroidExample
  • Original project folder:
    C:\Demo\before\AndroidExampleProject
  • Destination project folder:
    C:\Demo\AFTER\AndroidExampleProject

The cool thing about this workaround is that after copying the project to the folder, you always make the same (relatively simple) changes. There’s nothing specific about the destination folder in the changes we make.

Note: I’m including line numbers just as estimates. Your line numbers will almost definitely be different.

Be sure that Android Studio is completely closed.

In both of the following files, change the value for PROJECT_ABSOLUTE_PATH to be blank

  • C:\Demo\AFTER\AndroidExampleProject\AndroidExampleProject.iml (approx. line 7)
  • C:\Demo\After\AndroidExampleProject\AndroidExample\AndroidExample.iml (approx. line 15)

Change:

<option name="PROJECT_ABSOLUTE_PATH" value="C:\Demo\before\AndroidExampleProject" />

To:

<option name="PROJECT_ABSOLUTE_PATH" value="" />

In both of the following files remove the full path before build.gradle (including the slash ” \ “) and replace it with $PROJECT_DIR$/

  • C:\Demo\AFTER\AndroidExampleProject\.idea\gradle.xml (approx. line 6)

Change:

<option name="externalProjectPath" value="C:\Demo\before\AndroidExampleProject\build.gradle" />

To:

<option name="externalProjectPath" value="$PROJECT_DIR$/build.gradle" />
  • C:\Demo\AFTER\AndroidExampleProject\.idea\workspace.xml (approx. line 207)
    • The “option” element you’re changing will be a child of the “ExternalProjectPojo” element

Change:

<option name="path" value="C:\Demo\before\AndroidExampleProject\build.gradle" />

To:

<option name="path" value="$PROJECT_DIR$/build.gradle" />

And with that, you’re ready to open the destination project in Android Studio.

When you save the project, Android Studio will automatically save the new folder as the PROJECT_ABSOLUTE_PATH value.

I’m finding these changes much easier to manage than the ones I walked through yesterday. But as I mentioned yesterday, the best news of all is that I suspect that this will be a short lived bug and we won’t have to deal with this workaround for long.

For information on getting started developing Android applications or working with Android Studio, checkout Jim’s Android programming courses on Pluralsight including his latest course.

Android for .Net Developers Series - Getting Started

Programming Stuff

Android Studio Bug Workaround – Project breaks when copied or moved

Since I write training courses about Android development, I frequently have to copy projects from one folder to another. I commonly create a project in a “before” folder, copy the project to an “after” folder, and then do the work being discussed in the course in the project in the “after” folder. When students view the course they can download “before” and “after” copies of the project.

Well one of the pains I’ve been dealing with in the preview release of Android Studio is the fact that when a project is copied from one folder to another, the project keeps pointers to the original folder. One ends up with a mess where some things in the new project point to the new folder and somethings point to the old. Deleting the original folder makes things even worse.

I’ve reported the issue as an Android Studio bug. It appears to have been accepted as an issue but as of this writing the version of Android Studio currently available still has the problem.

The version available as of this writing…

AndroidStudioAbout_AI-130.700763

I’m certain this is an issue that will be addressed so if you’re reading this post substantially beyond the posting date, verify that the problem still exists before doing the steps I list here.

OK so the workaround…

UPDATE: The day after I made this post, I figured out a simpler work around. Please see this post for the new workaround.

The solution I’ve found is to modify the path information contained in 4 of the project files in the destination folder.

Before doing anything, be sure Android Studio is completely closed.

Let’s make the following Assumptions in copying our project to a new folder.

  • The project name is:
    AndroidExample
  • Original project folder:
    C:\Demo\before\AndroidExampleProject
  • Destination project folder:
    C:\Demo\AFTER\AndroidExampleProject

Note: I’m including line numbers just as estimates. Your line numbers will almost definitely be different.

1. File: C:\Demo\AFTER\AndroidExampleProject\AndroidExampleProject.iml (approx. line 7)

Change:

<option name="PROJECT_ABSOLUTE_PATH" value="C:\Demo\before\AndroidExampleProject" />

To:

<option name="PROJECT_ABSOLUTE_PATH" value="C:\Demo\AFTER\AndroidExampleProject" />

2. File: C:\Demo\AFTER\AndroidExampleProject\.idea\gradle.xml (approx. line 6)

Change:

<option name="externalProjectPath" value="C:\Demo\before\AndroidExampleProject\build.gradle" />

To:

<option name="externalProjectPath" value="C:\Demo\AFTER\AndroidExampleProject\build.gradle" />

3. File: C:\Demo\AFTER\AndroidExampleProject\.idea\workspace.xml(approx. line 207)

Note: The “option” element you’re changing will be a child of the “ExternalProjectPojo” element

Change:

<option name="path" value="C:\Demo\before\AndroidExampleProject\build.gradle" />

To:

<option name="path" value="C:\Demo\AFTER\AndroidExampleProject\build.gradle" />

4. File: C:\Demo\After\AndroidExampleProject\AndroidExample\AndroidExample.iml(approx. line 15)

Change:

<option name="PROJECT_ABSOLUTE_PATH" value="C:\Demo\before\AndroidExampleProject" />

To:

<option name="PROJECT_ABSOLUTE_PATH" value="C:\Demo\AFTER\AndroidExampleProject" />

5.
Now open the project in Android Studio

You may be prompted with a dialog indicating that it’s removing a non-existent project. Let it do that. It’s just cleaning up some internal data, it doesn’t appear to have any impact on the original project.

Voila! We now have a copy of our project.

The best news of all … I’m pretty sure that the bug that’s causing us to have to go through all of these steps (rather than simply copying the project folder) is a bug that will soon be fixed.

For information on getting started developing Android applications or working with Android Studio, checkout Jim’s Android programming courses on Pluralsight including his latest course.

Android for .Net Developers Series - Getting Started