Sunday, October 4, 2015

How to use BaseAdapter in Android

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:background="#fff"
    >
    <GridView
        android:id="@+id/gv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:horizontalSpacing="5dp"
        android:verticalSpacing="5dp"
        android:padding="5dp"
        android:gravity="left"
        android:background="#cacac5"
        />
</RelativeLayout>
MainActivity.java

package com.cfsuman.me.baseadapterexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.GridView;
import android.content.Context;
import android.view.WindowManager;
import android.view.Display;
import android.graphics.Point;

public class MainActivity extends AppCompatActivity {
    private Context mContext;
    private int gridview_column_width = 200; // In pixels

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

        mContext = getApplicationContext();

        // Get the widget reference from XML layout
        GridView gv = (GridView) findViewById(R.id.gv);

        // Initialize a new instance of BaseAdapter
        MyBaseAdapter adapter = new MyBaseAdapter(mContext);
        // Data bind the GridView with BaseAdapter
        gv.setAdapter(adapter);

        // Set GridView number of columns
        setGridViewNumberOfColumns(gv);
    }

    // Set the GridView number of columns
    private void setGridViewNumberOfColumns(GridView gv){
        int numberOfColumns = Math.round(getScreenWidth()/gridview_column_width);
        if(numberOfColumns<=2){
            gv.setNumColumns(GridView.AUTO_FIT);
        }
        else{
            gv.setNumColumns(numberOfColumns);
        }
    }

    // Get the screen width in pixels
    private int getScreenWidth(){
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int width = size.x;
        return width;
    }
}
MyBaseAdapter.java

package com.cfsuman.me.baseadapterexample;

import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Typeface;
import android.util.TypedValue;
import android.widget.BaseAdapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.graphics.Bitmap;
import android.widget.TextView;
import android.os.AsyncTask;

import java.io.IOException;
import java.io.InputStream;

/*
    Follow Field Naming Conventions
        Non-public, non-static field names start with m.
        Static field names start with s.
        Other fields start with a lower case letter.
        Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.
*/
public class MyBaseAdapter extends BaseAdapter {
    private Context mContext;
    private String mImageFolder = "animals";
    private int mImageWidth = 200; // In pixels
    private int mImageHeight = 100; // In pixels

    MyBaseAdapter(Context context){
        mContext = context;
    }

    // Get the image list from asset sub folder
    public String[] getImages(){
        String[] images = new String[]{};
        try{
            images = mContext.getAssets().list(mImageFolder);
        }catch (IOException e)
        {
            e.printStackTrace();
        }
        return images;
    }

    // Generate an ImageView from asset image
    public ImageView generateImageView(int position){
        final ImageView iv = new ImageView(mContext);
        iv.setLayoutParams(new LayoutParams(mImageWidth, mImageHeight));
        iv.setPadding(5, 5, 5, 5);
        iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
        iv.setBackgroundColor(Color.parseColor("#FFFEFFF6"));
        final String currentImageFile = mImageFolder+"/"+(getImages()[position]);

        // Initialize a new AsyncTask to read image
        /*
            Void for doInBackground()
            Void for onProgressUpdate()
            Bitmap for onPostExecute()
        */
        new AsyncTask<Void,Void,Bitmap>()
        {
            @Override
            protected Bitmap doInBackground(Void... voids){
                Bitmap bitmap = Bitmap.createBitmap(1,1, Bitmap.Config.ARGB_8888);
                try{
                    InputStream is;
                    is = mContext.getAssets().open(currentImageFile);
                    bitmap = BitmapFactory.decodeStream(is);
                }catch (IOException e){
                    e.printStackTrace();
                }
                return bitmap;
            }
            protected void onPostExecute(Bitmap result){
                iv.setImageBitmap(result);
            }
        }.execute();

        // Return the ImageView
        return iv;
    }

    // Generate a TextView to display image name
    public TextView generateTextView(int position){
        // Initialize a new TextView widget
        TextView tv = new TextView(mContext);
        tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

        // Get the current image name
        String imageName = getImages()[position];
        int endingIndex = imageName.indexOf('.');
        if(endingIndex>=0){
            // Get image name without extension
            imageName = imageName.substring(0,endingIndex);
        }

        tv.setText(imageName);
        tv.setTextColor(Color.BLACK);
        tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 8);
        tv.setTypeface(Typeface.MONOSPACE, Typeface.ITALIC);
        // Return the TextView
        return tv;
    }

    /*
        public abstract int getCount ()
            How many items are in the data set represented by this Adapter.

            Returns
                Count of items.
    */
    public int getCount(){
        return getImages().length;
    }

    /*
        public abstract Object getItem (int position)
            Get the data item associated with the specified position in the data set.

            Parameters
                position : Position of the item whose data we want within the adapter's data set.
            Returns
                The data at the specified position.
    */
    public Object getItem(int position){
        return null;
    }

    /*
        public abstract long getItemId (int position)
            Get the row id associated with the specified position in the list.

            Parameters
                position : The position of the item within the adapter's data set whose row id we want.
            Returns
                The id of the item at the specified position.
    */
    public long getItemId(int position){
        return 0;
    }

    /*
        public abstract View getView (int position, View convertView, ViewGroup parent)
            Get a View that displays the data at the specified position in the data set. You can
            either create a View manually or inflate it from an XML layout file. When the View is
            inflated, the parent View (GridView, ListView...) will apply default layout parameters
            unless you use inflate(int, android.view.ViewGroup, boolean) to specify a root
            view and to prevent attachment to the root.

            Parameters
                position : The position of the item within the adapter's data set of the
                    item whose view we want.
                convertView : The old view to reuse, if possible. Note: You should check that this
                    view is non-null and of an appropriate type before using. If it is not possible
                    to convert this view to display the correct data, this method can create a new
                    view. Heterogeneous lists can specify their number of view types, so that this
                    View is always of the right type (see getViewTypeCount() and getItemViewType(int)).
                parent : The parent that this view will eventually be attached to

            Returns
                A View corresponding to the data at the specified position.
    */
    public View getView(final int position, View convertView, ViewGroup parent){
        // Initialize a new RelativeLayout
        RelativeLayout rl = new RelativeLayout(mContext);
        rl.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        rl.setPadding(2, 2, 2, 2);
        rl.setBackgroundColor(Color.parseColor("#FFFEFFF6"));

        // Generate a new ImageView object
        ImageView iv = generateImageView(position);
        // Set an id for ImageView
        iv.setId(position+1);

        // Set a click listener for ImageView
        iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Do something
            }
        });

        // Generate a new TextView widget
        TextView tv = generateTextView(position);
        // Specify the layout rule of TextView
        ((LayoutParams) tv.getLayoutParams()).addRule(RelativeLayout.BELOW, iv.getId());
        ((LayoutParams) tv.getLayoutParams()).addRule(RelativeLayout.CENTER_HORIZONTAL);

        // Add ImageView to RelativeLayout
        rl.addView(iv);
        // Add TextView to RelativeLayout
        rl.addView(tv);

        // Return the RelativeLayout
        return rl;
    }
}

More android examples