ExpandableListView适配器上的空指针异常

时间:2014-01-19 04:20:47

标签: android expandablelistview

01-19 04:16:31.497: E/AndroidRuntime(878): FATAL EXCEPTION: main
01-19 04:16:31.497: E/AndroidRuntime(878): java.lang.NullPointerException
01-19 04:16:31.497: E/AndroidRuntime(878):  at com.psesto.expandablelistview.ExpandableListAdapter.getChildrenCount(ExpandableListAdapter.java:68)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.widget.ExpandableListConnector.refreshExpGroupMetadataList(ExpandableListConnector.java:563)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.widget.ExpandableListConnector.expandGroup(ExpandableListConnector.java:688)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.widget.ExpandableListView.handleItemClick(ExpandableListView.java:562)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.widget.ExpandableListView.performItemClick(ExpandableListView.java:522)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.widget.AbsListView$PerformClick.run(AbsListView.java:2749)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.widget.AbsListView$1.run(AbsListView.java:3423)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.os.Handler.handleCallback(Handler.java:725)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.os.Handler.dispatchMessage(Handler.java:92)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.os.Looper.loop(Looper.java:137)
01-19 04:16:31.497: E/AndroidRuntime(878):  at android.app.ActivityThread.main(ActivityThread.java:5041)
01-19 04:16:31.497: E/AndroidRuntime(878):  at java.lang.reflect.Method.invokeNative(Native Method)
01-19 04:16:31.497: E/AndroidRuntime(878):  at java.lang.reflect.Method.invoke(Method.java:511)
01-19 04:16:31.497: E/AndroidRuntime(878):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-19 04:16:31.497: E/AndroidRuntime(878):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)

这是ExpandableListAdapter.java

