user2991828
user2991828

Reputation: 163

Android Grid View with Custom base Adapter

i have started to learn android development. i am making an app in which i want to show movie thumbnails(image view and text view) combined in grid view layout i have made custom adapter but problem is that i cannot figure it out how to show image view and text view together.when i run app it shows blank white screen. i have tried many solution and also googled a lot but i cannot figure it out how to do this please help me. Here is my code.

    public class ImageAdapter extends BaseAdapter {

    private Context mContext;
    private LayoutInflater inflater;
    public ImageAdapter(Context c) {

        mContext = c;
      //
    }

    @Override
    public int getCount() {
        return mThumbIds.length;
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

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


        NewHolder holder = null;
        ImageView imageView;

        inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE );



        if(convertView==null){
            holder = new NewHolder();

            convertView =inflater.inflate(R.layout.activity_main,viewGroup,false);


            holder.imageView = new ImageView(mContext);
            holder.textView = new TextView(mContext);

            holder.imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            holder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);



         //   holder.textView.setLayoutParams(new GridView.LayoutParams(85, 85));

            convertView.setTag(holder);
            //textView.
           // textView.setText("Hello");
            holder.imageView.setPadding(8, 8, 8, 8);

        }


        else {
            holder = (NewHolder) convertView.getTag();
            //imageView= (ImageView) convertView. ;
            //textView = (TextView) convertView;
        }


//        convertView.
        holder.imageView.setImageResource(mThumbIds[position]);
     //   holder.textView.setText("hello");
        return convertView;



    }



    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
    };

}

Main Activity

public class MainActivity extends AppCompatActivity {

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

        GridView gridview = (GridView) findViewById(R.id.grid_view);
        gridview.setAdapter(new ImageAdapter(this));
     //   setContentView(gridview);

    }

Holder Class

public class NewHolder {

        public ImageView imageView;
        public TextView textView;
    }

Main Xml Layout File

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/grid_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnWidth="90dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
    />

Upvotes: 2

Views: 7402

Answers (3)

Krupal Shah
Krupal Shah

Reputation: 9187

You should not inflate the main activity layout in your adapter. Instead you should have a layout of the individual row to inflate in your getView() method.

What you have to do is, You have to give adapter a list of data you want to set in gridview. Adapter inflates the rows (the individual item in Grid) according to the count of data(models) given, then you will have to assign the data to the individual elements of the row.

So, I have corrected the adapter. Hope this will be helpful:

    public class ImageAdapter extends BaseAdapter {

    private Context mContext;
    private LayoutInflater inflater;



    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
    };

    private String mTexts[]={"a","b","d",....,"your texts"};

    public ImageAdapter(Context c) {
        mContext = c;
    }

    @Override
    public int getCount() {
        return mThumbIds.length; // adapter inflates the row according to the count of data given
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return mThumbIds.length;// inflates rows according to data given
    }

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


        NewHolder holder = null;
        ImageView imageView;

        if(convertView==null){//if convert view is null then only inflate the row
            inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
            convertView = inflater.inflate(R.layout.grid_item_layout,viewGroup,false);

            holder = new NewHolder();

            //find views in item row
            holder.imageView = (ImageView)convertView.findViewById(R.id.imageview_id);
            holder.textView = (ImageView)convertView.findViewById(R.id.textview_id);

            convertView.setTag(holder);
        }
        else { //otherwise get holder from tag
            holder = (NewHolder) convertView.getTag();
        }

        //set data here
        holder.imageView.setImageResource(mThumbIds[position]);
        holder.textView.setText(mTexts[position]);

        return convertView;
    }

    public class NewHolder {
        public ImageView imageView;
        public TextView textView;
    }

}

and your grid_item.xml should have layout for each item in GridView like:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp" >

<ImageView
        android:id="@+id/textview_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

 <TextView android:id="@+id/imageview_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

Upvotes: 1

VirtualProdigy
VirtualProdigy

Reputation: 1687

Here's the solution to your issue. You're using the adapter incorrectly. You're inflating the 'GridView' with the adapter in this line.

convertView =inflater.inflate(R.layout.activity_main,viewGroup,false);

That's no what you want to do. You want to make an other XML Layout that represents each movie's title in a TextView and image in an Imageview

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/movieimage"
    android:src="@drawable/moviethumb"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/movie_title"
    android:id="@+id/todo_list_item_bottom_text"
    android:layout_marginTop="10dp"
    android:textSize="12sp"/>
</LinearLayout>

This tutorial should help you. It's for a list view but all adapters in android pretty much work the same way. Adapter Tutorial

I noticed a something you can improve upon. Put your inflator inside you convertview == null. There's no point to creating this object when it's not used.

Upvotes: 1

dieter_h
dieter_h

Reputation: 2727

Make your own grid item layout.

layout/grid_item.xml

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

    <ImageView
        android:id="@+id/gridItemIV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/gridItemTextTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Medium Text"
        android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>

Change:

    if(convertView==null){
        holder = new NewHolder();
        convertView =inflater.inflate(R.layout.grid_item,viewGroup,false);

            holder.imageView = (ImageView)convertView.findViewById(R.id.gridItemIV)
            holder.textView = (TextView)convertView.findViewById(R.id.gridItemTextTV)
     }else {
...

Upvotes: 0

Related Questions