Android: BaseAdapter and getLayoutInflater on separate class file
Asked Answered
S

4

29

Right now to populate my GridViews I'm using a extended BaseAdapter class on each of my Android Activities (which are most of them).

In order to make it easier to read and maintain, I`m trying to put all the BaseAdapter code in a separate class file.

To populate the GridView, I'm using LayoutInflater, and here is where stuff gets tricky...

Since the getLayoutInflater() comes from android.Activity, it just won't do the trick. I tried making my Adapter.java(the class to populate the GridViews) a extended Activity class, and then inside create the BaseAdapter class (the way I do it right now), but I haven't been able to make it work properly.

Here's how Adapter.java looks:

//Adapter.java
package com.cimp.matitec;

import greendroid.app.GDActivity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class Adapter extends GDActivity{

public class ImageAdapter extends BaseAdapter
{
   Context MyContext;
   int count;
   String[] nombre;

   public ImageAdapter(Context _MyContext, int n, String[] nombre)
   {
      MyContext = _MyContext;
      count = n;
      this.nombre = nombre;
   }

   public int getCount()
   {
                     /* Set the number of element we want on the grid */
      return count;
   }

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

      if ( convertView == null )
      {
         /*we define the view that will display on the grid*/

         //Inflate the layout
         LayoutInflater li = getLayoutInflater();
         MyView = li.inflate(R.layout.grid_item, null);

         // Add The Text!!!
         TextView tv = (TextView)MyView.findViewById(R.id.grid_item_text);
         tv.setText(nombre[position]+"");

         // Add The Image!!!           
         ImageView iv = (ImageView)MyView.findViewById(R.id.grid_item_image);
         iv.setImageResource(R.drawable.ic_launcher);
      }

      return MyView;
   }

   @Override
   public Object getItem(int arg0) {
      // TODO Auto-generated method stub
      return null;
   }

   @Override
   public long getItemId(int arg0) {
      // TODO Auto-generated method stub
      return 0;
   }
}
}

To call it from the outside, I do the following:

//MainClass.java
Adapter MyGridAdapter = new Adapter();
MyGrid = (GridView)findViewById(R.id.grid);
MyGrid.setAdapter(MyGridAdapter.new ImageAdapter(this, 6, nombreTema));

The app runs, but when trying to populate, I got a NullPointerException getLayoutInflater().

Someone knows what I'm missing, or how to make it work properly?

Slaveholder answered 28/12, 2011 at 23:35 Comment(4)
Does GDActivity extend Activity?Deejay
Yup, is a Greendroid ActivitySlaveholder
From OO perspective, Adapter is not a Activity, your code is just not reasonable. You search for simplicity but end up with time and complexity, the way Google recommended might not be the most perfect, but it is the most reasonable and efficient, at least IMO.Gentilis
I know is kinda weird, but I couldn't find any other way to do it. All I need is to make the BaseAdapter to workSlaveholder
P
76

There are more ways to get a LayoutInflater object than directly from an Activity. As a matter of fact, getLayoutInflater() is probably just a convenience method for this:

LayoutInflater li = (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

Please see the documentation for LayoutInflater.

Pederson answered 29/12, 2011 at 0:27 Comment(1)
I did and tried something similar when starting, dunno why it didn't work that time, but now it does :). Thanks a lot.Slaveholder
C
6

you should pass the context of MainActivity when creating an object of the class that extends baseadapter something like this LayoutInflater inflater = ((Activity)MyContext)).getLayoutInflater;

this would cast MyContext to an Activity and then GetLayoutInflater() could be called!!

Carotenoid answered 22/12, 2014 at 9:49 Comment(1)
That casting is really good solution! Thanks.Prove
D
3

Read this...

Application Fundamentals

...especially the bit on Activities in the Application Components section.

Do NOT try to instantiate an Activity using new. An Activity is a special-case Android class and should NOT be treated like a regular Java class. An Activity should only be started using an Intent and it's the Android OS's responsibility for instantiating it.

In other words, never do this...

Adapter MyGridAdapter = new Adapter();

Also, Adapter is the name of an Android widget class so not a good choice for the name of one of your own classes.

EDIT: Also see my answer to this question here about creating a helper class and passing the activity's Context to it.

Deejay answered 28/12, 2011 at 23:57 Comment(5)
Im already doing that, I send context to the BaseAdapter... The problem is that I get the The method getLayoutInflater() is undefined for the type ImageAdapter, that's why Im extending to ActivitySlaveholder
You obviously didn't read the comment to my answer where I explain to the other person to use mContext.getSystemService(...) in his case. The same applies to your MyContext (which should start with a lower case letter by convention). You can use MyContext.getLayoutInflater() alternatively getApplicationContext().getLayoutInflater() should work. Either way, never try to instantiate an Activity with new.Deejay
I did read what you post, and tried it... Im trying LayoutInflater li = MyContext.getLayoutInflater(); (I'll fix cases later, since some of the code ain't mine) and it shows a The method getLayoutInflater() is undefined for the type ContextSlaveholder
OK sorry, it needs to be cast to an Activity as in ((Activity)MyContext).getLayoutInflater(). I see you've accepted an answer and have it working but that cast from Context to Activity may be of use for you in future situations.Deejay
Yeah, it will be helpful. Thanks a lot.Slaveholder
E
2

The best way is to use a static method LayoutInflator object with applicationcontext as the only parameter to get inflator.

Equinoctial answered 15/7, 2017 at 17:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.