Archive

Archive for the ‘Design Patterns’ Category

UI Design – Keep the Bar Floating


One of very common UI design patterns I see is: display top and bottom bar in floating state.

It looks very nice and close to users for interaction.

UI Design - Floating Bar

UI Design - Floating Bar

As you see in this image, the bottom bar containing one button always appears sticky to the bottom of the screen, even when I try to scroll up or down the list, it is still there.

You might read about my previous articles on Creating float View using FrameLayout, that solves this UI design pattern we are discussing about. However, it has several weaknesses:

– First, when you scroll up or down, the floating view is not displayed, it appears only when there is a trigger to the container layout, like: clicking to the list item…

– Second, when you click or hold your click on the view that stays behind your floating view, the floating view is hidden behind, of course, not displayed as well.

– Third, the drawable or color of floating view is unstable when you make changes to the view behind it.

Happily, after asking Mr. Google, I’ve found another solution for this UI design pattern.

It is, using RelativeLayout and define the floating bar position on the screen using layout_alignParentXXX attributes.

I refer it from here: Click to visit the reference!

I give it a try and it works like a charm! Just great it is!

Here the layout I create for the above demonstration image:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

	<ListView
		android:id="@+id/lvMain"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
	/>

	<LinearLayout
		android:id="@+id/layout_bottom_bar"
		android:orientation="horizontal"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:gravity="center"
		android:layout_alignParentBottom="true"
		android:background="#222222"
		android:padding="5dip"
		android:clickable="true"
	>
		<Button
			android:id="@+id/btnMore"
			android:layout_width="120dip"
			android:layout_height="wrap_content"
			android:text="More Songs"
			android:gravity="center"
			android:padding="5dip"
			android:background="#000000"
			android:textColor="#FFFFFF"
		/>
	</LinearLayout>

</RelativeLayout>

Well, do you like it or not?

Cheers,
Pete Houston

Advertisements
Categories: Design Patterns Tags: , , ,

ViewHolder Pattern – Caching View Efficiently

June 16, 2011 17 comments

A – Yeah! It works!

Yo, we’ve got a list view to display something:

Sample ListView

Sample ListView

This is what people like to write for list adapter:

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		View v = convertView;
		if(v == null) {
			LayoutInflater inflater = LayoutInflater.from(mContext);
			v = inflater.inflate(R.layout.layout_list_item, null);
		}

		TextView txtName = (TextView)v.findViewById(R.id.txtName);
		TextView txtMail = (TextView)v.findViewById(R.id.txtMail);

		Contact entry = mList.get(position);

		txtName.setText(entry.getName());
		txtMail.setText(entry.getMail());

		return v;
	}

That’s great because it works with no problem and the list displays contents nicely!!!

 

B – Dig It Out

Let’s see how it works..

+ First time loaded, oh right, it’s null!  Ok, to find our TextView controls, ‘findViewById()‘ is loaded. Great, we’ve got it!

+ Second time loaded,  it must be not null, but ‘findViewById()‘ is loaded. Well, just one time, it’s fine!

+ Next time loaded, it’s absolutely not null, eh, ‘findViewById()‘ is called by default. Eh oh..

+ ……whatever time

+ xxx th time…..something is calling ‘findViewById()‘…so stupid, damn it! But it’s still running fine … _ _!

 

C – Giving birth to a child: ViewHolder

You may see the problem, too. When the list is too big, containing lots of rows, then the calling of ‘findViewById()‘ everytime will impact slightly to your application performance, even though, it’s still working fine; however, it’s quite risky since it might be dead at some unexpected point.

This is one of most common problem, it is! Hence, from somewhere, the idea of ViewHolder pattern was created to improve this current situation.

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View v = convertView;
		if(v == null) {
			LayoutInflater inflater = LayoutInflater.from(mContext);
			v = inflater.inflate(R.layout.layout_list_item, null);
			ViewHolder holder = new ViewHolder();
			holder.txtName = (TextView)v.findViewById(R.id.txtName);
			holder.txtMail = (TextView)v.findViewById(R.id.txtMail);
			v.setTag(holder);
		}

		Contact entry = mList.get(position);
		if(entry != null) {
			ViewHolder holder = (ViewHolder)v.getTag();
			holder.txtName.setText(entry.getName());
			holder.txtMail.setText(entry.getMail());
		}
		return v;

	}

	static class ViewHolder {
		TextView txtName;
		TextView txtMail;
	}

The ViewHolder object is static, once created, it will cache all things inside. Therefore, we can avoid calling ‘findViewById()‘ on resource everytime.

 

D – Note

– Something works doesn’t mean it’s the best. Even if it’s fine, it might contain some invisible problems.

– Use ViewHolder pattern whenever possible to cache data!

 

E – Final Words

– Just something I’ve learned and wanna share to everyone.

– Feel free to comment, suggest and request; I’m here to listen to everyone’s voice 🙂

– Free to share, free to take!

 

Cheers,

Pete Houston