CategoryTutorial

How to add attributes to your custom View

Jack just asked the following questions on the tutorial for animated GIFs I once wrote:

“I want to be able to place the GifMovieView in an existing layout (like any regular control).
Please give me a step-by-step of how to bind xml layout attributes to this custom view.”

A good question. Here’s the answer.

1 Use your own View in an XML

To place your own View in an layout XML file, just use it like a normal view, only that you have to append the whole package name up front. Something like:

< eu.andlabs.tutorial.animatedgifs.views.GifMovieView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/my_id"
/>

In this XML, you can already use the standard Android attributes.

2 Define your custom attributes

If you want to define your own, custom attributes, go to the res/values-folder and create a file called attrs.xml.

You can define your custom attributes here. In the end, it should look like this:

< ?xml version="1.0" encoding="utf-8"?>
< resources>
< declare-styleable name = "eu.andlabs.tutorial.animatedgifs.view.GifMovieView">
< attr name="url" format="string" />
< attr name="fetchAutomatically" format="boolean" />
< /declare-styleable>
< /resources>

You can now address these attributes in your XML layout. To do so, add something like

xmlns:gif="http://schemas.android.com/apk/res-auto"

To your root layout element. Please notice that this only works with ADT 17 and older. Now you can access your attributes in your layout like this:

< eu.andlabs.tutorial.animatedgifs.views.GifMovieView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/my_id"
gif:url="http://mygif.com/mygif.gif"
gif:fetchAutomatically="true" 
/>

3 Handle the attributes in your View

Since the XML is done, it’s time to address the Java part, which means the custom View. You should at least overwrite the constructor that is receiving a Context and an Attributes-object. Like so:

public GifMovieView(final Context context, final AttributeSet attrs) {
super(context, attrs);
init(attrs);
}

You can now access your custom attributes in using the AttributeSet:

private void init(final AttributeSet attrs) {
if (attrs != null) {
String packageName = "http://schemas.android.com/apk/res-auto";
mUrl = attrs.getAttributeValue(packageName, "url");
mFetchAutomatically = attrs.getAttributeBooleanValue(packageName, "fetchAutomatically", false);
}
}

Do whatever is needed with it. That’s already it.

 

I hope you enjoyed this post. Please feel free to ask anything you want in the comments.

And remember: Sharing is caring!

The AndEngine PhysicsEditor Extension

[Update] Now supports circle sprites. Also, Andreas Löw, the creator of PhysicsEditor will link to it with the next update of the editor. [/Update]

If you ever created a physics game, for example with my favorite game engine, AndEngine, and wanted to produce a polygonal body, you probably did something that sucked big time. Something like defining your vertices in code. This is

  1. Dirty
  2. Really painful
This is why we looked around and found the PhysicsEditor, a simple to use tool to create an output that describes physic definitions. While iOS integration seemed to work both from the editor into the code, it only provided an AndEngine Exporter-format, but no tool to integrate it back into the engine.
Until today.

 

Capabilities

Here is what it’s capable of:
  • Definitions of (multiple) bodies
  • Definitions of (multiple) fixtures
  • Definitions of polygon shapes
  • Definitions of circle shapes
  • Definition of density, friction and elasticity
  • Definition of dynamic and non-dynamic bodies
  • Definition of sensor and non-sensor fixtures
  • Collision filtering
  • Automatic setting of a body’s user data

 

How to use it

For this part I assume you already know the very basics of AndEngine development. Let’s start from the beginning.

First, download the PhysicsEditor. Open it and import your sprite of choice. I chose the star from the examples project:

Now, draw your physical representation. You might want to use the Shape tracer for that (the wand icon):Now make your settings on the right

and push ‘publish as’. Save your XML somewhere.

Next, it’s time to get the source. Clone the repository using something like git clone git://github.com/ANDLABS-Git/AndEngine-PhysicsEditor-Extension.git. Import the source. Now, make sure you also have the AndEngine and the AndEnginePhysicsBox2DExtension in your workspace. You may have to update this dependencies.

A good match: PhysicsEditor Extension, Box2D Extension, AndEngine and PhysicsEditor Examples

A good match: PhysicsEditor Extension, Box2D Extension, AndEngine and PhysicsEditor Examples

Now in your project, create a new PhysicsEditorLoader-object using the default constructor:
final PhysicsEditorLoader loader = new PhysicsEditorLoader();
Use it to load whatever you want:

try {
loader.load(this, mPhysicsWorld, "xml/", "star.xml", star, true, true);
} catch (IOException e) {
//...
}

The parameters provided are a Context, the PhysicsWorld you want to attach your body to, the base path, the path to your specific definition, the IAreaShape (for example a Sprite) you want your definition to be connected to, whether you want your object’s position to be updated and whether you want your object’s rotation to be updated. And that’s it.

There are some other use cases covered like drawing lines for debugging or loading multiple definitions, but that’s not more than about five keystrokes of additional work. You can take a look at the examples to see what I mean (in case you are curious).
It is possible to use the PhysicsEditor as a tool for level creation. In fact, it enables you to actually ‘draw’ your levels in your graphics tool of choice. Please keep in mind though that the maximum size of an IAreaShape in AndEngine is 2048 pixels, so you may want to use multiple sprites to achieve big levels. Also, memory is low on mobile devices, depending which device your are targeting, you maybe want to think about using a different method than this.

 

A ball jumping on a polygonal physical representation

A ball jumping on a polygonal physical representation

Please keep in mind that this is a very early release that may still contain some bugs and needs some refactoring. Please feel free to leave any issue you discover in the project’s issue tracker.

