view

Customized list view

This is an example of how to create a Customized ListView on on Android. The normal ListView component of Android is very useful. But we have the ability to further customize it which makes it more flexible.

In order to create your own, customized ListView, follow these steps:

  • Create a new XML  file that describes the layout of each row
  • Create a custom ArrayAdapter . by Creating a new class that extends ArrayAdapter<T>
  • Override the getView method, inflate the XML layout file and retrieve reference of the described View
  • Take reference of each of the views widgets using the findViewById method, and customize them as you wish
  • In your activity class extend ListActivity
  • use setListAdapter method to set your custom Adapter as the ArrayAdapter for the ListView.

Let’s see how the code looks like:

package com.javacodegeeks.android.apps.moviesearchapp.ui;

import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.LinkedHashMap;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.javacodegeeks.android.apps.moviesearchapp.R;
import com.javacodegeeks.android.apps.moviesearchapp.io.FlushedInputStream;
import com.javacodegeeks.android.apps.moviesearchapp.model.Movie;
import com.javacodegeeks.android.apps.moviesearchapp.services.HttpRetriever;

public class MoviesAdapter extends ArrayAdapter<Movie> {

    private HttpRetriever httpRetriever = new HttpRetriever();
    private ArrayList<Movie> movieDataItems;
    private Activity context;

    public MoviesAdapter(Activity context, int textViewResourceId, ArrayList<Movie> movieDataItems) {

        super(context, textViewResourceId, movieDataItems);

        this.context = context;

        this.movieDataItems = movieDataItems;
    }

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

        View view = convertView;

        if (view == null) {

            LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            view = vi.inflate(R.layout.movie_data_row, null);

        }

        Movie movie = movieDataItems.get(position);

        if (movie != null) {

// name

            TextView nameTextView = (TextView) view.findViewById(R.id.name_text_view);

            nameTextView.setText(movie.name);

// rating

            TextView ratingTextView = (TextView) view.findViewById(R.id.rating_text_view);

            ratingTextView.setText("Rating: " + movie.rating);

// released

            TextView releasedTextView = (TextView) view.findViewById(R.id.released_text_view);

            releasedTextView.setText("Release Date: " + movie.released);

// certification

            TextView certificationTextView = (TextView) view.findViewById(R.id.certification_text_view);

            certificationTextView.setText("Certification: " + movie.certification);

// language

            TextView languageTextView = (TextView) view.findViewById(R.id.language_text_view);

            languageTextView.setText("Language: " + movie.language);

// thumb image

            ImageView imageView = (ImageView) view.findViewById(R.id.movie_thumb_icon);

            String url = movie.retrieveThumbnail();

            if (url != null) {

                Bitmap bitmap = fetchBitmapFromCache(url);

                if (bitmap == null) {

                    new BitmapDownloaderTask(imageView).execute(url);

                } else {

                    imageView.setImageBitmap(bitmap);

                }

            } else {

                imageView.setImageBitmap(null);

            }

        }

        return view;

    }
    private LinkedHashMap<String, Bitmap> bitmapCache = new LinkedHashMap<String, Bitmap>();

    private void addBitmapToCache(String url, Bitmap bitmap) {

        if (bitmap != null) {

            synchronized (bitmapCache) {

                bitmapCache.put(url, bitmap);

            }

        }
    }

    private Bitmap fetchBitmapFromCache(String url) {

        synchronized (bitmapCache) {

            final Bitmap bitmap = bitmapCache.get(url);

            if (bitmap != null) {

                // Bitmap found in cache

                // Move element to first position, so that it is removed last

                bitmapCache.remove(url);

                bitmapCache.put(url, bitmap);

                return bitmap;

            }

        }

        return null;

    }

    private class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {

        private String url;
        private final WeakReference<ImageView> imageViewReference;

        public BitmapDownloaderTask(ImageView imageView) {

            imageViewReference = new WeakReference<ImageView>(imageView);

        }

        @Override
        protected Bitmap doInBackground(String... params) {

            url = params[0];

            InputStream is = httpRetriever.retrieveStream(url);

            if (is == null) {

                return null;

            }

            return BitmapFactory.decodeStream(new FlushedInputStream(is));

        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {

            if (isCancelled()) {

                bitmap = null;

            }

            addBitmapToCache(url, bitmap);

            if (imageViewReference != null) {

                ImageView imageView = imageViewReference.get();

                if (imageView != null) {

                    imageView.setImageBitmap(bitmap);

                }

            }

        }
    }
}
package com.javacodegeeks.android.apps.moviesearchapp;

