自定义适配器在getView中抛出一个null异常

时间:2013-07-30 16:14:57

标签: android android-arrayadapter listadapter

我正在尝试使用自定义适配器来设置ListAdapter。我有一个所有者,一个OnwerAdapter,一个OnwerDetail和一个OnwerAsyncTask。我打电话给OwnerAsyncTask获取所有者列表;但是,当我设置列表适配器时,它会抛出异常。尝试设置textView时,将在OwnerAdapter类中抛出该execption。以下是一些示例代码:

//OwnerAdapter
package com.mb.carlovers.adapter;

import com.mb.carlovers.Owner;
import com.mb.carlovers.R;

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

public class OwnerAdapter extends ArrayAdapter<Owner> {

    private Context context;
    private int layoutResourceId;
    private Owner data[] = null;

    public OwnerAdapter(Context context, int textViewResourceId,Owner[] data) {
        super(context, textViewResourceId, data);
        this.context = context;
        this.layoutResourceId = textViewResourceId;
        this.data = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        OwnerHolder holder = null;

        if(row == null)
        {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);
            holder = new OwnerHolder();
            holder.tvFName = (TextView) row.findViewById(R.id.tvFirstName);
            holder.tvLName = (TextView) row.findViewById(R.id.tvLastName);
            holder.tvCId = (TextView) row.findViewById(R.id.tvCarID);
            row.setTag(holder);
        } else
        {
            holder = (OwnerHolder) row.getTag();
        }


        Owner item = data[position];
        String fName = item.getFirstName();

         **//The exception is thrown here.**
       // holder.tvFName.setText(item.setFirstName.toString()); //This was throwing an error.
           holder.tvFName.setText("Tester") //This is still throwing an exception
        holder.tvLName.setText("Example");
        holder.tvCId.setText("1");
        return row;
    }

    static class OwnerHolder
    {
      TextView tvFName;
      TextView tvLName;
      TextView tvCId;
    }
}

// Here is the owner's class

package com.mb.carlovers;

public class Owner {

    private String _firstName;
    private String _lastName;
    private String _carId;
    private Car _car;

    public Owner()
    {
      this._firstName = "";
      this._lastName = "";
      this._carId = "";
    }

    public Owner(String lName)
    {
      this._lastName = lName;
    }
    public Owner(String lName, String cId)
    {
      this._lastName = lName;
      this._carId = cId;
    }

    public Owner(String lName, String fName, String cId)
    {
      this._lastName = lName;
      this._firstName  = fName;
      this._carId = cId;
    }

    public Owner(String lName, String fName, String cId, Car car)
    {
         this._lastName = lName;
         this._firstName  = fName;
         this._carId = cId;
         this._car = car;
    }
    //Getters
    public String getFirstName()
    {
        return _firstName;
    }
    public String getLastName()
    {
        return _lastName;
    }
    public String getCarId()
    {
        return _carId;
    }

    public Car getCar()
    {
        return _car;
    }
    //Setters
    public void setFirstName(String fName)
    {
         _firstName = fName;
    }
    public void setLastName(String lName)
    {
        _lastName = lName;
    }
    public void setCarId(String cId)
    {
        _carId = cId;
    }

    public void setCar(Car car)
    {
        _car = car;
    }
}

//Here is the owner AsyncTask

package com.mb.carlovers.asynctask;

import java.util.ArrayList;
import java.util.List;

import com.mb.carlovers.Owner;
import android.os.AsyncTask;

public class OnwerAsyncTask extends AsyncTask<String, Void, List<Owner>> {

    private List<Owner> items = null;
    @Override
    protected List<Owner> doInBackground(String... params) {

        try
        {
            items = new ArrayList<Owner>();
            Owner own = new Owner();
            own.setFirstName("John");
            own.setLastName("Smith");
            own.setCarId("1");
            items.add(own);

            Owner own1 = new Owner();
            own1.setFirstName("Samantha");
            own1.setLastName("Right");
            own1.setCarId("2");
            items.add(own1);

            Owner own2 = new Owner();
            own2.setFirstName("Regie");
            own2.setLastName("Miller");
            own2.setCarId("3");
            items.add(own2);

            Owner own3 = new Owner();
            own3.setFirstName("Mark");
            own3.setLastName("Adam");
            own3.setCarId("4");
            items.add(own3);

        } catch(Exception ex)
        {
            ex.toString();
        }
        return items;
    }

    @Override
    protected void onPostExecute(List<Owner> result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
    }

}


//Here is the OnwerDetailList whenre the AsyncTask is being called
package com.mb.carlovers;

import java.util.List;
import java.util.concurrent.ExecutionException;

import com.mb.carlovers.adapter.OwnerAdapter;
import com.mb.carlovers.asynctask.OnwerAsyncTask;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

public class OwnerDetail extends ListFragment {

    OwnerAdapter ownerAdapter = null;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.customize_layout,container, false);
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         OnwerAsyncTask asynTask = new OnwerAsyncTask();
            List<Owner> lt = null;
            try {
                lt = asynTask.execute("").get();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Owner myOwners[] = lt.toArray(new Owner[lt.size()]);
            super.onActivityCreated(savedInstanceState);
            ownerAdapter = new OwnerAdapter(getActivity(),android.R.layout.simple_list_item_activated_1 , myOwners);
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setListAdapter(ownerAdapter);
    }
}

这是例外

07-30 14:18:15.155: E/AndroidRuntime(864): FATAL EXCEPTION: main
07-30 14:18:15.155: E/AndroidRuntime(864): java.lang.NullPointerException
07-30 14:18:15.155: E/AndroidRuntime(864):  at com.mb.carlovers.adapter.OwnerAdapter.getView(OwnerAdapter.java:48)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.widget.AbsListView.obtainView(AbsListView.java:2033)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.widget.ListView.onMeasure(ListView.java:1127)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.view.View.measure(View.java:12603)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.view.View.measure(View.java:12603)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.view.View.measure(View.java:12603)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677)
07-30 14:18:15.155: E/AndroidRuntime(864):  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)

1 个答案:

答案 0 :(得分:0)

问题是你使用的simple_list_item_activated_1只包含一个字段:android.R.id.text1。

由于该布局中不存在R.id.tvFirstName,因此findViewById()返回null,并且ViewHolder的属性为null,这就是它抛出空指针异常的原因。

为了使其正常工作,您将不得不使用这些字段创建自定义视图,并将其ID传递给您的适配器。

使用simple_list_item_activated_1可以做的最好的事情就是显示一个字段。使用simple_list_item_activated_2,您可以显示两个字段。对于任何自定义,您必须创建自己的视图。

为了使这个工作与simple_list_item_activated_1一致,你应该注释掉以下几行:

holder.tvLName.setText("Example");
holder.tvCId.setText("1");

并更改此行:

holder.tvFName = (TextView) row.findViewById(R.id.tvFirstName);

为:

holder.tvFName = (TextView) row.findViewById(android.R.id.text1);