Faster Loading images in GridViews or ListViews in Android using Menory Caching, Complete implemenation with sample code.

Hi all

This example shows you how to load large images in the gridview without any lag or without outofmemory error.

Fast Grid

This sample application uses the LruCache to hold the images.

A cache that holds strong references to a limited number of values. Each time a value is accessed, it is moved to the head of a queue. When a value is added to a full cache, the value at the end of that queue is evicted and may become eligible for garbage collection.

Read more from here.

http://developer.android.com/reference/android/util/LruCache.html

Now we will go to the implementation.

This is the MainActivity that holds the GridView.
We are adding here 100 images in the Grid to load.
This time I am loading images from the resources.

Everything is explained with in the code itself, So I am not adding more description here

MainActivity.java

package com.coderzheaven.testlistview;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.widget.GridView;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);

		ArrayList<String> items = new ArrayList<String>();

		// adding 100 images
		for (int p = 0; p < 100; p++) {
			items.add("photo");
		}

		ListAdapter list = new ListAdapter(this, items);

		GridView grid = new GridView(this);

		grid.setAdapter(list);

		grid.setNumColumns(GridView.AUTO_FIT);

		setContentView(grid);

	}

}

OK Now that our Activity is complete we will see the ListAdapter class that is processing each image and helps loading fast.

ListAdapter.java

package com.coderzheaven.testlistview;

import java.lang.ref.WeakReference;
import java.util.ArrayList;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.util.LruCache;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridLayout.LayoutParams;
import android.widget.GridView;
import android.widget.ImageView;

public class ListAdapter extends BaseAdapter {

	Context context;
	ArrayList<String> items;
	private LruCache<String, Bitmap> mMemoryCache;

	public ListAdapter(Context context, ArrayList<String> items) {
		this.context = context;
		this.items = items;

		// Get memory class of this device, exceeding this amount will throw an
		// OutOfMemory exception.
		final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

		// Use 1/8th of the available memory for this memory cache.
		final int cacheSize = maxMemory / 8;

		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {

			protected int sizeOf(String key, Bitmap bitmap) {
				// The cache size will be measured in bytes rather than number
				// of items.
				return bitmap.getByteCount();
			}

		};
	}

	@Override
	public int getCount() {
		return items.size();
	}

	@Override
	public Object getItem(int arg0) {
		return items.get(arg0);
	}

	@Override
	public long getItemId(int arg0) {
		return arg0;
	}

	@Override
	public View getView(int arg0, View convertView, ViewGroup arg2) {
		ImageView img = null;

		if (convertView == null) {
			img = new ImageView(context);
			img.setScaleType(ImageView.ScaleType.CENTER_CROP);
			img.setLayoutParams(new GridView.LayoutParams(
					LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		} else {
			img = (ImageView) convertView;
		}

		int resId = context.getResources().getIdentifier(items.get(arg0),
				"drawable", context.getPackageName());

		loadBitmap(resId, img);

		return img;
	}

	public void loadBitmap(int resId, ImageView imageView) {
		if (cancelPotentialWork(resId, imageView)) {
			final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
			imageView.setBackgroundResource(R.drawable.empty_photo);
			task.execute(resId);
		}
	}

	static class AsyncDrawable extends BitmapDrawable {
		private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

		public AsyncDrawable(Resources res, Bitmap bitmap,
				BitmapWorkerTask bitmapWorkerTask) {
			super(res, bitmap);
			bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
					bitmapWorkerTask);
		}

		public BitmapWorkerTask getBitmapWorkerTask() {
			return bitmapWorkerTaskReference.get();
		}
	}

	public static boolean cancelPotentialWork(int data, ImageView imageView) {
		final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

		if (bitmapWorkerTask != null) {
			final int bitmapData = bitmapWorkerTask.data;
			if (bitmapData != data) {
				// Cancel previous task
				bitmapWorkerTask.cancel(true);
			} else {
				// The same work is already in progress
				return false;
			}
		}
		// No task associated with the ImageView, or an existing task was
		// cancelled
		return true;
	}

	private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
		if (imageView != null) {
			final Drawable drawable = imageView.getDrawable();
			if (drawable instanceof AsyncDrawable) {
				final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
				return asyncDrawable.getBitmapWorkerTask();
			}
		}
		return null;
	}

	public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
		if (getBitmapFromMemCache(key) == null) {
			mMemoryCache.put(key, bitmap);
		}
	}

	public Bitmap getBitmapFromMemCache(String key) {
		return (Bitmap) mMemoryCache.get(key);
	}

	class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
		public int data = 0;
		private final WeakReference<ImageView> imageViewReference;

		public BitmapWorkerTask(ImageView imageView) {
			// Use a WeakReference to ensure the ImageView can be garbage
			// collected
			imageViewReference = new WeakReference<ImageView>(imageView);
		}

		// Decode image in background.
		@Override
		protected Bitmap doInBackground(Integer... params) {
			data = params[0];
			final Bitmap bitmap = decodeSampledBitmapFromResource(
					context.getResources(), data, 100, 100);
			addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
			return bitmap;
		}

		// Once complete, see if ImageView is still around and set bitmap.
		@Override
		protected void onPostExecute(Bitmap bitmap) {
			if (imageViewReference != null && bitmap != null) {
				final ImageView imageView = imageViewReference.get();
				if (imageView != null) {
					imageView.setImageBitmap(bitmap);
				}
			}
		}
	}

	public static Bitmap decodeSampledBitmapFromResource(Resources res,
			int resId, int reqWidth, int reqHeight) {

		// First decode with inJustDecodeBounds=true to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeResource(res, resId, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth,
				reqHeight);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeResource(res, resId, options);
	}

	public static int calculateInSampleSize(BitmapFactory.Options options,
			int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {

			// Calculate ratios of height and width to requested height and
			// width
			final int heightRatio = Math.round((float) height
					/ (float) reqHeight);
			final int widthRatio = Math.round((float) width / (float) reqWidth);

			// Choose the smallest ratio as inSampleSize value, this will
			// guarantee
			// a final image with both dimensions larger than or equal to the
			// requested height and width.
			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
		}

		return inSampleSize;
	}

}

You can download the sample android source code from here.

Please leave your comments. I will be adding a modified version of this sample for using it to download from a URL and caching it in the disk and Memory in the coming posts.

What is a Memory Heap Size in android? and how can use Bitmap Efficiently?

Memory Heap Size

Android is a full multitasking system so it’s possible to run multiple programs at the same time and obviously each one can’t use all of your device memory.
For this reason there is a hard limit on your Android application’s heap size: if your application needs to allocate more memory and you have gone up to that heap size already, you are basically going to get a “out of memory error”.
Heap size limit is device dependent and it has changed a lot over the years, the first Android phone (the G1) has 16MB heap size limit, now we have tablets like Motorola Xoom that have 48MB heap size limit.
The basic reason is that new tablets and new phones have an high monitor resolution so they need more memory in order to draw more pixels.
However this limit is also too tight for a new kind of application that you can image for a tablet. For example, think about a photo editor that is really memory intensive, probably 48MB of heap space isn’t enough for that.
For that kind of application Honeycomb introduced an option in the Android Manifest: “android:largeHeap=true” that give you a big heap space limit.”
This doesn’t mean that if you get an “out of memory error” you can fix it simply setting this option!
You have to use this option only if you are going to build an application that is really memory intensive and you really need it.
When you develop an application you have to think that your application will run on a very large set of different devices with different capability and different heap size limit, so you need to worry about that and a simple thing you can do it’s provide your bitmap resources in all the different resolution ldpi, mdpi, hdpi, xhdpi.

Handle bitmap efficiently

If you’re not careful, bitmaps can quickly consume your available memory budget leading to an application crash due to the dreaded exception: “java.lang.OutofMemoryError: bitmap size exceeds VM budget”.

Images come in all shapes and sizes. In many cases they are larger than required for a typical application user interface (UI).
Given that you are working with limited memory, the best thing that you can do is to load a lower resolution version into the memory. The lower resolution version should match the size of the UI component that displays it. An image with an higher resolution does not provide any visible benefit, but still takes up precious memory and incurs additional performance overhead due to additional on the fly scaling.
The BitmapFactory class provides several decoding methods (decodeByteArray(), decodeFile(),decodeResource(), etc.) for creating a Bitmap from various sources.
Each type of decode method has additional signatures that let you specify the decoding options via BitmapFactory.Options class.
Setting the inJustDecodeBounds property to true while decoding avoids memory allocation, returning null for the bitmap object but setting outWidth, outHeight and outMimeType. This technique allows you to read the dimensions and type of the image data before the construction (and memory allocation) of the bitmap.
Now that the image dimensions are known, they can be used to decide if we should load the full image or a subsampled version, into the memory. To tell the decoder to subsample the image, loading a smaller version into memory, set inSampleSize to the scale factor in your BitmapFactory.Options object.
The code below shows how to load an Image of arbitrarily large size to a bitmap of the reqWidth and reqHeight.
The calcualteInSampleSize just determinates the scale factor from the original size and the requested size.

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
 
    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
 
    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

References:

http://android-developers.blogspot.it/2011/03/memory-analysis-for-android.html

http://android-developers.blogspot.it/2009/01/avoiding-memory-leaks.html

http://developer.android.com/training/displaying-bitmaps/index.html

FlipCard animation using Fragments in Android.

Hello all

I am back with fragments again. I know you have seen a lot of posts on fragments and fragment animation.

This one will be another useful post for you.

This post helps you to show a FlipCard animation using Fragments.

Let us see how can we do this.

At first I will show the activity that I am using to create Animation which contain two fragments for Front and Back Page.

CardFlipActivity.java


package com.example.cardflipanimation;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.NavUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

