Question

I seem to have hit a wall with my custom ArrayAdapter. I'd started to access specific R elements, depending on the class type passed in, but since then BOOM! (with the below NPE). Trouble is, it's not listing any of my code, and I'm flying a little blind. I know it's my code, because commenting out the setListAdapter (and the other bits), will run fine. I just don't know what I've done.

I'm only testing the ArrayAdapter at the moment, hence the for loop creating objects. But at least I know those are not null, as I've stepped through the code as far as I can.

Any help is greatly appreciated. I'm quite sure I'm doing something stupid, but it's been an hour now and I've gone code-blind!

Many thanks.

PS. I've checked other questions, but most appear to be regarding null objects being sent across, or people not creating layouts correctly, or instantiating. Mine would appear to be completely different as LogCat doesn't display any links to my code :(

LogCat:

11-19 13:12:44.968: E/AndroidRuntime(7406): FATAL EXCEPTION: main
11-19 13:12:44.968: E/AndroidRuntime(7406): java.lang.NullPointerException
11-19 13:12:44.968: E/AndroidRuntime(7406):     at  android.widget.AbsListView.obtainView(AbsListView.java:1454)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.widget.ListView.makeAndAddView(ListView.java:1745)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.widget.ListView.fillDown(ListView.java:670)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.widget.ListView.fillFromTop(ListView.java:727)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.widget.ListView.layoutChildren(ListView.java:1598)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.widget.AbsListView.onLayout(AbsListView.java:1282)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.view.View.layout(View.java:7175)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.view.View.layout(View.java:7175)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.view.View.layout(View.java:7175)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1140)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.os.Looper.loop(Looper.java:130)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at android.app.ActivityThread.main(ActivityThread.java:3683)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at java.lang.reflect.Method.invokeNative(Native Method)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at java.lang.reflect.Method.invoke(Method.java:507)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-19 13:12:44.968: E/AndroidRuntime(7406):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
11-19 13:12:44.968: E/AndroidRuntime(7406):     at dalvik.system.NativeStart.main(Native Method)

ListActivity:

package com.goosesys.dta_pta_test;

import com.goosesys.gooselib.Views.GooseArrayAdapter;
import com.goosesys.gooselib.Views.GooseDeliveryItem;
import com.goosesys.gooselib.Interfaces.*;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ListView;
import android.widget.Toast;

public class DeliveryList extends ListActivity implements OnTaskFinished {
public String response = "";

static String[] vals;
static String[] vals2;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); 

    populate();
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id){
    String selectedValue = (String)getListAdapter().getItem(position);
    Toast.makeText(this, selectedValue, Toast.LENGTH_LONG).show();
}

private void populate(){
    //new GetFromNetTask(this).execute(AppSettings.DELIV_LIST_URL);
    GooseDeliveryItem[] deliveries = new GooseDeliveryItem[50];

    for(int i=0; i<50; i++){
        GooseDeliveryItem gdi = new GooseDeliveryItem(i, "Some Customer " + String.valueOf(i));
        deliveries[i] = gdi;
    }

    setListAdapter(new GooseArrayAdapter<Object>(this, R.layout.goose_delivery_item, deliveries));
    ListView listView = getListView();
    listView.setTextFilterEnabled(true);

    // on click stuff here

}

@Override
public void onTaskFinished(String result) {
}
}

ArrayAdapter:

package com.goosesys.gooselib.Views;

import com.goosesys.gooselib.R;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.content.Context;

public class GooseArrayAdapter<T> extends ArrayAdapter<T> {
private Context context;
private int layoutResId;
T data[] = null;

public GooseArrayAdapter(Context context, int layoutResId, T[] data){
    super(context, layoutResId, data);

    this.layoutResId = layoutResId;
    this.context = context;
    this.data = data;
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
    LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(this.layoutResId, parent, false);           

    T obj = data[position];

    //if(obj instanceof GooseDeliveryItem){
        //TextView tv = (TextView)rowView.findViewById(R.id.customerName);
        //tv.setText(((GooseDeliveryItem)obj).customerText);
    //}

    return convertView;
}   
}

How I'm calling the Intent from my main activity:

    GooseMenuItem gmi2 = (GooseMenuItem)findViewById(R.id.gmiDelivery);
    gmi2.setHeaderText("DELIVERIES");
    gmi2.setDescriptionText("Out and about");
    gmi2.setButtonImageSrc(getResources().getDrawable(R.drawable.truck));
    gmi2.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent i = new Intent(Main.this, DeliveryList.class);
            startActivity(i);
        }
    });

The horrible goose_delivery_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/White"
android:orientation="horizontal" >

<TableLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" >

    <TableRow
        android:id="@+id/tableRow1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <ImageView
            android:id="@+id/listImage"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:maxHeight="40dp"
            android:maxWidth="40dp"
            android:padding="2dp"
            android:scaleType="fitCenter"
            android:src="@drawable/truck" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent" >

            <TextView
                android:id="@+id/customerName"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="CUSTOMER NAME/ADDRESS"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:textColor="@color/black" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="left"
            android:orientation="vertical" >

            <ImageView
                android:id="@+id/mapPointImage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="3dp"
                android:scaleType="centerInside"
                android:src="@drawable/mappoint" />

        </LinearLayout>

    </TableRow>
</TableLayout>

</RelativeLayout>
Was it helpful?

Solution

Your getView function returns null, since you never return anything but the passed argument. Initially convertView will be null, and you need to initialize it. Afterwards, if it is not null, you can simply reuse it.

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

    ...
    if (convertView == null) {
        convertView = ... // Create you view here
    }

    return convertView;
}

OTHER TIPS

Try to change your getView to:

@Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(this.layoutResId, parent, false);           

T obj = data[position];

//if(obj instanceof GooseDeliveryItem){
    //TextView tv = (TextView)rowView.findViewById(R.id.customerName);
    //tv.setText(((GooseDeliveryItem)obj).customerText);
//}

return rowView ;
}

return rowView instead of convertView, as convertView is never assigned

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