Question

I created my own custom adapter that extends Array Adapter:

public class AdapterGeoArea extends ArrayAdapter<GeoArea>{
    private Context _context;   
    private int resource;
    private ArrayList<GeoArea> _myGeoArea;

    public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
        super(context, 0, myGeoArea);
        _context = context;
        _myGeoArea = myGeoArea;
    }

    public int getCount() {
        return _myGeoArea.size();
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        LinearLayout GeoAreaView;
        if (convertView == null) { 
            GeoAreaView = new LinearLayout(_context);
            LayoutInflater li = LayoutInflater.from(_context);
            convertView = li.inflate(R.layout.layout_geo_areas, null);
        }
        else {
            GeoAreaView = (LinearLayout) convertView;
        }

        GeoArea curGeoArea = _myGeoArea.get(position);

        TextView name = (TextView) GeoAreaView.findViewById(R.id.txtGeoAreaName);
        name.setText(curGeoArea.name);

        return convertView;
    }

    static class ViewHolder { 
        TextView name;
        RelativeLayout childContainer;
    }

    @Override
    public Filter getFilter() {
        return null;
    }
}

And here is how I am using it in my main:

public class ActivityGeoAreas extends Activity {

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

        GeoArea.searchTerm =  "Bar & Grill";

        GeoArea torontoArea = new GeoArea("cityOfToronto");

        ArrayList<GeoArea> testList = new ArrayList<GeoArea>();
        testList.add(torontoArea);

        AdapterGeoArea adapter = new AdapterGeoArea(this, testList);

        ListView lv = (ListView) findViewById(R.id.textGeoArea);
        lv.setAdapter(adapter);

    }

}

Everything seem to be fine except for this line:

 TextView name = (TextView) GeoAreaView.findViewById(R.id.textGeoArea);

And here is how I defined my layout:

<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".ActivityGeoAreas" >

    <TextView
        android:id="@+id/textGeoArea"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Choose Area"
        android:textAppearance="?android:attr/textAppearanceLarge" />


    <LinearLayout
        android:id="@+id/LinearLayoutGeoAreas"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textGeoArea"
        android:layout_below="@+id/textGeoArea"
        android:orientation="vertical" >
        <ListView
            android:id="@+id/listViewGeoArea"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" >
        </ListView>

    </LinearLayout>
</RelativeLayout>

It simply can't find the TextView textGeoArea and this line become null, what am I doing wrong?

Was it helpful?

Solution

Change this

TextView name = (TextView) GeoAreaView.findViewById(R.id.txtGeoAreaName);

to

TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);

I guess you have got confused.

Move textview to a new layout list_item.xml

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

<TextView
    android:id="@+id/textGeoArea"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="14dp"
    android:text="Choose Area"
    android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

Now change your getView as below

 LayoutInflater inflater;
 public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
    super(context, 0, myGeoArea);
    _context = context;
    _myGeoArea = myGeoArea;
    inflater = LayoutInflater.from(context); // initialize inflater
}


 public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {  
            convertView = inflater.inflate(R.layout.list_row,parent,false);
            holder = new ViewHolder();
            holder.tv = (TextView)convertView.findViewById(R.id.textGeoArea); 
            holder.setTag(convertView);

        }
        else { 
                holder = (ViewHolder) convertView.getTag(); 
        } 
        GeoArea curGeoArea = _myGeoArea.get(position);
        holder.tv.setText(curGeoArea.name);

        return convertView;
    }

static class ViewHolder  // use a view holder for smooth scrolling an performance
{
TextView tv;
}

OTHER TIPS

On the first pass, GeoAreaView is a childless LinearLayout since you just created it. convertView is the View initialized your layout which holds the TextView. So you need to use that to find the TextView.

TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);

I see you have a ViewHolder but you don't appear to be using it. You may want to take a little time and go through a good tutorial on using ListView.

This guy usually seems to have good tutorials

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top