public class CardFlipActivity extends Activity implements
		FragmentManager.OnBackStackChangedListener {
	/**
	 * A handler object, used for deferring UI operations.
	 */
	private Handler mHandler = new Handler();

	/**
	 * Whether or not we're showing the back of the card (otherwise showing the
	 * front).
	 */
	private boolean mShowingBack = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_card_flip);

		if (savedInstanceState == null) {
			// If there is no saved instance state, add a fragment representing
			// the
			// front of the card to this activity. If there is saved instance
			// state,
			// this fragment will have already been added to the activity.
			getFragmentManager().beginTransaction()
					.add(R.id.container, new CardFrontFragment()).commit();
		} else {
			mShowingBack = (getFragmentManager().getBackStackEntryCount() > 0);
		}

		// Monitor back stack changes to ensure the action bar shows the
		// appropriate
		// button (either "photo" or "info").
		getFragmentManager().addOnBackStackChangedListener(this);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		// Add either a "photo" or "finish" button to the action bar, depending
		// on which page
		// is currently selected.
		MenuItem item = menu.add(Menu.NONE, R.id.action_flip, Menu.NONE,
				mShowingBack ? R.string.action_photo : R.string.action_info);
		item.setIcon(mShowingBack ? R.drawable.ic_action_photo
				: R.drawable.ic_action_info);
		item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			// Navigate "up" the demo structure to the launchpad activity.
			// See http://developer.android.com/design/patterns/navigation.html
			// for more.
			NavUtils.navigateUpTo(this,
					new Intent(this, CardFlipActivity.class));
			return true;

		case R.id.action_flip:
			flipCard();
			return true;
		}

		return super.onOptionsItemSelected(item);
	}

	private void flipCard() {
		if (mShowingBack) {
			getFragmentManager().popBackStack();
			return;
		}

		// Flip to the back.

		mShowingBack = true;

		// Create and commit a new fragment transaction that adds the fragment
		// for the back of
		// the card, uses custom animations, and is part of the fragment
		// manager's back stack.

		getFragmentManager().beginTransaction()

		// Replace the default fragment animations with animator resources
		// representing
		// rotations when switching to the back of the card, as well as animator
		// resources representing rotations when flipping back to the front
		// (e.g. when
		// the system Back button is pressed).
				.setCustomAnimations(R.animator.card_flip_right_in,
						R.animator.card_flip_right_out,
						R.animator.card_flip_left_in,
						R.animator.card_flip_left_out)

				// Replace any fragments currently in the container view with a
				// fragment
				// representing the next page (indicated by the just-incremented
				// currentPage
				// variable).
				.replace(R.id.container, new CardBackFragment())

				// Add this transaction to the back stack, allowing users to
				// press Back
				// to get to the front of the card.
				.addToBackStack(null)

				// Commit the transaction.
				.commit();

		// Defer an invalidation of the options menu (on modern devices, the
		// action bar). This
		// can't be done immediately because the transaction may not yet be
		// committed. Commits
		// are asynchronous in that they are posted to the main thread's message
		// loop.
		mHandler.post(new Runnable() {
			@Override
			public void run() {
				invalidateOptionsMenu();
			}
		});
	}

	@Override
	public void onBackStackChanged() {
		mShowingBack = (getFragmentManager().getBackStackEntryCount() > 0);

		// When the back stack changes, invalidate the options menu (action
		// bar).
		invalidateOptionsMenu();
	}

	/**
	 * A fragment representing the front of the card.
	 */
	public static class CardFrontFragment extends Fragment {
		public CardFrontFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			return inflater.inflate(R.layout.fragment_card_front, container,
					false);
		}
	}

	/**
	 * A fragment representing the back of the card.
	 */
	public static class CardBackFragment extends Fragment {
		public CardBackFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			return inflater.inflate(R.layout.fragment_card_back, container,
					false);
		}
	}
}

Now the animations.
For that you have to create 4 xml animation files in the res/animator folder.

card_flip_left_in.xml
card_flip_left_out.xml
card_flip_right_in.xml
card_flip_right_out.xml

I will be listing these files in this order.

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Before rotating, immediately set the alpha to 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="-180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Rotate. -->
    <objectAnimator android:valueFrom="0"
        android:valueTo="180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full"></objectAnimator>

    <!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
    <objectAnimator android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1"></objectAnimator>
</set>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Before rotating, immediately set the alpha to 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="0"
        android:valueTo="-180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

Inside the drawable folder put these images.

ic_action_info.png
ic_action_photo.png
image1.png

Put these inside the ids.xml folder inside the res/values folder.

    <item type="id" name="action_next" />
    <item type="id" name="action_flip" />

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">CardFlipAnimation</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="action_info">Photo info</string>
    <string name="action_photo">View photo</string>

</resources>

And also integers.xml

<resources>
    <integer name="card_flip_time_full">300</integer>
    <integer name="card_flip_time_half">150</integer>
</resources>

Download the complete android source code from here.

Process lifecycle in Android and Different types of processes.

The Android system tries to maintain an application process for as long as possible, but eventually needs to remove old processes to reclaim memory for new or more important processes. To determine which processes to keep and which to kill, the system places each process into an “importance hierarchy” based on the components running in the process and the state of those components. Processes with the lowest importance are eliminated first, then those with the next lowest importance, and so on, as necessary to recover system resources.

There are five levels in the importance hierarchy. The following list presents the different types of processes in order of importance (the first process is most important and is killed last ):

Foreground process A process that is required for what the user is currently doing. A process is considered to be in the foreground if any of the following conditions are true:

It hosts an Activity that the user is interacting with (the Activity ‘s onResume() method has been called).

It hosts a Service that’s bound to the activity that the user is interacting with.

It hosts a Service that’s running “in the foreground”—the service has called startForeground() .

It hosts a Service that’s executing one of its lifecycle callbacks ( onCreate() , onStart() , or onDestroy() ).

It hosts a BroadcastReceiver that’s executing its onReceive() method.

Generally, only a few foreground processes exist at any given time. They are killed only as a last resort—if memory is so low that they cannot all continue to run. Generally, at that point, the device has reached a memory paging state, so killing some foreground processes is required to keep the user interface responsive.

Visible process A process that doesn’t have any foreground components, but still can affect what the user sees on screen. A process is considered to be visible if either of the following conditions are true:

It hosts an Activity that is not in the foreground, but is still visible to the user (its onPause() method has been called). This might occur, for example, if the foreground activity started a dialog, which allows the previous activity to be seen behind it.

It hosts a Service that’s bound to a visible (or foreground) activity.

A visible process is considered extremely important and will not be killed unless doing so is required to keep all foreground processes running.

Service process A process that is running a service that has been started with the startService() method and does not fall into either of the two higher categories. Although service processes are not directly tied to anything the user sees, they are generally doing things that the user cares about (such as playing music in the background or downloading data on the network), so the system keeps them running unless there’s not enough memory to retain them along with all foreground and visible processes.

Background process A process holding an activity that’s not currently visible to the user (the activity’s onStop() method has been called). These processes have no direct impact on the user experience, and the system can kill them at any time to reclaim memory for a foreground, visible, or service process. Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state.

Empty process A process that doesn’t hold any active application components. The only reason to keep this kind of process alive is for caching purposes, to improve startup time the next time a component needs to run in it. The system often kills these processes in order to balance overall system resources between process caches and the underlying kernel caches.

Android ranks a process at the highest level it can, based upon the importance of the components currently active in the process. For example, if a process hosts a service and a visible activity, the process is ranked as a visible process, not a service process.

In addition, a process’s ranking might be increased because other processes are dependent on it—a process that is serving another process can never be ranked lower than the process it is serving. For example, if a content provider in process A is serving a client in process B, or if a service in process A is bound to a component in process B, process A is always considered at least as important as process B.

Because a process running a service is ranked higher than a process with background activities, an activity that initiates a long-running operation might do well to start a service for that operation, rather than simply create a worker thread—particularly if the operation will likely outlast the activity. For example, an activity that’s uploading a picture to a web site should start a service to perform the upload so that the upload can continue in the background even if the user leaves the activity. Using a service guarantees that the operation will have at least “service process” priority, regardless of what happens to the activity. This is the same reason that broadcast receivers should employ services rather than simply put time-consuming operations in a thread.

How to write multilingual Android apps?

To build multilingual Android apps you need to collect the texts into resource files and translate them.

Once you provide the translation, Android OS will choose the resources that match user’s locale. If your application is available in several languages, Android will select the language that the device uses.

In this tutorial, we’ll cover:

  • Application localization process
  • Translating strings
  • Localizing images
  • Running and testing the localized application

In order to have a multilingual Android app you need to provide Android with the localized resource files.