So far, we have tested the four sample projects on the following devices:

  • Samsung Galaxy Y (2.3.6)
  • Nexus One (2.3.6)
  • Galaxy Nexus (4.0.4)

The new madvertise SDK: How to migrate

Three days ago, madvertise officially announced the availability of their new SDKs for Android and iOS.

What has changed?

This time, besides minor changes, rich media functionality, or to be more precise, the MRAID v. 1.0-standard, was implemented. For ads this means: They can be completely written in HTML 5 and they can access some extra functionality via JavaScript. With this extra functionality, for MRAID 1.0, ads are able to expand in size up to full screen. However, madvertise takes care that only ads requested in full screen mode will expand themself immediately. For smaller banner formats like MMA, ads will only expand on user interaction.

How to migrate?

First, install git.

Second, learn how to use git. Seriously.

Third: Clone the madvertise repository into your workspace or wherever you want it to be: git clone git://github.com/madvertise/madvertise-android-sdk.git. In case you already cloned the repository once, pull the new changes.

Now switch to the new mad_mraid10- branch: git checkout mad_mraid10

Import the SDK using new -> Android Project -> from existing source. In case you just pulled in step three, just select your madvertise SDK-project and hit F5. In the SDK Project you should now see a new class called MadvertiseMraidView.java. In the projects integrating the madvertise SDK as a source project, you should see some compile errors at the places where you implemented the MadvertiseCallbackListener. Add the unimplemented methods. They are:

public void onAdClicked()
public void onApplicationPause()
public void onApplicationResume()

onAdClicked() is, obviously, called when an ad is clicked by a user. In this method you can track ad clicks or reward your users by removing the ad for a couple of seconds. In case you want to do so I recommend something like
mMadView.setFetchingAdsEnabled(false);
mMadView.setVisibility(View.GONE);

setFetchingAdsEnabled(boolean isEnabled) allows you to stop fetching ads for a given MadvertiseView or to start it again.
onApplicationPause() is called when a rich media ad is expanded and the actual app content is not in the foreground anymore. The easyest construct here is to directly call onPause() from this method. onApplicataionResume() is the corresponding counterpart to onResume().

Lets look into the XML code, first into the attrs.xml. Here, add < attr name="placement_type" format="string" /> and < attr name="mraid" format="boolean" />. Obviously, you can include those values into your layout files as well:
mad:placement_type="interstitial"
mad:mraid="true"

Placement type declares how you plan to place your rich media ads. Interstitial is perfect when loading something and showing an ad in the meantime, for example full screen. Inline is more suitable for most of the other cases. With the mraid-attribute you declare whether you want rich media ads to be delivered to your app or not. In other words: If you want everything to stay the way it was, set mad:mraid="false". The default for this attribute is true, so if you want rich media functionality, you can leave your layout files just the way they were. With one exception: In case you already upgraded to SDK tools in revision 17, you should now replace the ‘xmlns:mad=...‘-namespace with xmlns:mad="http://schemas.android.com/apk/res-auto".

And that’s already it.

Conclusion

madvertise’s eCPMs and fillrates really sucked in the last months. However, the company doesn’t give up and promises higher costs per click for the new rich media ads. I hope they keep their word and that the rich media ads won’t be too annoying. Let me know what you think (and hope) in the comments.

Tutorial: How to play animated GIFs in Android – Part 3

Animated GIFs in Android is a difficult topic. It is an issue that has been discussed heavily and still, it is very difficult for developers to bring GIFs to life. There are three ways to animate GIFs on Android, each of them has its pros and cons. Each part of this series will cover one of these approaches.

Getting started

For this example, we will use an image I found on gifs.net, it’s this one:

I will store it in our project’s asset folder and name it ‘piggy.gif’. We will also use an Activity to set the views we define as content views. If you want to know everything about playing GIFs, please start at part one.

Approach 3: Using a WebView

This is the by far easyest way. As you might know, a WebView is able to do what a browser does. And since the browser of Android devices using Android 2.2 + supports the animation of GIFs (at least on most devices), we can just use that.

So, at first, we extend our own class by a WebView:

public class GifWebView extends WebView

We create a constructor that takes both a context to call the constructor of the mother-class and a path to the file. We use loadUrl() to load that file into our WebView:

   public GifWebView(Context context, String path) {
      super(context);
      loadUrl(path);
   }

Now, let’s go back to our Activity which we created in the first tutorial. Here, we create our view and pass it a context and path to our GIF-file:

   GifWebView view = new GifWebView(this, "file:///android_asset/piggy.gif");
   setContentView(view);

And now, believe it or not, we are done.

Movie, GifDecoder or WebView?

Which way you take depends on your needs. When your app is targeting users mainly using devices with Android 2.2+, the way described above is probably your way to go. If you want to support as many devices as possible and don’t care much about memory footprint, you can also use the GifDecoder-method. When you want to support many users but don’t want to recycle tons of Bitmaps, and are sure the format of your GIFs can be played using the Movie-class, then this approach is for you.

Personally, I prefer the WebView-way. Because WebKit is already implemented native, it’s memory footprint is really low, especially when compared to the GifDecoder. Operations on images like scaling can be performed simply by using HTML and the overall code is really short and pretty.

 

You can checkout the code of the three parts of this series at http://code.google.com/p/animated-gifs-in-android/.

 

Which method do you like best? As always, please feel free to leave your thoughts in the comments.

© 2024 Droid-Blog

Theme by Anders NorenUp ↑