Search This Blog

Sunday, 18 March 2012

Chapter 21:GridView using adapters


GridView using adapters

Grid View

GridView is a ViewGroup that displays items in a two-dimensional, scrollable grid. The grid items are automatically inserted to the layout using a ListAdapter.
In this tutorial, you'll create a grid of image thumbnails. When an item is selected, a toast message will display the position of the image.
  1. Start a new project named HelloGridView.
  2. Find some photos you'd like to use, or download these sample images. Save the image files into the project's res/drawable/ directory.
  3. Open the res/layout/main.xml file and insert the following:
    <?xml version="1.0" encoding="utf-8"?>
    <GridView xmlns:android="http://schemas.android.com/apk/res/android" 
        android:id="@+id/gridview"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:columnWidth="90dp"
        android:numColumns="auto_fit"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        android:stretchMode="columnWidth"
        android:gravity="center"
    />
    This GridView will fill the entire screen. The attributes are rather self explanatory. For more information about valid attributes, see the GridView reference.
  4. Open HelloGridView.java and insert the following code for the onCreate() method:
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        GridView gridview = (GridView) findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(this));
        gridview.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                Toast.makeText(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show();
            }
        });
    }
    After the main.xml layout is set for the content view, the GridView is captured from the layout with findViewById(int). The setAdapter() method then sets a custom adapter (ImageAdapter) as the source for all items to be displayed in the grid. The ImageAdapter is created in the next step.
    To do something when an item in the grid is clicked, the setOnItemClickListener() method is passed a new AdapterView.OnItemClickListener. This anonymous instance defines the onItemClick() callback method to show a Toast that displays the index position (zero-based) of the selected item (in a real world scenario, the position could be used to get the full sized image for some other task).
  5. Create a new class called ImageAdapter that extends BaseAdapter:
    public class ImageAdapter extends BaseAdapter {
        private Context mContext;
        public ImageAdapter(Context c) {
            mContext = c;
        }
        public int getCount() {
            return mThumbIds.length;
        }
        public Object getItem(int position) {
            return null;
        }
        public long getItemId(int position) {
            return 0;
        }
        // create a new ImageView for each item referenced by the Adapter
        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imageView;
            if (convertView == null) {  // if it's not recycled, initialize some attributes
                imageView = new ImageView(mContext);
                imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setPadding(8, 8, 8, 8);
            } else {
                imageView = (ImageView) convertView;
            }
            imageView.setImageResource(mThumbIds[position]);
            return imageView;
        }
        // references to our images
        private Integer[] mThumbIds = {
                R.drawable.sample_2, R.drawable.sample_3,
                R.drawable.sample_4, R.drawable.sample_5,
                R.drawable.sample_6, R.drawable.sample_7,
                R.drawable.sample_0, R.drawable.sample_1,
                R.drawable.sample_2, R.drawable.sample_3,
                R.drawable.sample_4, R.drawable.sample_5,
                R.drawable.sample_6, R.drawable.sample_7,
                R.drawable.sample_0, R.drawable.sample_1,
                R.drawable.sample_2, R.drawable.sample_3,
                R.drawable.sample_4, R.drawable.sample_5,
                R.drawable.sample_6, R.drawable.sample_7
        };
    }
    First, this implements some required methods inherited from BaseAdapter. The constructor and getCount() are self-explanatory. Normally, getItem(int) should return the actual object at the specified position in the adapter, but it's ignored for this example. Likewise, getItemId(int) should return the row id of the item, but it's not needed here.
    The first method necessary is getView(). This method creates a new View for each image added to the ImageAdapter. When this is called, a View is passed in, which is normally a recycled object (at least after this has been called once), so there's a check to see if the object is null. If it is null, an ImageView is instantiated and configured with desired properties for the image presentation:
    • setLayoutParams(ViewGroup.LayoutParams) sets the height and width for the View—this ensures that, no matter the size of the drawable, each image is resized and cropped to fit in these dimensions, as appropriate.
    • setScaleType(ImageView.ScaleType) declares that images should be cropped toward the center (if necessary).
    • setPadding(int, int, int, int) defines the padding for all sides. (Note that, if the images have different aspect-ratios, then less padding will cause for more cropping of the image if it does not match the dimensions given to the ImageView.)
    If the View passed to getView() is not null, then the local ImageView is initialized with the recycled View object.
    At the end of the getView() method, the position integer passed into the method is used to select an image from the mThumbIds array, which is set as the image resource for the ImageView.
    All that's left is to define the mThumbIds array of drawable resources.
  6. Run the application.
Your grid layout should look something like this:

Example

This sample android program shows you how to use GridView in Android. In this program a list is shown as a grid. When you click on the list, the selected item is shown on the text view. You can use this ArrayAdapter widget and the GridView object together with the onListItemClick() method to determine the selected index and process accordingly.
The GridViewDemo.java file is as follows:
package com.javasamples;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.TextView;