If the locale is ‘en-US’, Android will look for a value of “R.string.title” by searching the files in the following order:

  • ‘res/values-en-rUS/strings.xml’
  • ‘res/values-en/strings.xml’
  • ‘res/values/strings.xml’

  • Translating Strings

    For example if an application requires four strings.xml files, one for each in English, Italian, French, and Russian.

    The procedure for creating strings.xml files is as follows:

    • Translate the strings.xml file to each language
    • Create three new folders under res – values-it, values-fr and values-ru (The original values folder already exists).
    • Place the translated strings.xml files in the respective folders.

    Localizing Images

    If our application also needs six more drawable folders, each containing a variant of the background image.

    Place background image that has to appear for a respective language in corresponding folders under the project workspace of the application as specified in below Table.

    If your images contain texts, we recommend creating copies of the texts in your strings.xml file. This way, translators can translate just the texts, and you can rebuild the localized images.

    Background image Destination folder in project workspace
    Italian drawable-it-rIT/background.png
    French drawable-fr-rFR/background.png
    French (Canada) drawable-fr-rCA/background.png
    English (Canada) drawable-en-rCA/background.png
    Russian drawable-ru-rRU/background.png
    US English drawable-en-rUS/background.png
    Default (Earth image) drawable/background.png

    Running and Testing the Localized Application

    Once the localized string and image resources are added to the project workspace, the application is ready for testing. To test it, we can set different locales via Home > Menu > Settings > Locale & text > Select locale.

    Depending on configuration of the device, some devices may offer only a few locales or may not offer any alternate locales via the settings application. However, the Android emulator will offer a selection of all the locales that are available in Android OS. To set the emulator to a locale that is not available in the system image, you can use Custom Locale, available in the Application tab.

    Hope you enjoyed this post, Please leave a comment at the end.

    What are the main differences between a service and an Intent Service and when you should use it?

    Service is a base class of service implementation. Service class is run in the application’s main thread which may reduce the application performance. Thus, IntentService, which is a direct subclass of Service is borned to make things easier. The IntentService is used to perform a certain task in the background. Once done, the instance of IntentService terminate itself automatically. Examples for its usage would be to download a certain resources from the Internet.

    Differences

    Service class uses the application’s main thread, while IntentService creates a worker thread and uses that thread to run the service.

    IntentService creates a queue that passes one intent at a time to onHandleIntent(). Thus, implementing a multi-thread should be made by extending Service class directly. Service class needs a manual stop using stopSelf(). Meanwhile, IntentService automatically stops itself when there is no intent in queue.

    IntentService implements onBind() that returns null. This means that the IntentService can not be bound by default.

    IntentService implements onStartCommand() that sends Intent to queue and to onHandleIntent(). In brief, there are only two things to do to use IntentService. Firstly, to implement the constructor. And secondly, to implement onHandleIntent(). For other callback methods, the super is needed to be called so that it can be tracked properly.

    In short
    A Service is a broader implementation for the developer to set up background operations, while an IntentService is useful for “fire and forget” operations, taking care of background Thread creation and cleanup.

    From the docs:

    Service A Service is an application component representing either an application’s desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.

    IntentService IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

    What is the difference between Services, Thread and an AsyncTask in Android?

    Service is like an Activity but has no interface. Probably if you want to fetch the weather for example you won’t create a blank activity for it, for this you will use a Service.

    A Thread is a Thread, probably you already know it from other part. You need to know that you cannot update UI from a Thread. You need to use a Handler for this, but read further.

    An AsyncTask is an intelligent Thread that is advised to be used. Intelligent as it can help with it’s methods, and there are two methods that run on UI thread, which is good to update UI components.

    Handling Multiple Instances of a Widget in Android and Identifying each instance with it’s own ID.

    Hey everyone…….Hope all are well…..

    This post is about Android Widgets.
    This is going to be one of the bigger posts in Coderzheaven.

    This posts helps you to handle multiple instances of a Widget.
    Many of our problem is to identify different instances of the same widget.

    But there is a solution to this problem.

    Please check out my other posts in Coderzheaven to get an Idea of Android Widgets and it’s working.

    Create new Widget

    http://www.coderzheaven.com/2012/06/15/placing-controls-widget-android-listening-events-them/

    How to get Notified when a widget is deleted?

    Android Multiple Instance Widget

    Android Multiple Instance Widget

    Android Multiple Instance Widget

    Android Multiple Instance Widget

    Here is how we start.

    First of all you need to keep these things about the Widget in Mind.

      1. Every instance of Same Widget is associated with a Unique ID.
      2. Widgets ID’s are sent through in the activities that has the “android.appwidget.action.APPWIDGET_CONFIGURE” intent-filter.
      3. RESULT_OK should sent back to the widget

    Now we will start.

    First we will look at the layouts.

    This is the Widget Layout.
    widget_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/widget_root"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:baselineAligned="false"
        android:orientation="vertical"
        android:background="@drawable/theme0" >
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Widget Text"
            android:gravity="center"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    
    </LinearLayout>
    

    Now the widgetprovider XML.

    <?xml version="1.0" encoding="utf-8"?>
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="250dip"
        android:minHeight="72dip"
        android:updatePeriodMillis="100000"
        android:configure="com.coderzheaven.multiplewidgetinstance.SettingsPage" 
        android:initialLayout="@layout/widget_main"
    /> 
    

    Please note that you have to use the exact package name with the class named you used as Configure Intent-filter in the “android:configure” property.

    Now the XML for the settings Page.

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="20dp"
        tools:context=".MainActivity" 
        android:background="@drawable/theme0">
    
        <TextView
            android:id="@+id/id_tv"
            android:paddingBottom="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:textStyle="bold"
            android:textSize="18dp"
            android:text="@string/hello_world" />
    
        <EditText
            android:id="@+id/editText1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/id_tv"
            android:ems="10" >
    
            <requestFocus />
        </EditText>
    
        <Button
            android:id="@+id/button1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/editText1"
                android:textStyle="bold"
            android:text="Save" />
    
    </RelativeLayout>
    

    Please check the above screenshot how it looks like when clicking on the widget.
    It is having an edittext in which we will enter the value for the widget.

    Our all layout xml are now complete.
    Now we will go to the java classes.

    We will write the MyAppWidgetProvider class

    MyAppWidgetProvider.java

    package com.coderzheaven.multiplewidgetinstance;
    
    import android.appwidget.AppWidgetManager;
    import android.appwidget.AppWidgetProvider;
    import android.content.Context;
    import android.content.Intent;
    
    public class MyAppWidgetProvider extends AppWidgetProvider {
    
    	@Override
    	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
    			int[] appWidgetIds) {
    	}
    
    	/*
    	 * This is called when an instance the App Widget is created for the first
    	 * time.
    	 */
    	@Override
    	public void onEnabled(Context context) {
    		super.onEnabled(context);
    	}
    
    	/*
    	 * This is called for every broadcast and before each of the above callback
    	 * methods.
    	 */
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		super.onReceive(context, intent);
    	}
    
    	/*
    	 * This is called When all instances of App Widget is deleted from the App
    	 * Widget host.
    	 */
    	@Override
    	public void onDisabled(Context context) {
    		// Unschedule any timers and tasks
    		super.onDisabled(context);
    	}
    
    	/*
    	 * This is called every time an App Widget is deleted from the App Widget
    	 * host.
    	 */
    	@Override
    	public void onDeleted(Context context, int[] appWidgetIds) {
    		// Unschedule any timers and tasks
    		super.onDeleted(context, appWidgetIds);
    	}
    }
    

    Please make sure you read the comments in this java, so I am providing any description for that.

    Now the SettingsPage that edit the widget.

    package com.coderzheaven.multiplewidgetinstance;
    
    import android.app.Activity;
    import android.app.PendingIntent;
    import android.appwidget.AppWidgetManager;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.RemoteViews;
    import android.widget.TextView;
    
    public class SettingsPage extends Activity {
    
    	int thisWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    	public static String ACTION_WIDGET_CONFIGURE = "WIDGET_CONFIGURED";
    	SharedPreferences customSharedPreference;
    	EditText ed = null;
    	Button save = null;
    	TextView widgetId = null;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		ed = (EditText) findViewById(R.id.editText1);
    		save = (Button) findViewById(R.id.button1);
    		widgetId = (TextView) findViewById(R.id.id_tv);
    
    		save.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				updateWidget();
    				if (ed.getText().toString().trim().length() > 0) {
    					saveToPreferences("Widget" + thisWidgetId, ed.getText()
    							.toString().trim());
    
    					setResultDataToWidget(RESULT_OK);
    				} else
    					setResultDataToWidget(RESULT_CANCELED);
    			}
    		});
    
    		getIdOfCurrentWidget(savedInstanceState);
    
    	}
    
    	/** Get the Id of Current Widget from the intent of the Widget **/
    	void getIdOfCurrentWidget(Bundle savedInstanceState) {
    
    		setResult(RESULT_CANCELED);
    
    		Bundle extras = getIntent().getExtras();
    
    		if (extras != null) {
    			thisWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
    					AppWidgetManager.INVALID_APPWIDGET_ID);
    			if (getWidgetData("Widget" + thisWidgetId) != null) {
    				save.setText("Update");
    				ed.append(getWidgetData("Widget" + thisWidgetId));
    			}
    
    			widgetId.setText("Widget ID = " + thisWidgetId);
    		}
    
    		// If they gave us an intent without the widget id, just bail.
    		if (thisWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
    			finish();
    		}
    
    	}
    
    	/**
    	 * Update the Current Widget - This is very important to ensure the widget
    	 * is enabled
    	 **/
    	void updateWidget() {
    		AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
    		RemoteViews remoteViews = new RemoteViews(getPackageName(),
    				R.layout.widget_main);
    		Intent clickIntent = getIntent();
    		clickIntent.setAction(ACTION_WIDGET_CONFIGURE);
    		remoteViews.setTextViewText(R.id.textView1, ed.getText().toString()
    				.trim());
    		clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, thisWidgetId);
    		PendingIntent pendingIntent = PendingIntent.getActivity(this,
    				thisWidgetId, clickIntent, 0);
    		remoteViews.setOnClickPendingIntent(R.id.widget_root, pendingIntent);
    		// update this widget
    		appWidgetManager.updateAppWidget(thisWidgetId, remoteViews);
    	}
    
    	void setResultDataToWidget(int result) {
    		Intent resultValue = new Intent();
    		resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, thisWidgetId);
    		setResult(result, resultValue);
    		finish();
    	}
    
    	public void saveToPreferences(String file_name, String data) {
    		SharedPreferences myPrefs = getSharedPreferences("Data",
    				MODE_WORLD_WRITEABLE);
    		SharedPreferences.Editor prefsEditor = myPrefs.edit();
    		prefsEditor.putString(file_name, data);
    		prefsEditor.commit();
    	}
    
    	public String getWidgetData(String file_name) {
    		SharedPreferences myPrefs = getSharedPreferences("Data",
    				MODE_WORLD_READABLE);
    		return (myPrefs.getString(file_name, null));
    	}
    
    }
    

    Now the AndroidManifest File.
    Make sure you carefully read the Manifest files. Look at the intent filters in the activities and make sure that you have the correct package name in the provider xml file.

    AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.coderzheaven.multiplewidgetinstance"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.coderzheaven.multiplewidgetinstance.SettingsPage"
                android:configChanges="keyboardHidden|orientation"
                android:label="@string/app_name"
                android:theme="@android:style/Theme.Dialog">
                <intent-filter>
                    <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
                </intent-filter>
            </activity>
    
            <!-- Broadcast Receiver that will process AppWidget Updates -->
            <receiver
                android:name="com.coderzheaven.multiplewidgetinstance.MyAppWidgetProvider"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                </intent-filter>
    
                <meta-data
                    android:name="android.appwidget.provider"
                    android:resource="@layout/my_widget_provider" />
            </receiver>
        </application>
    
    </manifest>
    

    Hooray you multiple instance code is complete.
    Here we are saving data for each widget in the preferences with the widgetId as key with which we are reloading the data and editing it.

    You can download the complete source code from here.

    How to get a return value from a DialogFragment? or Using DialogFragments in android.

    Hello all……

    This post examples how to get an edittext value from a dialog fragment.
    You can use the same method to get a button click from a dialog or events like that.

    Dialog Fragment

    You can click on the download link to get the source code.

    At first we will create a layout for the Dialog Fragment.
    The layout contains only an editext. We are getting this edittext value from the fragment to the activity when the “DONE” button is clicked after inputting text.

    frag_edit_name.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/edit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:orientation="vertical" >
    
        <TextView
            android:id="@+id/lbl_your_name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
             android:layout_margin="10dp"
            android:text="Your name" />
    
        <EditText
            android:id="@+id/txt_your_name"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:hint="Type your name"
            android:imeOptions="actionDone"
            android:inputType="text" />
    
    </LinearLayout>
    

    Next we will write the class for the DialogFragment.

    MyDialogFragment is my class name for the DialogFragment.

    MyDialogFragment.java

    package com.example.dialogfragmentsexxample;
    
    import android.os.Bundle;
    import android.support.v4.app.DialogFragment;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.inputmethod.EditorInfo;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.TextView.OnEditorActionListener;
    
    public class MyDialogFragment extends DialogFragment implements
    		OnEditorActionListener {
    
    	public interface EditNameDialogListener {
    		void onFinishEditDialog(String inputText);
    	}
    
    	private EditText mEditText;
    
    	public MyDialogFragment() {
    		// Empty constructor required for DialogFragment
    	}
    
    	@Override
    	public View onCreateView(LayoutInflater inflater, ViewGroup container,
    			Bundle savedInstanceState) {
    		View view = inflater.inflate(R.layout.frag_edit_name, container);
    		mEditText = (EditText) view.findViewById(R.id.txt_your_name);
    		getDialog().setTitle("Dialog Fragment Example");
    
    		// Show soft keyboard automatically
    		mEditText.requestFocus();
    		mEditText.setOnEditorActionListener(this);
    
    		return view;
    	}
    
    	@Override
    	public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    		if (EditorInfo.IME_ACTION_DONE == actionId) {
    			// Return input text to activity
    			EditNameDialogListener activity = (EditNameDialogListener) getActivity();
    			activity.onFinishEditDialog(mEditText.getText().toString());
    			this.dismiss();
    			return true;
    		}
    		return false;
    	}
    }
    

    OK Now our fragment is complete.
    Here we use interface to get value from the editext in the DialogFragment.

    This is the interface which has only one method

    onFinishEditDialog

    Now we implement this interface in the activity and call the method “onFinishEditDialog” from the dialog after inputting the text.
    This is the line that calls this function from the dialogfragment.

    activity.onFinishEditDialog(mEditText.getText().toString());
    

    This is the activity class.

    MainActivity.java

    package com.example.dialogfragmentsexxample;
    
    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.app.FragmentManager;
    import android.widget.TextView;
    
    import com.example.dialogfragmentsexxample.MyDialogFragment.EditNameDialogListener;
    
    public class MainActivity extends FragmentActivity implements
    		EditNameDialogListener {
    
    	TextView txt = null;
    
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		txt = new TextView(this);
    		txt.setText("Nothing received from Dialog Fragment");
    		txt.setTextSize(30);
    		setContentView(txt);
    		showEditDialog();
    	}
    
    	private void showEditDialog() {
    		FragmentManager fm = getSupportFragmentManager();
    		MyDialogFragment editNameDialog = new MyDialogFragment();
    		editNameDialog.show(fm, "fragment_edit_name");
    	}
    
    	@Override
    	public void onFinishEditDialog(String inputText) {
    		txt.setText("Input value from DialogFragment " + inputText);
    	}
    }
    

    Please leave your valuable comments if you found this post useful.

    You can download the complete source code for the above post from here.

    Using a ListBox, Dynamically adding contents to a listbox in Windows Phone

    This post shows how to add string objects to a ListBox Control in Windows Phone.

    Make sure to choose a C# template for the project.

    This is the layout .

    ListBox Windows Phone

    This is the complete Layout
    Just change the class name in the root of the layout to yours.

    <phone:PhoneApplicationPage 
        x:Class="ListBoxExample.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        shell:SystemTray.IsVisible="True">
    
        <!--LayoutRoot is the root grid where all page content is placed-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel contains the name of the application and page title-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock x:Name="ApplicationTitle" Text="MY LISTBOX APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="ListBox Application" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
            <!--ContentPanel - place additional content here-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <ListBox Height="383" HorizontalAlignment="Left" Margin="3,7,0,0" Name="listBox1" VerticalAlignment="Top" Width="448" />
                <Button Content="Add to ListBox" Height="72" HorizontalAlignment="Left" Margin="86,499,0,0" Name="button1" VerticalAlignment="Top" Width="250" Click="button1_Click" />
                <TextBlock Height="30" HorizontalAlignment="Left" Margin="12,414,0,0" Name="textBlock1" Text="Type something to add to the ListBox" VerticalAlignment="Top" Width="443" />
                <TextBox Height="72" HorizontalAlignment="Left" Margin="3,436,0,0" Name="textBox1" Text="" VerticalAlignment="Top" Width="460" />
            </Grid>
        </Grid>
     </phone:PhoneApplicationPage>
    

    Now we will look at the code.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    namespace ListBoxExample
    {
        public partial class MainPage : PhoneApplicationPage
        {
            // Constructor
            public MainPage()
            {
                InitializeComponent();
                listBox1.Items.Add("ListBox Demo From Coderzheaven"); 
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                listBox1.Items.Add(textBox1.Text.Trim());
            }
        }
    }
    

    Navigation Drawer Example in Android.

    Navigation Drawer

    The navigation drawer is a panel that transitions in from the left edge of the screen and displays the app’s main navigation options.
    Displaying the navigation drawer

    Creating a Navigation Drawer

    The user can bring the navigation drawer onto the screen by swiping from the left edge of the screen or by touching the application icon on the action bar.

    Dismissing the navigation drawer

    When the navigation drawer is expanded, the user can dismiss it in one of four ways:

    Touching the content outside the navigation drawer
    Swiping to the left anywhere on the screen (including edge swipe from right)
    Touching the app icon/title in the action bar
    Pressing Back

    Navigation Drawer

    Now we will see how we can start using this in our code.

    At first you have to create a layout for the main page.

    activity_main.xml

    <!--
     A DrawerLayout is intended to be used as the top-level content view using match_parent 
    for both width and height to consume the full space available.
    -->
    <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <!--
             As the main content view, the view below consumes the entire
             space available using match_parent in both dimensions.
        -->
    
        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <!--
             android:layout_gravity="start" tells DrawerLayout to treat
             this as a sliding drawer on the left side for left-to-right
             languages and on the right side for right-to-left languages.
             The drawer is given a fixed width in dp and extends the full height of
             the container. A solid background is used for contrast
             with the content view.
        -->
    
        <ListView
            android:id="@+id/left_drawer"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="#111"
            android:choiceMode="singleChoice"
            android:divider="@android:color/transparent"
            android:dividerHeight="0dp" />
    
    </android.support.v4.widget.DrawerLayout>
    

    Now the layout for the row in the listitem in the drawer panel

    drawer_list_item.xml

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textColor="#fff"
        android:background="?android:attr/activatedBackgroundIndicator"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"/>
    

    This is the layout for the fragment in which we are showing the contents when the drawer list is clicked.

    fragment_planet.xml

    <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        android:gravity="center"
        android:padding="32dp" />
    

    I am storing an array in the strings.xml.

    <resources>
        <string name="app_name">Navigation Drawer Example</string>
        <string-array name="planets_array">
            <item>Mercury</item>
            <item>Venus</item>
            <item>Earth</item>
            <item>Mars</item>
            <item>Jupiter</item>
            <item>Saturn</item>
            <item>Uranus</item>
            <item>Neptune</item>
        </string-array>
        <string name="drawer_open">Open navigation drawer</string>
        <string name="drawer_close">Close navigation drawer</string>
        <string name="action_websearch">Web search</string>
        <string name="app_not_available">Sorry, there\'s no web browser available</string>
    </resources>
    

    Our layout ans string resources are complete.

    Now the activity that is holding the drawer and implementing it.
    MainActivity.java

    package com.coderzheaven.navigationdrawerexample;
    
    import java.util.Locale;
    
    import android.app.Activity;
    import android.app.Fragment;
    import android.app.FragmentManager;
    import android.app.SearchManager;
    import android.content.Intent;
    import android.content.res.Configuration;
    import android.os.Bundle;
    import android.support.v4.app.ActionBarDrawerToggle;
    import android.support.v4.view.GravityCompat;
    import android.support.v4.widget.DrawerLayout;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.ImageView;
    import android.widget.ListView;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
        private DrawerLayout mDrawerLayout;
        private ListView mDrawerList;
        private ActionBarDrawerToggle mDrawerToggle;
    
        private CharSequence mDrawerTitle;
        private CharSequence mTitle;
        private String[] mPlanetTitles;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mTitle = mDrawerTitle = getTitle();
            mPlanetTitles = getResources().getStringArray(R.array.planets_array);
            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            mDrawerList = (ListView) findViewById(R.id.left_drawer);
    
            // set a custom shadow that overlays the main content when the drawer opens
            mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
            // set up the drawer's list view with items and click listener
            mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                    R.layout.drawer_list_item, mPlanetTitles));
            mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
    
            // enable ActionBar app icon to behave as action to toggle nav drawer
            getActionBar().setDisplayHomeAsUpEnabled(true);
            getActionBar().setHomeButtonEnabled(true);
    
            /* ActionBarDrawerToggle ties together the the proper interactions
            between the sliding drawer and the action bar app icon */
            mDrawerToggle = new ActionBarDrawerToggle(
                    this,                  /* host Activity */
                    mDrawerLayout,         /* DrawerLayout object */
                    R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
                    R.string.drawer_open,  /* "open drawer" description for accessibility */
                    R.string.drawer_close  /* "close drawer" description for accessibility */
                    ) {
                public void onDrawerClosed(View view) {
                    getActionBar().setTitle(mTitle);
                    invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                }
    
                public void onDrawerOpened(View drawerView) {
                    getActionBar().setTitle(mDrawerTitle);
                    invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                }
            };
            mDrawerLayout.setDrawerListener(mDrawerToggle);
    
            if (savedInstanceState == null) {
                selectItem(0);
            }
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.main, menu);
            return super.onCreateOptionsMenu(menu);
        }
    
        /* Called whenever we call invalidateOptionsMenu() */
        @Override
        public boolean onPrepareOptionsMenu(Menu menu) {
            // If the nav drawer is open, hide action items related to the content view
            boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
            menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
            return super.onPrepareOptionsMenu(menu);
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
             // The action bar home/up action should open or close the drawer.
             // ActionBarDrawerToggle will take care of this.
            if (mDrawerToggle.onOptionsItemSelected(item)) {
                return true;
            }
            // Handle action buttons
            switch(item.getItemId()) {
            case R.id.action_websearch:
                // create intent to perform web search for this planet
                Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
                intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
                // catch event that there's no activity to handle intent
                if (intent.resolveActivity(getPackageManager()) != null) {
                    startActivity(intent);
                } else {
                    Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }
    
        /* The click listner for ListView in the navigation drawer */
        private class DrawerItemClickListener implements ListView.OnItemClickListener {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectItem(position);
            }
        }
    
        private void selectItem(int position) {
            // update the main content by replacing fragments
            Fragment fragment = new PlanetFragment();
            Bundle args = new Bundle();
            args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
            fragment.setArguments(args);
    
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
    
            // update selected item and title, then close the drawer
            mDrawerList.setItemChecked(position, true);
            setTitle(mPlanetTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);
        }
    
        @Override
        public void setTitle(CharSequence title) {
            mTitle = title;
            getActionBar().setTitle(mTitle);
        }
    
        /**
         * When using the ActionBarDrawerToggle, you must call it during
         * onPostCreate() and onConfigurationChanged()...
         */
    
        @Override
        protected void onPostCreate(Bundle savedInstanceState) {
            super.onPostCreate(savedInstanceState);
            // Sync the toggle state after onRestoreInstanceState has occurred.
            mDrawerToggle.syncState();
        }
    
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            // Pass any configuration change to the drawer toggls
            mDrawerToggle.onConfigurationChanged(newConfig);
        }
    
        /**
         * Fragment that appears in the "content_frame", shows a planet
         */
        public static class PlanetFragment extends Fragment {
            public static final String ARG_PLANET_NUMBER = "planet_number";
    
            public PlanetFragment() {
                // Empty constructor required for fragment subclasses
            }
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
                int i = getArguments().getInt(ARG_PLANET_NUMBER);
                String planet = getResources().getStringArray(R.array.planets_array)[i];
    
                int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()),
                                "drawable", getActivity().getPackageName());
                ((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId);
                getActivity().setTitle(planet);
                return rootView;
            }
        }
    }
    

    Please leave your valuable comments below.

    You can download the complete source code from here.

    How to create a fully customizable Toast which will use your own time duration and gravity and layout with ease without using the default toast in android?

    Hello all
    We all have seen toasts right…ok then you have already customized your toasts right.

    Here I will show you a method to create toasts which will last the time you set and the gravity.

    You can download the code by clicking on the download links.

    Custom Toast

    This is the class that creates the toast notification.

    MyMsgBox.java

    package com.example.messageboxtest;
    
    import android.app.Activity;
    import android.content.Context;
    import android.os.Handler;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.animation.AlphaAnimation;
    import android.view.animation.Animation;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    public class MyMsgBox {
    
    	private static final int ANIMATION_DURATION = 600;
    
    	private int HIDE_DELAY = 5000;
    
    	private View mContainer;
    
    	private int gravity = Gravity.CENTER;
    
    	private TextView mTextView;
    
    	private Handler mHandler;
    
    	private AlphaAnimation mFadeInAnimation;
    
    	private AlphaAnimation mFadeOutAnimation;
    
    	public MyMsgBox(Context context, int HIDE_DELAY, int gravity) {
    		ViewGroup container = (ViewGroup) ((Activity) context)
    				.findViewById(android.R.id.content);
    		View v = ((Activity) context).getLayoutInflater().inflate(
    				R.layout.newmb__messagebar, container);
    		this.HIDE_DELAY = HIDE_DELAY;
    		this.gravity = gravity;
    		init(v);
    	}
    
    	private void init(View v) {
    		mContainer = v.findViewById(R.id.mbContainer);
    		mContainer.setVisibility(View.GONE);
    		mTextView = (TextView) v.findViewById(R.id.mbMessage);
    		mFadeInAnimation = new AlphaAnimation(0.0f, 1.0f);
    		mFadeOutAnimation = new AlphaAnimation(1.0f, 0.0f);
    		mFadeOutAnimation.setDuration(ANIMATION_DURATION);
    		mFadeOutAnimation
    				.setAnimationListener(new Animation.AnimationListener() {
    					@Override
    					public void onAnimationStart(Animation animation) {
    					}
    
    					@Override
    					public void onAnimationEnd(Animation animation) {
    						mContainer.setVisibility(View.GONE);
    					}
    
    					@Override
    					public void onAnimationRepeat(Animation animation) {
    					}
    				});
    
    		mHandler = new Handler();
    
    	}
    
    	public void show(String message) {
    		mContainer.setVisibility(View.VISIBLE);
    
    		((LinearLayout) mContainer).setGravity(gravity
    				| Gravity.CENTER_VERTICAL);
    
    		mTextView.setText(message);
    
    		mFadeInAnimation.setDuration(ANIMATION_DURATION);
    
    		mContainer.startAnimation(mFadeInAnimation);
    		mHandler.postDelayed(mHideRunnable, HIDE_DELAY);
    	}
    
    	private final Runnable mHideRunnable = new Runnable() {
    		@Override
    		public void run() {
    			mContainer.startAnimation(mFadeOutAnimation);
    		}
    	};
    
    }
    

    Now the layout for this toast.. Here I am making a toast with only one textview in it.

    This is the layout.
    newmb__messagebar.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/mbContainer"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_margin="10dp"
        android:gravity="bottom"
        android:orientation="vertical" >
    
        <LinearLayout
            style="@style/bgTheme"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:gravity="bottom"
            android:orientation="vertical" >
    
            <TextView
                android:id="@+id/mbMessage"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Test"
                android:textColor="@drawable/white" />
        </LinearLayout>
    
    </LinearLayout>
    

    This will create some errors.
    inside your drawable folder create an xml named “bg_gradiant.xml” and copy this code into it.

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item><shape>
                <solid android:color="@drawable/dark_grey" />
    
                <stroke android:width="0dp" android:color="#000000" />
    
                <corners android:radius="5dp" />
            </shape></item>
    
    </selector>
    

    And at last in your values/styles.xml add this style

     <style name="bgTheme">
            <item name="android:layout_width">wrap_content</item>
            <item name="android:layout_gravity">center_horizontal|center</item>
            <item name="android:layout_height">wrap_content</item>
            <item name="android:textColor">@drawable/white</item>
            <item name="android:textStyle">bold</item>
            <item name="android:layout_margin">3dp</item>
            <item name="android:background">@drawable/bg_gradiant</item>
            <item name="android:textSize">14sp</item>
            <item name="android:typeface">normal</item>
            <item name="android:text">05</item>
            <item name="android:padding">10dp</item>
        </style>
    [/xml
    
    You can add these colors to your <strong>strings.xml</strong>
    1
        <drawable name="white">#ffffff</drawable>
        <drawable name="black">#000000</drawable>
        <drawable name="blue">#2554C7</drawable>
        <drawable name="green">#347C2C</drawable>
        <drawable name="orange">#ff9900</drawable>
        <drawable name="pink">#FF00FF</drawable>
        <drawable name="violet">#a020f0</drawable>
        <drawable name="grey">#778899</drawable>
        <drawable name="red">#C11B17</drawable>
        <drawable name="yellow">#FFFF8C</drawable>
        <drawable name="PowderBlue">#b0e0e6</drawable>
        <drawable name="brown">#2F1700</drawable>
        <drawable name="Hotpink">#7D2252</drawable>
        <drawable name="dark_grey">#424242</drawable>
    

    Now in your activity call the class like this.

    // time in ms
    MyMsgBox m = new MyMsgBox(arg0.getContext(), 5000,
    		Gravity.BOTTOM);
    m.show("Hello this is a custom toast");
    

    Our custom toast is complete, now run the project and customize it according to your need.

    You can download the complete android source code for this project from here.

    Apple iPhones may come up with as less as $99 in the future

    iPhone

    Yes,
    these are the rumours about the future iphone. Apple is reportedly looking at iPhones with bigger screens and will be releasing the low cost phone in
    a range of colors as soon as this year, the ABC News reports.

    According to the report, Apple declined to comment on the rumors,
    Cook also said the iPhone doesn’t have a larger screen right now for a few reasons.

    He said that a large screen today comes with a lot of tradeoffs, adding that people do look at the size, but they also look at things like if the photos show the proper color, the white balance, reflectivity, battery life, brightness, the longevity of the display.

    Read more from here

    Use of custom animations in a FragmentTransaction when pushing and popping a stack. or How to apply animations in Fragments when pushing on to a stack?

    Hello all

    We have seen many examples of how to use fragments in android.
    You can search coderzheaven for all types of transactions using Fragments.
    Today in this post we will see how we can apply animations to Fragments when pushing on to a stack.

    This is fairly a long example. I will try to explain with code one by one,
    You can click on the download link to get the source code.

    Fragment

    Fragment

    Fragment

    Here we start.

    At first we will see the layout used in the Fragment.

    hello_world.xml

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center_horizontal"
        android:text="@string/hello_world"
        android:textAppearance="?android:attr/textAppearanceMedium" />
    

    Now the layout for the activity.
    fragment_stack.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:padding="4dip" >
    
        <FrameLayout
            android:id="@+id/simple_fragment"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1" >
        </FrameLayout>
    
        <Button
            android:id="@+id/new_fragment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:text="@string/new_fragment" >
    
            <requestFocus />
        </Button>
    
    </LinearLayout>
    

    Now the xml for the animations in the Fragment.
    First create a folder inside res folder called “animator” and create four xml files inside it.

    fragment_slide_left_enter.xml
    fragment_slide_left_exit.xml
    fragment_slide_right_enter.xml
    fragment_slide_right_exit.xml

    fragment_slide_left_enter.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:interpolator="@android:interpolator/decelerate_quint"
            android:valueFrom="100dp" android:valueTo="0dp"
            android:valueType="floatType"
            android:propertyName="translationX"
            android:duration="@android:integer/config_mediumAnimTime" />
        <objectAnimator
            android:interpolator="@android:interpolator/decelerate_quint"
            android:valueFrom="0.0" android:valueTo="1.0"
            android:valueType="floatType"
            android:propertyName="alpha"
            android:duration="@android:integer/config_mediumAnimTime" />
    </set>
    

    fragment_slide_left_exit.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:interpolator="@android:interpolator/decelerate_quint"
            android:valueFrom="0dp" android:valueTo="-100dp"
            android:valueType="floatType"
            android:propertyName="translationX"
            android:duration="@android:integer/config_mediumAnimTime" />
        <objectAnimator
            android:interpolator="@android:interpolator/decelerate_quint"
            android:valueFrom="1.0" android:valueTo="0.0"
            android:valueType="floatType"
            android:propertyName="alpha"
            android:duration="@android:integer/config_mediumAnimTime" />
    </set>
    

    fragment_slide_right_enter.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:interpolator="@android:interpolator/decelerate_quint"
            android:valueFrom="-100dp" android:valueTo="0dp"
            android:valueType="floatType"
            android:propertyName="translationX"
            android:duration="@android:integer/config_mediumAnimTime" />
        <objectAnimator
            android:interpolator="@android:interpolator/decelerate_quint"
            android:valueFrom="0.0" android:valueTo="1.0"
            android:valueType="floatType"
            android:propertyName="alpha"
            android:duration="@android:integer/config_mediumAnimTime" />
    </set>
    

    fragment_slide_right_exit.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:interpolator="@android:interpolator/decelerate_quint"
            android:valueFrom="0dp" android:valueTo="100dp"
            android:valueType="floatType"
            android:propertyName="translationX"
            android:duration="@android:integer/config_mediumAnimTime" />
        <objectAnimator
            android:interpolator="@android:interpolator/decelerate_quint"
            android:valueFrom="1.0" android:valueTo="0.0"
            android:valueType="floatType"
            android:propertyName="alpha"
            android:duration="@android:integer/config_mediumAnimTime" />
    </set>
    

    Now the activity that do all the transactions in the Fragment.

    FragmentCustomAnimations.java

    package com.example.fragmentcustomanimations;
    
    import android.app.Activity;
    import android.app.Fragment;
    import android.app.FragmentTransaction;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.TextView;
    
    /**
     * Demonstrates the use of custom animations in a FragmentTransaction when
     * pushing and popping a stack.
     */
    public class FragmentCustomAnimations extends Activity {
        int mStackLevel = 1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.fragment_stack);
    
            // Watch for button clicks.
            Button button = (Button)findViewById(R.id.new_fragment);
            button.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    addFragmentToStack();
                }
            });
    
            if (savedInstanceState == null) {
                // Do first time initialization -- add initial fragment.
                Fragment newFragment = CountingFragment.newInstance(mStackLevel);
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                ft.add(R.id.simple_fragment, newFragment).commit();
            } else {
                mStackLevel = savedInstanceState.getInt("level");
            }
        }
    
        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putInt("level", mStackLevel);
        }
    
    
        void addFragmentToStack() {
            mStackLevel++;
    
            // Instantiate a new fragment.
            Fragment newFragment = CountingFragment.newInstance(mStackLevel);
    
            // Add the fragment to the activity, pushing this transaction
            // on to the back stack.
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.setCustomAnimations(R.animator.fragment_slide_left_enter,
                    R.animator.fragment_slide_left_exit,
                    R.animator.fragment_slide_right_enter,
                    R.animator.fragment_slide_right_exit);
            ft.replace(R.id.simple_fragment, newFragment);
            ft.addToBackStack(null);
            ft.commit();
        }
    
        public static class CountingFragment extends Fragment {
            int mNum;
            /**
             * Create a new instance of CountingFragment, providing "num"
             * as an argument.
             */
            static CountingFragment newInstance(int num) {
                CountingFragment f = new CountingFragment();
    
                // Supply num input as an argument.
                Bundle args = new Bundle();
                args.putInt("num", num);
                f.setArguments(args);
    
                return f;
            }
    
            /**
             * When creating, retrieve this instance's number from its arguments.
             */
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                mNum = getArguments() != null ? getArguments().getInt("num") : 1;
            }
    
            /**
             * The Fragment's UI is just a simple text view showing its
             * instance number.
             */
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                View v = inflater.inflate(R.layout.hello_world, container, false);
                View tv = v.findViewById(R.id.text);
                ((TextView)tv).setText("Fragment #" + mNum);
                tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));  
                return v;
            }
        }
    
    }
    

    You can download the complete source code from here.

    How to display a context menu from a fragment?

    Hello all

    I think you all know about the context menu in android. It appears as a popup when you long press something. Fragment also provides some methods for registering with the contextmenu and showing it.

    Fragment Context Menu

    Fragment Context Menu

    Let’s see how we can do it.
    You can click on the download links to download the source code.

    At first we will look at the simple layout for demonstrating this example.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="@string/fragment_context_menu_msg" />
    
        <Button android:id="@+id/long_press"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="Long Press Me">
            <requestFocus />
        </Button>
        
    </LinearLayout>
    
    

    Now create a folder named “menu” inside the res folder inside your project.
    And create an xml file named “my_menu.xml” inside this folder and copy this code into it.

    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item android:id="@+id/invisible_item"
            android:visible="false"
            android:alphabeticShortcut="i"
            android:title="Invisible item" />
    
        <item android:id="@+id/a_item"
            android:alphabeticShortcut="a"
            android:title="Alvin" />
    
        <item android:id="@+id/b_item"
            android:alphabeticShortcut="b"
            android:title="Bart" />
    
        <item android:id="@+id/c_item"
            android:alphabeticShortcut="c"
            android:title="Chris" />
    
        <item android:id="@+id/d_item"
            android:alphabeticShortcut="d"
            android:title="David" />
    
        <item android:id="@+id/e_item"
            android:alphabeticShortcut="e"
            android:title="Eric" />
    
        <item android:id="@+id/f_item"
            android:alphabeticShortcut="f"
            android:title="Frank" />
    
        <item android:id="@+id/g_item"
            android:alphabeticShortcut="g"
            android:title="Gary" />
    
        <item android:id="@+id/h_item"
            android:alphabeticShortcut="h"
            android:title="Henry" />
    
        <item android:id="@+id/excl_item"
            android:alphabeticShortcut="!"
            android:title="Exclamation" />
    
    </menu>
    

    I am using only two of the items from the above XML for showing the context menu.
    Now we will go to the java code. My Activity is named FragmentContextMenu.java which looks like this.

    package com.coderzheaven.fragmentcontextmenu;
    
    import android.app.Activity;
    import android.app.Fragment;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.ContextMenu;
    import android.view.ContextMenu.ContextMenuInfo;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    
    /**
     * Demonstration of displaying a context menu from a fragment.
     */
    public class FragmentContextMenu extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // Create the list fragment and add it as our sole content.
            ContextMenuFragment content = new ContextMenuFragment();
            getFragmentManager().beginTransaction().add(android.R.id.content, content).commit();
        }
    
        public static class ContextMenuFragment extends Fragment {
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                View root = inflater.inflate(R.layout.fragment_context_menu, container, false);
                registerForContextMenu(root.findViewById(R.id.long_press));
                return root;
            }
    
            @Override
            public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
                super.onCreateContextMenu(menu, v, menuInfo);
                menu.add(Menu.NONE, R.id.a_item, Menu.NONE, "Menu A");
                menu.add(Menu.NONE, R.id.b_item, Menu.NONE, "Menu B");
            }
    
            @Override
            public boolean onContextItemSelected(MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.a_item:
                        Log.i("ContextMenu", "Item 1a was chosen");
                        return true;
                    case R.id.b_item:
                        Log.i("ContextMenu", "Item 1b was chosen");
                        return true;
                }
                return super.onContextItemSelected(item);
            }
        }
    }
    

    And That’s all done. Now you can run the project and see the result.

    You can download the complete source code from here.

    How to initialize a Fragements with attributes as a Bundle at runtime and from attributes in a layout?

    This post Demonstrates a fragment that can be configured through both Bundle arguments
    and layout attributes.

    Fragments

    You can click on the links to download the source code.

    Here there are two fragments in the layout, one is directly in the layout and the other is created dynamically with arguments at runtime.
    Here is how we do it.
    At first I will show you layout that contains the fragments.
    fragment_arguments.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:padding="4dip" >
    
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical|center_horizontal"
            android:layout_weight="0"
            android:gravity="top|center_horizontal"
            android:padding="4dip"
            android:text="@string/fragment_arguments_msg"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="4dip" >
    
            <fragment
                android:id="@+id/embedded"
                android:layout_width="0px"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                class="com.example.argumentsfragment.FragmentArguments$MyFragment"
                android:label="@string/fragment_arguments_embedded" />
    
            <FrameLayout
                android:id="@+id/created"
                android:layout_width="0px"
                android:layout_height="wrap_content"
                android:layout_weight="1" />
        </LinearLayout>
    
    </LinearLayout>
    

    Now the layout for each fragment.
    hello_world.xml

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center_horizontal"
        android:text="@string/hello_world"
        android:textAppearance="?android:attr/textAppearanceMedium" />
    

    OK layouts are now complete.

    Now the activity that does the thing that we want to do.
    FragmentArguments.java

    package com.example.argumentsfragment;
    
    import android.app.Activity;
    import android.app.Fragment;
    import android.app.FragmentTransaction;
    import android.content.res.TypedArray;
    import android.os.Bundle;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    /**
     * Demonstrates a fragment that can be configured through both Bundle arguments
     * and layout attributes.
     */
    public class FragmentArguments extends Activity {
    
        @Override protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.fragment_arguments);
    
            if (savedInstanceState == null) {
                // First-time init; create fragment to embed in activity.
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                Fragment newFragment = MyFragment.newInstance("From Arguments");
                ft.add(R.id.created, newFragment);
                ft.commit();
            }
        }
    
    
    
        public static class MyFragment extends Fragment {
            CharSequence mLabel;
    
            /**
             * Create a new instance of MyFragment that will be initialized
             * with the given arguments.
             */
            static MyFragment newInstance(CharSequence label) {
            	System.out.println("newInstance");
                MyFragment f = new MyFragment();
                Bundle b = new Bundle();
                b.putCharSequence("label", label);
                f.setArguments(b);
                return f;
            }
    
            /**
             * Parse attributes during inflation from a view hierarchy into the
             * arguments we handle.
             */
            @Override public void onInflate(Activity activity, AttributeSet attrs,
                    Bundle savedInstanceState) {
            	System.out.println("onInflate");
                super.onInflate(activity, attrs, savedInstanceState);
    
                TypedArray a = activity.obtainStyledAttributes(attrs,
                        R.styleable.FragmentArguments);
                mLabel = a.getText(R.styleable.FragmentArguments_android_label);
                a.recycle();
            }
    
            /**
             * During creation, if arguments have been supplied to the fragment
             * then parse those out.
             */
            @Override public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                System.out.println("onCreate");
                Bundle args = getArguments();
                if (args != null) {
                    mLabel = args.getCharSequence("label", mLabel);
                }
            }
    
            /**
             * Create the view for this fragment, using the arguments given to it.
             */
            @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
            	System.out.println("onCreateView");
                View v = inflater.inflate(R.layout.hello_world, container, false);
                View tv = v.findViewById(R.id.text);
                ((TextView)tv).setText(mLabel != null ? mLabel : "(no label)");
                tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
                return v;
            }
        }
    
    }
    

    Now create a file named “attr.xml” inside the res/values folder and copy this code into it.
    It contains the styelable attribute.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <declare-styleable name="FragmentArguments">
            <attr name="android:label" />
        </declare-styleable>
    
    </resources>
    

    and copy these code to the strings.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string name="app_name">ArgumentsFragment</string>
        <string name="hello_world">Hello world!</string>
        <string name="menu_settings">Settings</string>
        <string name="fragment_arguments_msg">Demonstrates a fragment that takes arguments
            as a Bundle at runtime (on the right) or from attributes in a layout (on the left).</string>
        <string name="fragment_arguments_embedded">From Attributes</string>
    
    </resources>
    

    All code is now complete. Go on and run the project.

    You can download the complete source code from here.

    How to hide and show a Fragment with animation in Android? and How to retain a state in a Fragment in Android?

    Hello everyone

    This posts helps you to hide and show a fragment with animation (without XML files animation). And also it shows how to retain a saved state(for eg: a value in a textview).

    A little about Fragments
    A Fragments is an independent component which can be connected to an activity. A Fragment typically defines a part of a user interface but it is possible to define headless Fragments, i.e. without user interface.

    Fragments can be dynamically or statically added to a layout. A Fragment encapsulate functionality so that it is easier to reuse within activity and layouts.

    A Fragment component runs in the context of an activity but it has its own lifecycle and their own user interface.

    Fragment show or hide

    Fragment show or hide

    This is the layout that holds two fragments.
    You can click on the download link to download the code.

    fragment_hide_show.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        android:layout_width="match_parent" android:layout_height="match_parent">
    
        <TextView android:layout_width="match_parent" android:layout_height="wrap_content"
            android:gravity="center_vertical|center_horizontal"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="Demonstration of hiding and showing fragments." />
    
        <LinearLayout android:orientation="horizontal" android:padding="4dip"
            android:gravity="center_vertical" android:layout_weight="1"
            android:layout_width="match_parent" android:layout_height="wrap_content">
    
            <Button android:id="@+id/frag1hide"
                android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:text="Hide" />
    
            <fragment android:name="com.example.fragmentshowingandhiding.FragmentHideShow$FirstFragment"
                    android:id="@+id/fragment1" android:layout_weight="1"
                    android:layout_width="0px" android:layout_height="wrap_content" />
    
        </LinearLayout>
    
        <LinearLayout android:orientation="horizontal" android:padding="4dip"
            android:gravity="center_vertical" android:layout_weight="1"
            android:layout_width="match_parent" android:layout_height="wrap_content">
    
            <Button android:id="@+id/frag2hide"
                android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:text="Hide" />
    
            <fragment android:name="com.example.fragmentshowingandhiding.FragmentHideShow$SecondFragment"
                    android:id="@+id/fragment2" android:layout_weight="1"
                    android:layout_width="0px" android:layout_height="wrap_content" />
    
        </LinearLayout>
    
    </LinearLayout>
    
    

    And this is the xml for the content inside each Fragment.

    labeled_text_edit.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="4dip" >
    
        <TextView
            android:id="@+id/msg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:paddingBottom="4dip" />
    
        <EditText
            android:id="@+id/saved"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/holo_blue_light"
            android:freezesText="true"
            android:text="I am in a Fragment" >
    
            <requestFocus />
        </EditText>
    
    </LinearLayout>
    

    FragmentHideShow.java

    package com.example.fragmentshowingandhiding;
    
    import android.app.Activity;
    import android.app.Fragment;
    import android.app.FragmentManager;
    import android.app.FragmentTransaction;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.TextView;
    
    /**
     * Demonstration of hiding and showing fragments.
     */
    public class FragmentHideShow extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.fragment_hide_show);
    
            // The content view embeds two fragments; now retrieve them and attach
            // their "hide" button.
            FragmentManager fm = getFragmentManager();
            addShowHideListener(R.id.frag1hide, fm.findFragmentById(R.id.fragment1));
            addShowHideListener(R.id.frag2hide, fm.findFragmentById(R.id.fragment2));
        }
    
        void addShowHideListener(int buttonId, final Fragment fragment) {
            final Button button = (Button)findViewById(buttonId);
            button.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    FragmentTransaction ft = getFragmentManager().beginTransaction();
                    ft.setCustomAnimations(android.R.animator.fade_in,
                            android.R.animator.fade_out);
                    if (fragment.isHidden()) {
                        ft.show(fragment);
                        button.setText("Hide");
                    } else {
                        ft.hide(fragment);
                        button.setText("Show");
                    }
                    ft.commit();
                }
            });
        }
    
        public static class FirstFragment extends Fragment {
            TextView mTextView;
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                View v = inflater.inflate(R.layout.labeled_text_edit, container, false);
                View tv = v.findViewById(R.id.msg);
                ((TextView)tv).setText("The fragment saves and restores this text.");
    
                // Retrieve the text editor, and restore the last saved state if needed.
                mTextView = (TextView)v.findViewById(R.id.saved);
                if (savedInstanceState != null) {
                    mTextView.setText(savedInstanceState.getCharSequence("text"));
                }
                return v;
            }
    
            @Override
            public void onSaveInstanceState(Bundle outState) {
                super.onSaveInstanceState(outState);
    
                // Remember the current text, to restore if we later restart.
                outState.putCharSequence("text", mTextView.getText());
            }
        }
    
        public static class SecondFragment extends Fragment {
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                View v = inflater.inflate(R.layout.labeled_text_edit, container, false);
                View tv = v.findViewById(R.id.msg);
                ((TextView)tv).setText("The TextView saves and restores this text.");
    
                // Retrieve the text editor and tell it to save and restore its state.
                // Note that you will often set this in the layout XML, but since
                // we are sharing our layout with the other fragment we will customize
                // it here.
                ((TextView)v.findViewById(R.id.saved)).setSaveEnabled(true);
                return v;
            }
        }
    }
    

    You can download the complete source code for the above example from here.

    Google’s Android will beat Apple’s iphone in total number of apps downloaded in next few months.

    Google Android

    Analysts are saying that Google play store will be the most popular platform for downloading mobile apps in the next few months.

    History of Google Play
    Google Play, formerly known as the Android Market, is a digital application distribution platform for Android and an online electronics store developed and maintained by Google. The service allows users to browse and download music, magazines, books, movies, television programs, and applications published through Google. Users can also purchase Chromebooks and Google Nexus–branded mobile devices through Google Play.
    Applications are available either for free or at a cost. They can be downloaded directly to an Android or Google TV device through the Play Store mobile app, or by deploying the application to a device from the Google Play website. These applications are generally targeted to users based on a particular hardware attribute of their device, such as a motion sensor (for motion-dependent games) or a front-facing camera (for online video calling).

    You can read more about Google Play Store from here

    How to create animation by default in a GridLayout in Android?

    This example shows you how to create animation using the default XML tag in a gridview.

    This application demonstrates how to use the animateLayoutChanges tag in XML to automate
    transition animations as items are removed from or added to a container.

    Click on the download link to get the source code.

    Let’s have a look.

    GridLayout Animation

    At first we will look at the layout XML.

    layout_animations_by_default.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <Button
            android:id="@+id/addNewButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Add Button" />
    
        <GridLayout
            android:id="@+id/gridContainer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true"
            android:columnCount="4" />
    
    </LinearLayout>
    

    Now the Activity that uses this XML to create the animation.
    LayoutAnimationsByDefault.java

    package com.example.animationdemo1;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.GridLayout;
    
    /**
     * This application demonstrates how to use the animateLayoutChanges tag in XML to automate
     * transition animations as items are removed from or added to a container.
     */
    public class LayoutAnimationsByDefault extends Activity {
    
        private int numButtons = 1;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_animations_by_default);
    
            final GridLayout gridContainer = (GridLayout) findViewById(R.id.gridContainer);
    
            Button addButton = (Button) findViewById(R.id.addNewButton);
            addButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    Button newButton = new Button(LayoutAnimationsByDefault.this);
                    newButton.setText(String.valueOf(numButtons++));
                    newButton.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                            gridContainer.removeView(v);
                        }
                    });
                    gridContainer.addView(newButton, Math.min(1, gridContainer.getChildCount()));
                }
            });
        }
    
    }
    

    You can download the complete source code for the above post from here.

    How to create a SearchView with Filter mode in a ListView in Android?

    Actually this is fairly simple.
    Android by default provides a SearchView class that has the ability to filter.

    Filter ListView
    Filter ListView

    Just look at the XML layout that I am using in this post.
    It consists of a SearchView and a ListView. The searchView searches the listview for the matched content.
    Click on the link to download the code.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
        <SearchView
                android:id="@+id/search_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        <ListView
                android:id="@+id/list_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"/>
    
    </LinearLayout>
    

    Now the Java class or the activity that implements the searchFilter.

    package com.coderzheaven.searchviewwithfilter;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.view.Window;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.SearchView;
    
    /**
     * Shows a list that can be filtered in-place with a SearchView in non-iconified mode.
     */
    public class SearchViewFilterMode extends Activity implements SearchView.OnQueryTextListener {
    
        private SearchView mSearchView;
        private ListView mListView;
    
        private final String[] mStrings = Cheeses.sCheeseStrings;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
    
            setContentView(R.layout.searchview_filter);
    
            mSearchView = (SearchView) findViewById(R.id.search_view);
            mListView = (ListView) findViewById(R.id.list_view);
            mListView.setAdapter(new ArrayAdapter<String>(this,
                    android.R.layout.simple_list_item_1,
                    mStrings));
            mListView.setTextFilterEnabled(true);
            setupSearchView();
        }
    
        private void setupSearchView() {
            mSearchView.setIconifiedByDefault(false);
            mSearchView.setOnQueryTextListener(this);
            mSearchView.setSubmitButtonEnabled(true); 
            mSearchView.setQueryHint("Search Here");
        }
    
        public boolean onQueryTextChange(String newText) {
            if (TextUtils.isEmpty(newText)) {
                mListView.clearTextFilter();
            } else {
                mListView.setFilterText(newText.toString());
            }
            return true;
        }
    
        public boolean onQueryTextSubmit(String query) {
            return false;
        }
    }
    
    

    Click to download the source code from here.

    Google to unveil Moto X to take on Apple.

    Motorola

    Google bought Motorola in 2011 and ever since there has not been a phone from Google and Motorola.
    Now it is that Google will be unveiling Moto X to take on rival Apple.

    iPhone overprice tag has not come down since its launch in 2007. This will be a area where Google and Motorola will be targeting.

    While Apple’s critics say the once wildly inventive company is running out of ideas, Motorola’s chief executive, Dennis Woodside, has promised to bring “audaciousness” and “innovation” back to mobile computing.

    In a future-gazing presentation at the AllThingsD conference in California, Woodside, who has been charged with turning around the company that invented the first mobile phones of the 1980s, said he was also working on wearable technology.

    Read complete story from here.

    Wave Scale Animation in GridViews in Android

    Hello all

    Previously I have shown many posts where we animate each row of the GridView randomly, linearly etc.

    GridView RandomFade animation in Android

    and

    Cascade animation in a ListView in Android.

    Wave Scale

    Wave Scale

    In today’s post I will show you how to create a wave scale animation in the ListViews.

    Please refer to my old posts for the extra code. Here I am posting only the animation XML only for the wave animation.

    layout_wave_scale.xml ( inside the res/anim folder)

    <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
        <alpha
            android:fromAlpha="0.0"
            android:toAlpha="1.0"
            android:duration="100" />
        <scale
            android:fromXScale="0.5" android:toXScale="1.5"
            android:fromYScale="0.5" android:toYScale="1.5"
            android:pivotX="50%" android:pivotY="50%"
            android:duration="200" />
        <scale 
            android:fromXScale="1.5" android:toXScale="1.0"
            android:fromYScale="1.5" android:toYScale="1.0"
            android:pivotX="50%" android:pivotY="50%"
            android:startOffset="200"
            android:duration="100" />
    </set>
    

    Apply it to the GridView and see the result.

    <GridView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/grid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnWidth="60dp"
        android:gravity="center"
        android:horizontalSpacing="10dp"
        android:layoutAnimation="@anim/layout_wave_scale"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dp" />
    
    

    Samsung Galaxy S4

    Samsung Galaxy S4

    Samsung Galaxy S4

    Display
    5inch Full HD Super AMOLED (1920 x 1080) display, 441 ppi

    AP
    1.9 GHz Quad-Core Processor / 1.6 GHz Octa-Core Processor
    The seletion of AP will be differed by markets

    Network
    2.5G (GSM/ GPRS/ EDGE): 850 / 900 / 1800 / 1900 MHz
    3G (HSPA+ 42Mbps): 850 / 900 / 1900 / 2100 MHz
    4G (LTE Cat 3 100/50Mbps) : up to 6 different band sets (Dependent on market)
    OS
    Android 4.2.2 (Jelly bean)

    Memory
    16 / 32 / 64GB memory + microSD slot (up to 64GB), 2GB RAM
    Camera
    Main(Rear): 13 Mega pixel Auto Focus camera with Flash & Zero Shutter Lag, BIS
    Sub (Front): 2 Mega pixel camera, Full HD recording @30fps with Zero Shutter Lag, BIS

    Camera Features
    Dual Shot , Drama Shot, Sound & Shot, 360 Photo, Animated Photo, Eraser, Night, Best Photo, Best Face, Beauty Face, HDR (High Dynamic Range), Panorama, Sports

    Video
    Codec: MPEG4, H.264, H.263, DivX, DivX3.11, VC-1, VP8, WMV7/8, Sorenson Spark, HEVC
    Recording & Playback: Full HD (1080p)

    Audio
    Codec: MP3, AMR-NB/WB, AAC/AAC+/eAAC+, WMA, OGG,
    FLAC, AC-3, apt-X

    Additional Features
    Group Play: Share Music, Share Picture, Share Document, Play Games
    Story Album, S Translator, Optical Reader

    Samsung Smart Scroll, Samsung Smart Pause, Air Gesture,
    Air View
    Samsung Hub, ChatON (Voice/Video Call, Share screen,
    3-way calling) Samsung WatchON
    S Travel (Trip Advisor), S Voice™ Drive, S Health
    Samsung Adapt Display, Samsung Adapt Sound, Auto adjust touch sensitivity (Glove friendly)
    Safety Assistance, Samsung Link, Screen Mirroring
    Samsung KNOX (B2B only)
    Google Mobile Services
    Google Search, Google Maps, Gmail, Google Latitude Google Play Store, Google Plus, YouTube, Google Talk, Google Places, Google Navigation, Google Downloads, Voice Search

    Sensor
    Accelerometer, RGB light, Geomagnetic, Proximity, Gyro,
    Barometer
    Temperature & Humidity, Gesture

    Dimension
    136.6 x 69.8 x 7.9 mm, 130g

    Connectivity
    WiFi 802.11 a/b/g/n/ac (HT80)
    GPS / GLONASS
    NFC, Bluetooth® 4.0 (LE)
    IR LED (Remote Control), MHL 2.0
    Battery
    2,600mAh

    How to create a beautiful wheel animation in android?

    Today’s post is about animation, a beautiful animation, exploring capabilities of android.

    Animation

    Animation

    You can click on the link to download the code.

    Here we will have three java classes and no XML files.
    1. GraphicsActivity.java
    2. PictureLayout.java
    3. Sweep.java

    At first we start with PictureLayout.java

    package com.example.sweep;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Picture;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.ViewParent;
    
    public class PictureLayout extends ViewGroup {
        private final Picture mPicture = new Picture();
    
        public PictureLayout(Context context) {
            super(context);
        }
    
        public PictureLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public void addView(View child) {
            if (getChildCount() > 1) {
                throw new IllegalStateException("PictureLayout can host only one direct child");
            }
    
            super.addView(child);
        }
    
        @Override
        public void addView(View child, int index) {
            if (getChildCount() > 1) {
                throw new IllegalStateException("PictureLayout can host only one direct child");
            }
    
            super.addView(child, index);
        }
    
        @Override
        public void addView(View child, LayoutParams params) {
            if (getChildCount() > 1) {
                throw new IllegalStateException("PictureLayout can host only one direct child");
            }
    
            super.addView(child, params);
        }
    
        @Override
        public void addView(View child, int index, LayoutParams params) {
            if (getChildCount() > 1) {
                throw new IllegalStateException("PictureLayout can host only one direct child");
            }
    
            super.addView(child, index, params);
        }
    
        @Override
        protected LayoutParams generateDefaultLayoutParams() {
            return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            final int count = getChildCount();
    
            int maxHeight = 0;
            int maxWidth = 0;
    
            for (int i = 0; i < count; i++) {
                final View child = getChildAt(i);
                if (child.getVisibility() != GONE) {
                    measureChild(child, widthMeasureSpec, heightMeasureSpec);
                }
            }
    
            maxWidth += getPaddingLeft() + getPaddingRight();
            maxHeight += getPaddingTop() + getPaddingBottom();
    
            Drawable drawable = getBackground();
            if (drawable != null) {
                maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
                maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
            }
    
            setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
                    resolveSize(maxHeight, heightMeasureSpec));
        }
    
        private void drawPict(Canvas canvas, int x, int y, int w, int h,
                              float sx, float sy) {
            canvas.save();
            canvas.translate(x, y);
            canvas.clipRect(0, 0, w, h);
            canvas.scale(0.5f, 0.5f);
            canvas.scale(sx, sy, w, h);
            canvas.drawPicture(mPicture);
            canvas.restore();
        }
    
        @SuppressWarnings("unused")
    	@Override
        protected void dispatchDraw(Canvas canvas) {
            super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
            mPicture.endRecording();
    
            int x = getWidth()/2;
            int y = getHeight()/2;
    
            if (false) {
                canvas.drawPicture(mPicture);
            } else {
                drawPict(canvas, 0, 0, x, y,  1,  1);
                drawPict(canvas, x, 0, x, y, -1,  1);
                drawPict(canvas, 0, y, x, y,  1, -1);
                drawPict(canvas, x, y, x, y, -1, -1);
            }
        }
    
        @Override
        public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
            location[0] = getLeft();
            location[1] = getTop();
            dirty.set(0, 0, getWidth(), getHeight());
            return getParent();
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            final int count = super.getChildCount();
    
            for (int i = 0; i < count; i++) {
                final View child = getChildAt(i);
                if (child.getVisibility() != GONE) {
                    final int childLeft = getPaddingLeft();
                    final int childTop = getPaddingTop();
                    child.layout(childLeft, childTop,
                            childLeft + child.getMeasuredWidth(),
                            childTop + child.getMeasuredHeight());
    
                }
            }
        }
    }
    

    Now our second java file, GraphicsActivity.java
    No need to declare this activity in the Manifest since you are only extending it.

    package com.example.sweep;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.ViewGroup;
    
    class GraphicsActivity extends Activity {
        // set to true to test Picture
        private static final boolean TEST_PICTURE = false;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public void setContentView(View view) {
            if (TEST_PICTURE) {
                ViewGroup vg = new PictureLayout(this);
                vg.addView(view);
                view = vg;
            }
    
            super.setContentView(view);
        }
    }
    

    Now the last java class that extends the GraphicsActivity and creates the animation.
    Sweep.java

    package com.example.sweep;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Shader;
    import android.graphics.SweepGradient;
    import android.os.Bundle;
    import android.view.View;
    
    public class Sweep extends GraphicsActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(new SampleView(this));
        }
    
        private static class SampleView extends View {
            private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            private float mRotate;
            private Matrix mMatrix = new Matrix();
            private Shader mShader;
            private boolean mDoTiming;
    
            public SampleView(Context context) {
                super(context);
                setFocusable(true);
                setFocusableInTouchMode(true);
    
                float x = 160;
                float y = 100;
                mShader = new SweepGradient(x, y, new int[] { Color.GREEN,
                                                      Color.RED,
                                                      Color.BLUE,
                                                      Color.GREEN }, null);
                mPaint.setShader(mShader);
            }
    
            @Override protected void onDraw(Canvas canvas) {
                Paint paint = mPaint;
                float x = 160;
                float y = 100;
    
                canvas.drawColor(Color.WHITE);
    
                mMatrix.setRotate(mRotate, x, y);
                mShader.setLocalMatrix(mMatrix);
                mRotate += 3;
                if (mRotate >= 360) {
                    mRotate = 0;
                }
                invalidate();
    
                if (mDoTiming) {
                    long now = System.currentTimeMillis();
                    for (int i = 0; i < 20; i++) {
                        canvas.drawCircle(x, y, 80, paint);
                    }
                    now = System.currentTimeMillis() - now;
                    android.util.Log.d("skia", "sweep ms = " + (now/20.));
                }
                else {
                    canvas.drawCircle(x, y, 80, paint);
                }
            }
    
           
        }
    }
    

    Please leave your valuable comments on this post.

    You can download the source code for the above post from here.

    900 million Android activations

    Google’s Android OS has more than 900 million users, the company said Wednesday at its I/O event began in San Francisco.

    Google also announced several APIs that will let developers add more capabilities to their Android apps, including in the areas of location and improving battery life.

    “It’s been an amazing year for Android developers,” said Android and Chrome vice president Sundar Piachai.

    Read More from here.
    http://www.pcworld.com/article/2038798/google-says-it-has-900-million-android-activations.html