Archives for posts with tag: android

I was trying to add a custom font to the LunchTable app when an exception thrown by Typeface.createFromAsset gave me “Native typeface cannot be made.” For me, this was related to Gradle.

The solution was simple: I moved my assets folder directly under main, at the same level as java and res. It might not be necessary, but my .ttf file was in assets/fonts/, as well.

$ logout

Advertisements

There is an issue with the Sony Xperia Z (C6833) keyboard that causes any EditText using an InputFilter to misbehave. For example, typing h-e-l-l-o in one of these fields comes out as hhehelhellhello.

In order to keep my filtering functionality (I want to only allow alphanumeric characters), I removed my old code ( myText.setFilters(new InputFilter[] { ... }); ) and made a few simple changes to any EditTexts I need filtered so they look like this:

<EditText
    android:digits="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    android:singleLine="true"
    android:imeOptions="actionNext"
    />

The android:digits property does the filtering here. Give it any and all valid characters you want to accept, and for extra credit, throw it in a string resource to reduce copy-and-paste errors.

If you’d like the “Next” button to show on your user’s keyboard for this field, android:imeOptions="actionNext" alone isn’t going to cut it—the android:digits property causes the keyboard to show an Enter key on every device I tested, so throw in android:singleLine="true" to fix it.

$ logout

Sometimes error messages don’t really do their job and tell you how to rectify them, like this one I found today in Android Studio (v0.4.5). While attempting to add a page indicator for my ViewPager, I got “CirclePageIndicator is not allowed here.”

Way to be ambiguous...

As it turns out, this is less about Mama Android telling you where to put your controls, and more about using the correct namespace when adding controls (I had only copied over this class, not the whole project).

Mind your namespaces!

$ logout

After creating a new project in Android Studio 0.3.1 utilizing Gradle, opening the project on a new machine gave me a few problems.

First, I got: Gradle could not resolve all dependencies.

To fix this, I opened the SDK Manager and downloaded the Android Support Library, since com.android.support:appcompat-v7 isn’t in Maven Central.

Next, I got: Could not execute build using gradle installation.

To fix this, I opened a terminal and ran gradle build. Ubuntu informed me it wasn’t installed, so I:

  1. downloaded it
  2. moved it to /opt/gradle
  3. went to Settings > Gradle in Android Studio
  4. under Project-level settings, selected Use local gradle distribution
  5. changed both Gradle home and Service directory path to /opt/gradle
  6. restarted Android Studio

And everything worked!

$ logout

In case you want to make a TextView clickable, simply setting an onClick handler won’t do it. Make sure you set your android:clickable attribute:

...
android:onClick="doMagicalThings"
android:clickable="true"
...

$ logout

In one app I’m working on, we’re using a ListView to display a near-realtime stream of posts by various users. However, with constant updates, it was easy for any post a user is reading to get bumped down out of view due to new items being added at the top. This is how I fixed it.

The flow to this solution is:

  1. Finding what index of the list we’re currently scrolled to (+/- the pixel offset, for more exactness),
  2. Adding our new posts at the top,
  3. Doing a notifyDataSetChanged(),
  4. Waiting for our new items to be drawn to calculate our new scroll position.

We’ll start before our for loop / add()ing block, inside the method that checks for new posts (in our case, onLoadFinished()):

// Set up vars to track current scroll position / number of
// posts already displayed
boolean newPosts = false;
int scrolledToIndex = 0;
int topOffset = 0;
int startCount = mAdapter.getCount();

// If we've received new posts, we'll set our current scroll
// values:
if (/* ...we've detected new posts... */) {
    scrolledToIndex = getListView().getFirstVisiblePosition();
    View v = getListView().getChildAt(0);
    topOffset = (v == null) ? 0 : v.getTop();

    newPosts = true;

    // Add new posts...
}

// Update the ListView
mAdapter.notifyDataSetChanged();

// Get number of new posts
int delta = mAdapter.getCount() - startCount;

// Set final variables
final int finalTopOffset = topOffset;
// The index of our first visible post has changed by delta
final int finalScrollToIndex = scrolledToIndex + delta;

// Wait until list has drawn our new posts before scrolling
// to our previous location
getListView().post(new Runnable() {
    @Override
    public void run() {
        try {
            getListView().setSelectionFromTop(finalScrollToIndex, finalTopOffset);
        } catch (IllegalStateException e) {}
    }
});

$ logout