Android developer Nepal

drawtext with background

To add a dynamic text with background color at the desired position in screen

onDraw method of a view,

1. Create a rectangle with method

canvas.drawRect(left, top, right, bottom, paint)

2. Create a text with method

canvas.drawText(text, x, y, paint)

where
– x, y is the desired origin position of text,
– paint is the paint of text with color, fontsize, style

We can draw text with the method with your position and paint but for drawing background, we need to calculate width and height of desired text.

Text to show “I Like Android Learning”

Paint mTxtPaint = new Paint();

Now, add styles and define font metrices

FontMetrics fm = new FontMetrics();
	mTxtPaint.setColor(Color.BLACK);
	mTxtPaint.setTextSize(18.0f);
	mTxtPaint.getFontMetrics(fm);
	int margin = 5;

Draw rectangle to canvas for your string (This will draw background color for the text)

String str = "I Like Android Learning";
canvas.drawRect(100 - margin, 100 + fm.top - margin,
		100 + mTxtPaint.measureText(str) + margin, 100 + fm.bottom
		+ margin, mTxtPaint);

Now draw text

mTxtPaint.setColor(Color.WHITE);
canvas.drawText(str, 100, 100, mTxtPaint);

Your onDraw will be like:

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);

		String str = "I Like Android Learning";
		FontMetrics fm = new FontMetrics();
		mTxtPaint.setColor(Color.BLACK);
		mTxtPaint.setTextSize(18.0f);

		mTxtPaint.getFontMetrics(fm);

		int margin = 5;
		
		canvas.drawRect(100 - margin, 100 + fm.top - margin,
				100 + mTxtPaint.measureText(str) + margin, 100 + fm.bottom
						+ margin, mTxtPaint);

		mTxtPaint.setColor(Color.WHITE);
		
		canvas.drawText(str, 100, 100, mTxtPaint);

	}

device-2013-11-17-154627
In this example, we’ll see how to add multiple colors with different levels of the progress in Seekbar. It also covers how to customize levels and colors of the progress item. Basic concept behind this custom seekbar ui is to hide your default drawables and draw your desired rectangles with calculated positions within the canvas for seekbar.

At first, lets create a helper class for progress item to define progress span and color.

ProgressItem.java

public class ProgressItem {

	public int color;
	public float progressItemPercentage;
}

Now lets create a Custom seekbar class that extends SeekBar. We’ll use the list of progress items passed from our activity to show progress span and color for each progress item.

CustomSeekBar.java

		int progressBarWidth = getWidth();
		int progressBarHeight = getHeight();
		int thumboffset = getThumbOffset();
		int lastProgressX = 0;
		int progressItemWidth, progressItemRight;
		for (int i = 0; i < mProgressItemsList.size(); i++) {
			ProgressItem progressItem = mProgressItemsList.get(i);
			Paint progressPaint = new Paint();
			progressPaint.setColor(getResources().getColor(progressItem.color));

			progressItemWidth = (int) (progressItem.progressItemPercentage
					* progressBarWidth / 100);

			progressItemRight = lastProgressX + progressItemWidth;

			// for last item give right of the progress item to width of the
			// progress bar
			if (i == mProgressItemsList.size() - 1
					&& progressItemRight != progressBarWidth) {
				progressItemRight = progressBarWidth;
			}
			Rect progressRect = new Rect();
			progressRect.set(lastProgressX, thumboffset / 2, progressItemRight,
					progressBarHeight - thumboffset / 2);
			canvas.drawRect(progressRect, progressPaint);
			lastProgressX = progressItemRight;
		}
		super.onDraw(canvas);
	}

In onDraw method, we’ve calculated width of progress item with respect to the width of whole progressbar. Left position for the progress item will be right position of the previous item, for the first progress item, it will be 0. Use left position and width of progress item to get right position of the item. Now, draw a rectangle using these positions. Call super.onDraw(canvas) method right after add your custom changes.

Now, you can add your CustomSeekBar from your activity or xml file. I’ve added this it in xml file as

activity_main.xml

<yourpackagename.CustomSeekBar
        android:id="@+id/customSeekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:progress="0"
        android:progressDrawable="@android:color/transparent"
        android:thumb="@drawable/seek_thumb_normal"
        android:thumbOffset="12dp" />

Since we’re not showing any progressDrawable so use transparent drawable here.