public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private Context mContext;
    private ArrayList<ContactNameItems> mListDataHeader;// header titles

    // child data in format of header title, child title
    private HashMap<String, List<String>> mListDataChild;

    public ExpandableListAdapter(Context context, ArrayList<ContactNameItems> listDataHeader,
            HashMap<String, List<String>> listChildData) {
        this.mContext = context;
        this.mListDataHeader = listDataHeader;
        this.mListDataChild = listChildData;        
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {

        return this.mListDataChild.get(this.mListDataHeader.get(groupPosition))
                .get(childPosition);
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {

        return childPosition;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {

        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {

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

            convertView = inflater.inflate(R.layout.list_item, null);
        }

        TextView txtListChild = (TextView) convertView
                .findViewById(R.id.lblListItem);
        txtListChild.setText(childText);

        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {

/* line 68 */return this.mListDataChild.get(this.mListDataHeader.get(groupPosition))
/* line 69 */   .size();
    }

    @Override
    public ContactNameItems getGroup(int groupPosition) {

        return this.mListDataHeader.get(groupPosition);
    }

    @Override
    public int getGroupCount() {

        return this.mListDataHeader.size();
    }

    @Override
    public long getGroupId(int groupPosition) {

        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {

        String headerTitle = getGroup(groupPosition).getName();
        Bitmap image = getGroup(groupPosition).getImage();

        if (convertView == null) {

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

            convertView = inflater.inflate(R.layout.list_group, null);
        }

        TextView lblListHeader = (TextView) convertView
                .findViewById(R.id.lblListHeader);
        lblListHeader.setText(headerTitle);

        ImageView imageView = (ImageView) convertView
                .findViewById(R.id.ivContactPhoto);

        if (image != null) {
            imageView.setImageBitmap(image);

        } else {
            imageView.setImageResource(R.drawable.default_contact);
        }

        return convertView;
    }

    @Override
    public boolean hasStableIds() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        // TODO Auto-generated method stub
        return true;
    }

}

这是使用该适配器类的活动(片段):

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;

public class MainActivity extends Activity {

    private final String NAME_ARRAY_KEY = "name_array_key";
    private ArrayList<ContactNameItems> mContactNameItems;

    private ProgressDialog mDialog;

    private Bundle mBundle;
    private Bundle mPassToFragBundle;

    private String contactName, contactId;

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

        mBundle = savedInstanceState;
        mPassToFragBundle = new Bundle();

        mContactNameItems = new ArrayList<ContactNameItems>();

        GetContactsTask getContactsTask = new GetContactsTask();
        getContactsTask.execute();

    }

    private class GetContactsTask extends
            AsyncTask<Void, Void, ArrayList<ContactNameItems>> {

        @Override
        protected void onPreExecute() {

            mDialog = ProgressDialog.show(MainActivity.this, "Select Contacts",
                    "Getting Contacts");

            super.onPreExecute();
        }

        @Override
        protected ArrayList<ContactNameItems> doInBackground(Void... params) {

            Uri uri = ContactsContract.Contacts.CONTENT_URI;
            String[] projection = null;
            String selection = null;
            String[] selectionArgs = null;
            String sortOrder = ContactsContract.Contacts.DISPLAY_NAME;
            Cursor cursor = getContentResolver().query(uri, projection,
                    selection, selectionArgs, sortOrder);

            if (cursor != null) {
                for (int i = 0; i < cursor.getCount(); i++) {
                    cursor.moveToNext();
                    String hasName = cursor
                            .getString(cursor
                                    .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                    if (hasName != null && hasName.length() > 0
                            && !hasName.contains("@")) {
                        ContactNameItems listItem = new ContactNameItems();

                        contactId = cursor.getString(cursor
                                .getColumnIndex(ContactsContract.Contacts._ID));

                        contactName = cursor
                                .getString(cursor
                                        .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

                        listItem.set_id(Long.parseLong(contactId));

                        listItem.setName(contactName);

                        final Bitmap my_btmp = BitmapFactory
                                .decodeStream(openPhoto(Long.parseLong(contactId)));
                        listItem.setImage(my_btmp);

                        mContactNameItems.add(listItem);
                    }
                }
            }

            if (cursor != null)
                cursor.close();

            return mContactNameItems;
        }

        @Override
        protected void onPostExecute(ArrayList<ContactNameItems> result) {

            mPassToFragBundle.putSerializable(NAME_ARRAY_KEY, result);

            ContactExpListFragment contactExpListFragment = new ContactExpListFragment();
            contactExpListFragment.setArguments(mPassToFragBundle);

            if (mBundle == null) {
                getFragmentManager().beginTransaction()
                        .add(R.id.container, contactExpListFragment).commit();

            }
            mDialog.dismiss();

            super.onPostExecute(result);
        }
    }

    public InputStream openPhoto(long contact_id) {
        contact_id = Long.parseLong(contactId);
        Uri contactUri = ContentUris.withAppendedId(
                ContactsContract.Contacts.CONTENT_URI, contact_id);
        Uri photoUri = Uri.withAppendedPath(contactUri,
                ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
        Cursor photoCursor = getContentResolver().query(photoUri,
                new String[] { ContactsContract.Contacts.Photo.PHOTO }, null,
                null, null);
        if (photoCursor == null) {
            return null;
        }
        try {
            if (photoCursor.moveToFirst()) {
                byte[] data = photoCursor.getBlob(0);
                if (data != null) {
                    return new ByteArrayInputStream(data);
                }
            }
        } finally {
            photoCursor.close();
        }
        return null;
    }
}

2 个答案:

答案 0 :(得分:0)

试试这个:

public int getChildrenCount(int groupPosition) {
    if (this.mListDataHeader == null) {
        Log.e("Debug", "mListDataHeader is null.");
        return 0;
    } else if (groupPosition < 0 || groupPosition >= this.mListDataHeader.size()) {
        Log.e("Debug", "position invalid: " + groupPosition);
        return 0;
    } else if (this.mListDataHeader.get(groupPosition) == null) {
        Log.e("Debug", "Value of mListDataHeader at position is null: " + groupPosition);
        return 0;
    } else if (this.mListDataChild == null) {
        Log.e("Debug", "mListDataChild is null.");
        return 0;
    } else if (!this.mListDataChild.containsKey(this.mListDataHeader.get(groupPosition)) {
        Log.e("Debug", "No key: " + this.mListDataHeader.get(groupPosition));
        return 0;
    } else if (this.mListDataChild.get(this.mListDataHeader.get(groupPosition)) == null) {
        Log.e("Debug", "Value at key is null: " + this.mListDataHeader.get(groupPosition)));
        return 0;
    } else {
        return this.mListDataChild.get(this.mListDataHeader.get(groupPosition)).size();
    }
}

扩展时检查LogCat。

答案 1 :(得分:0)

解决方案:

listDataHeader是一个对象的arrayList。我的问题是我没有意识到listDataChild.get(key)正在要求一把钥匙,因为我是从原创教程开始工作的。我将listDataHeader.get(groupPosition)更改为listDataHeader.get(groupPosition).getName(),现在一切都很好。