import java.util.ArrayList;

import android.app.ListActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;

import com.javacodegeeks.android.apps.moviesearchapp.model.Movie;
import com.javacodegeeks.android.apps.moviesearchapp.ui.MoviesAdapter;

public class MoviesListActivity extends ListActivity {

    private static final String IMDB_BASE_URL = "http://m.imdb.com/title/";
    private ArrayList<Movie> moviesList = new ArrayList<Movie>();
    private MoviesAdapter moviesAdapter;

    @SuppressWarnings("unchecked")
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.movies_layout);

        moviesAdapter = new MoviesAdapter(this, R.layout.movie_data_row, moviesList);

        moviesList = (ArrayList<Movie>) getIntent().getSerializableExtra("movies");

        setListAdapter(moviesAdapter);

        if (moviesList != null && !moviesList.isEmpty()) {

            moviesAdapter.notifyDataSetChanged();

            moviesAdapter.clear();

            for (int i = 0; i < moviesList.size(); i++) {

                moviesAdapter.add(moviesList.get(i));

            }

        }

        moviesAdapter.notifyDataSetChanged();

    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {

        super.onListItemClick(l, v, position, id);

        Movie movie = moviesAdapter.getItem(position);

        String imdbId = movie.imdbId;

        if (imdbId == null || imdbId.length() == 0) {

            longToast(getString(R.string.no_imdb_id_found));

            return;

        }

        String imdbUrl = IMDB_BASE_URL + movie.imdbId;

        Intent imdbIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(imdbUrl));

        startActivity(imdbIntent);
    }

    public void longToast(CharSequence message) {

        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }
}
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="6dip">

    <ImageView

  android:id="@+id/movie_thumb_icon"

  android:layout_width="wrap_content"

  android:layout_height="fill_parent"

  android:layout_marginRight="6dip"/>

    <LinearLayout

  android:orientation="vertical"

  android:layout_width="0dip"

  android:layout_weight="1"

  android:layout_height="fill_parent">

  <TextView

android:id="@+id/name_text_view"

android:layout_width="fill_parent"

android:layout_height="0dip"

android:layout_weight="1"

android:singleLine="true"

android:ellipsize="marquee"

android:textStyle="bold"

  />

  <TextView

android:id="@+id/rating_text_view"

android:layout_width="fill_parent"

android:layout_height="0dip"

android:layout_weight="1"

android:singleLine="true"

android:ellipsize="marquee"

  />

  <TextView

android:id="@+id/released_text_view"

android:layout_width="fill_parent"

android:layout_height="0dip"

android:layout_weight="1"

android:singleLine="true"

android:ellipsize="marquee"

  />

  <TextView

android:id="@+id/certification_text_view"

android:layout_width="fill_parent"

android:layout_height="0dip"

android:layout_weight="1"

android:singleLine="true"

android:ellipsize="marquee"

  />

  <TextView

android:id="@+id/language_text_view"

android:layout_width="fill_parent"

android:layout_height="0dip"

android:layout_weight="1"

android:singleLine="true"

android:ellipsize="marquee"

  />

  <TextView

android:id="@+id/adult_text_view"

android:layout_width="fill_parent"

android:layout_height="0dip"

android:layout_weight="1"

android:singleLine="true"

android:ellipsize="marquee"

  />

    </LinearLayout>

</LinearLayout>

 
This was an example of how to create a Customized ListView in Android.

Related Article:

Ilias Tsagklis

Ilias is a software developer turned online entrepreneur. He is co-founder and Executive Editor at Java Code Geeks.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button