Add your progress items in your activity.

MainActivity.java

	private CustomSeekBar seekbar;
	private float totalSpan = 1500;
	private float redSpan = 200;
	private float blueSpan = 300;
	private float greenSpan = 400;
	private float yellowSpan = 150;
	private float darkGreySpan;
        private ArrayList<ProgressItem> progressItemList;
	private ProgressItem mProgressItem;

        @Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		seekbar = ((CustomSeekBar) findViewById(R.id.customSeekBar));
		initDataToSeekbar();
		}

        private void initDataToSeekbar() {
		progressItemList = new ArrayList<ProgressItem>();
		// red span
		mProgressItem = new ProgressItem();
		mProgressItem.progressItemPercentage = ((redSpan / totalSpan) * 100);
		mProgressItem.color = R.color.red;
		progressItemList.add(mProgressItem);
		// blue span
		mProgressItem = new ProgressItem();
		mProgressItem.progressItemPercentage = (blueSpan / totalSpan) * 100;
		mProgressItem.color = R.color.blue;
		progressItemList.add(mProgressItem);
		// green span
		mProgressItem = new ProgressItem();
		mProgressItem.progressItemPercentage = (greenSpan / totalSpan) * 100;
		mProgressItem.color = R.color.green;
		progressItemList.add(mProgressItem);
		// yellow span
		mProgressItem = new ProgressItem();
		mProgressItem.progressItemPercentage = (yellowSpan / totalSpan) * 100;
		mProgressItem.color = R.color.yellow;
		progressItemList.add(mProgressItem);
		// greyspan
		mProgressItem = new ProgressItem();
		mProgressItem.progressItemPercentage = (darkGreySpan / totalSpan) * 100;
		mProgressItem.color = R.color.grey;
		progressItemList.add(mProgressItem);

		seekbar.initData(progressItemList);
		seekbar.invalidate();
	}

The project can be downloaded here: CustomSeekBar

listview with custom divider, alternate backgrounds and a selectorIn this example we’ll create a listview with a custom list divider, alternate backgrounds for list items and a list selector.

At first let’s create a listview and give them necessary attributes.

res/layout/main.xml

    
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000">
    </ListView>

List Divider

Now Let’s customize our listview with a simple list divider.All we need to do is just give divider and dividerHeight, XML attributes to our listview. The list divider is a Drawable with our custom shapes and color. In this example, we will use Gradient Drawable as a list divider list_divider.xml

res/drawable/list_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <gradient
        android:angle="270.0"
        android:endColor="#f6fafc"
        android:startColor="#c9dbe4" />

</shape>

Add this list divider to our listview by adding android:divider="@drawable/list_divider" to ListView tag. Also, give height to our divider by adding tag android:dividerHeight="1dp"

Alternate backgrounds to ListView

For adding your alternate backgrounds, you can create your custom adapter, and add your changes to the method getView(). In this example, i’ve created MyListAdapter that extends ArrayAdapter and two ColorDrawables as my background colors that’ll be added to list items.

Color Drawable 1 : res/drawable/list_background1.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <solid android:color="#e9f1f4" />

</shape>

Color Drawable 2 : res/drawable/list_background2.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <solid android:color="#f6f9fa" />

</shape>

MyListAdapter.java

public class MyListAdapter extends ArrayAdapter {

	int[] listItemBackground = new int[] { R.drawable.list_background1,
			R.drawable.list_background2 };

	public MyListAdapter(Context context, int resource, int textViewResourceId,
			String[] objects) {
		super(context, resource, textViewResourceId, objects);
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View view = convertView;
		if (view == null) {
			// your list item layout to inflate here
		}

		int listItemBackgroundPosition = position % listItemBackground.length;
		view.setBackgroundResource(listItemBackground[listItemBackgroundPosition]);
		return view;
	}
}

List Selectors

After adding background to the list item, we’ll see no selectors for our list. In this example i’ve created a list selector for pressed_state.

res/drawable/list_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/list_selector_pressed" android:state_pressed="true"></item>

</selector>

Color Drawable for pressed state : res/drawable/list_selector_pressed.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <solid android:color="#bfced4" />

</shape>

Now add list selector attribute android:listSelector to the ListView tag. Since our list item background is on the top of list selector we have to modify the background drawables we’ve used in get view.For the pressed state we’ll set transparency to our list item backgrounds. So, create color background with different selection states.