public class GridViewDemo extends Activity implements
                AdapterView.OnItemClickListener {

        TextView selection;
        String[] items = { "this", "is", "a", "really", "really2", "really3",
                        "really4", "really5", "silly", "list" };

        @Override
        public void onCreate(Bundle icicle) {
                super.onCreate(icicle);
                setContentView(R.layout.main);
                selection = (TextView) findViewById(R.id.selection);

                GridView gv = (GridView) findViewById(R.id.grid);

                ArrayAdapter<String> aa = new ArrayAdapter<String>(
                                this,
                                android.R.layout.simple_list_item_1, 
                                items );

                gv.setAdapter(aa);
                gv.setOnItemClickListener(this);
        }

        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                selection.setText(items[position]);
        }
        
}// class

The output of this program will be as shown in the android emulator below.

The main.xml file in your res/layout folder is as follows:
<?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:id="@+id/selection"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#ff0033cc"
          android:textSize="14pt"
          android:textStyle="bold"
        
        />
    <GridView
        android:id="@+id/grid"
        android:background="#ff0000ff"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:verticalSpacing="35px"
        android:horizontalSpacing="5px"
        android:numColumns="auto_fit"
        android:columnWidth="100px"
        android:stretchMode="columnWidth"
        android:gravity="center"
        />
</LinearLayout>

Android: Creating a custom Adapter for GridView (ButtonAdapter)




Background
This is the attempt at a casual explanation of how to create your own custom adapter, in this example we will create a ButtonAdapter similar to something you might see in a soundboard (yawn).

Example of a grid adapter in use
Advantages of an adapter
  • Dynamic – Can expand to any number of elements rather than statically coding each individual view.
  • Elegant – Makes your code petite and quite clear to understand once you get over the initial difficulty
  • Beautiful – Now you don’t have to control how many items there are in rows or columns, android will automatically fill up the screen in the best way possible. This also means you don’t need to redesign your application for horizontal and vertical orientations.
Creating a ButtonAdapter
So we’re going to dive straight into the deep end and create our own ButtonAdapter class that extends the BaseAdapter class. If you are doing this in eclipse you can write the first line and then it will offer to autocreate (implement) the missing methods for you (if you highlight the error). This code goes inside your Activity in your java file but not inside your oncreate method.
view plaincopy to clipboardprint?
    public class ButtonAdapter extends BaseAdapter {  
     private Context mContext;    
     // Gets the context so it can be used later  
     public ButtonAdapter(Context c) {  
      mContext = c;  
     }  
      
     // Total number of things contained within the adapter  
     public int getCount() {  
      return filenames.length;  
     }  
      
      // Require for structure, not really used in my code.  
     public Object getItem(int position) {  
      return null;  
     }  
      
     // Require for structure, not really used in my code. Can  
     // be used to get the id of an item in the adapter for  
     // manual control.  
     public long getItemId(int position) {  
      return position;  
     }  
      
     public View getView(int position,  
                               View convertView, ViewGroup parent) {  
      Button btn;  
      if (convertView == null) {  
       // if it's not recycled, initialize some attributes  
       btn = new Button(mContext);  
       btn.setLayoutParams(new GridView.LayoutParams(100, 55));  
       btn.setPadding(8, 8, 8, 8);  
       }  
      else {  
       btn = (Button) convertView;  
      }  
      exus  
      btn.setText(filesnames[position]);  
      // filenames is an array of strings  
      btn.setTextColor(Color.WHITE);  
      btn.setBackgroundResource(R.drawable.button);  
      btn.setId(position);  
      
      return btn;  
     }  

So the important methods are getCount and getView. getCount returns the number of objects (in our case buttons) that will be needed in this adapter. getView returns an object (again a button in our case) so that it can be used.
Both these functions reference an array that I have referered to as filenames this is a string array (String[]) which looks something like the following:
view plaincopy to clipboardprint?
    public String[] filesnames = {  
                "File 1",  
                "File 2",  
                "Roflcopters"  
                }; 
Creating an OnClickListener
You can add the following to your getView method to setup a new onclick listener for your buttons so that they can react to button presses.
view plaincopy to clipboardprint?
    // Set the onclicklistener so that pressing the button fires an event  
    // We will need to implement this onclicklistner.  
    btn.setOnClickListener(new MyOnClickListener(position)); 
For this to work we need to implement our own OnClickListner which I have named MyOnClickListener (for lack of a better name) this is the same as a normal onclick listner except we pass an integer so that we can tell which button called our onClick method (you could get the id from the view passed, but this method is useful when expanding your program later on).
view plaincopy to clipboardprint?
    class MyOnClickListener implements OnClickListener  
    {  
     private final int position;  
      
     public MyOnClickListener(int position)  
     {  
      this.position = position;  
     }  
      
     public void onClick(View v)  
     {  
      // Preform a function based on the position  
      someFunction(this.position)  
     }  

Implementing this adapter
Now implementing the adapater is very simple, add a few imports and load a grid view from an xml file. Then we simply set the gridview’s adapter to be a new ButtonAdapter and it will automatically do the rest for us.
view plaincopy to clipboardprint?
    // You will need the following imports  
      
    import android.widget.BaseAdapter;  
    import android.widget.Button;  
  1. import android.widget.GridView;  
  2.   
  3. // In your oncreate (or where ever you want to create your gridview)  
  4. GridView gridview = (GridView) findViewById(R.id.gridview);  
  5. gridview.setAdapter(new ButtonAdapter(this)); 





http://developer.android.com/reference/android/widget/GridView.html


No comments:

Post a Comment