Color Drawable 1 : res/drawable/fancy_list_background1.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@android:color/transparent" android:state_pressed="true"></item>
    <item android:drawable="@drawable/list_background1"></item>

</selector>

Color Drawable 2 : res/drawable/fancy_list_background2.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@android:color/transparent" android:state_pressed="true"></item>
    <item android:drawable="@drawable/list_background2"></item>

</selector>

Now replace the values in listItemBackground with these drawables.

int[] listItemBackground = new int[] { R.drawable.fancy_list_background1,
			R.drawable.fancy_list_background2 };

Our final ListView will be

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"
        android:divider="@drawable/list_divider"
        android:dividerHeight="1dp"
        android:listSelector="@drawable/list_selector" >
    </ListView>

In this post we’ll see how to use pattern images as background. Cropping a part of image and creating its 9-Patch image wont work here. A simple trick is to define a bitmap source and set parameters android:tileMode to “repeat”. this will repeat bitmap in both directions. Another parameter you need to give is image path. Set android:src to your pattern image “@drawable/background_pattern_image”.
In my case, pattern image is background_pattern_image.The bitmap source is

res/drawable/my_background

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/background_pattern_image"
    android:tileMode="repeat" >
</bitmap>

Now your pattern background is ready to use. you can use this background on any layouts and views you want

android:background="@drawable/my_background"

ViewPager is a view group based on api available only on. Since these api are not available in standard sdk, you need to add the compatibility package to the android project.For this, once you have the compatibility package, right click to your project in eclipse, choose ‘Android tools’ and ‘Add Compatibility Library’.
Define a ViewPager control in layout resources file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
	android:id="@+id/my_view_pager"
	android:layout_width="match_parent"
	android:layout_height="match_parent"/>
</LinearLayout>

Now create the set of resources that will be your pages for swiping in ViewPager.
page1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF">
<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is page1"
        android:textColor="#000000"/>
</LinearLayout>

page2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is page2"/>
</LinearLayout>

Now implement your custom PagerAdapter to load your content for each pages. While extending your adapter class to PagerAdapter, it will implement the inherited abstract methods.
-getCount() method returns the page size
-instantiateItem() method is used to inflate the layout to be loaded on your page
-destroyItem() method removes the layout from the collection when it is no longer displayed

public class MyViewPagerAdapter extends PagerAdapter{

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return 2;
		}

		public Object instantiateItem(View collection, int position) {
			 
            LayoutInflater mInflater = (LayoutInflater) collection.getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
            int resId = 0;
            switch (position) {
            case 0:
                resId = R.layout.page1;
                break;
            case 1:
                resId = R.layout.page2;
                break;
            }
 
            View view = mInflater.inflate(resId, null);
 
            ((ViewPager) collection).addView(view, 0);
 
            return view;
        }
 
        @Override
        public void destroyItem(View arg0, int arg1, Object arg2) {
            ((ViewPager) arg0).removeView((View) arg2);
 
        }
 
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == ((View) arg1);
 
        }
 
        @Override
        public Parcelable saveState() {
            return null;
        }
    	
    }

Now bind your PagerAdater to the ViewPager. On oncreate() method,

 ViewPager myViewPager = (ViewPager) findViewById(R.id.my_view_pager);
        MyViewPagerAdapter viewPagerAdapter = new MyViewPagerAdapter();
        myViewPager.setAdapter(viewPagerAdapter);

Now run the application and swipe left/right to load the pages.

Hello World

As i’m a new to android programming, i’m starting with “Hello World” and i’ve learned to do this, which i’m going to share as my first post.

At first we need an activity, which is a chunk of codes that does some work. Our application enters through the activity. When the application is first called it enters through the onCreate.

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

Now it’s time to set something to get displayed in screen. For this we need a layout in layout folder, by default it creates main.xml in layout folder. In this file we need a textView where we print out text. Remember to give layout height and width. Now our main.xml file is like:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/textView1"
/>
</LinearLayout>

Let’s use this layout in our activity inside onCreate

setContentView(R.layout.main);

Now, initialize our textView

TextView myText = (TextView) findViewById(R.id.textView1);

The id it uses is the one we gave in our layout for that textView. Set the text to that textView,

myText.setText("Hello World");

The whole code is like:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView myText = (TextView) findViewById(R.id.textView1);
myText.setText("Hello World");
}