Frage

I'm trying to make a custom ExpandableListView, but it always gives a NullPointException. I've tried debugging it and it always crashes at myExpandableList.setAdapter(listAdapter)

I've searched for other solutions, sending the context in "ManagerListActivity.this" form and "this" form didn't help.

Code samples:

public class ManagerListActivity extends SherlockActivity {

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

    // Get the ExpandableListView
    ExpandableListView managerList = (ExpandableListView) findViewById(R.id.list_manager);
    ManagerListAdapter listAdapter = new ManagerListAdapter(ManagerListActivity.this);

    ArrayList<Subordinate> managers = new ArrayList<Subordinate>();
    ArrayList<Employee> employees = new ArrayList<Employee>();

    ArrayList<String> listDataHeader = new ArrayList<String>();
    HashMap<String, List<String>> listDataChild = new HashMap<String, List<String>>();

// I'm skipping the part where I create the managers and employees

        for (int i = 0; i < managers.size(); i++) {
            // Name the headers
            listDataHeader.add(managers.get(i).getFirstName());
            List<String> childList = new ArrayList<String>();

            for (int j = 0; j < managers.get(i).getProjects().size(); j++) {
                // Name the children
                childList.add(managers.get(i).getProjects().get(j)
                        .getProjectName());
            }

            listDataChild.put(listDataHeader.get(i), childList);
        }

    listAdapter = new ManagerListAdapter(this, managers, listDataChild,
            employees);
    managerList.setAdapter(listAdapter);
}

Now the adapter:

public class ManagerListAdapter extends BaseExpandableListAdapter {

private Context context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
private ArrayList<Subordinate> managers;
private ArrayList<Employee> employees;
String phone = "";

public ManagerListAdapter(Context context, ArrayList<Subordinate> managers,
        HashMap<String, List<String>> listDataChild,
        ArrayList<Employee> employees) {
    this.context = context;
    for (int i = 0; i < managers.size(); i++) {
        _listDataHeader.add(managers.get(i).getFirstName());
    }
    this._listDataChild = listDataChild;
    this.employees = employees;
}

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

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

    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this.context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.list_manager_child,
                null);
    }

    TextView txtListChild = (TextView) convertView
            .findViewById(R.id.manager_child);

    txtListChild.setText(childText);
    return convertView;
}


@Override
public View getGroupView(int pos, boolean isExpanded, View view,
        ViewGroup parent) {
    if (view == null) {
        LayoutInflater infalInflater = (LayoutInflater) this.context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = infalInflater.inflate(R.layout.list_manager_item, null);
    }

    TextView lblListHeader = (TextView) view
            .findViewById(R.id.manager_firstname);
    lblListHeader.setTypeface(null, Typeface.BOLD);
    lblListHeader.setText(managers.get(pos).getFirstName());

    // Use the holder to pass data to the call button
    RowViewHolder holder = new RowViewHolder();
    holder.callImg = (ImageView) view.findViewById(R.id.gl_call);
    holder.callImg.setOnClickListener(callListener);
    view.setTag(holder);

    phone = employees.get(pos).getContact();

    return view;
}

// Call button handling
private OnClickListener callListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
        try {
            Intent i = new Intent(Intent.ACTION_CALL);
            i.setData(Uri.parse("tel:" + phone));
            context.startActivity(i);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};

protected static class RowViewHolder {
    public ImageView callImg;
}

Of course, I've also implemented every other required method that BaseExpandableListAdapter needs.

Any help would be appreciated.

UPDATE:

Logcat extract:

11-06 16:13:46.283: E/AndroidRuntime(924): FATAL EXCEPTION: main 11-06 16:13:46.283: E/AndroidRuntime(924): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tcs.mobility.uy.rmg/com.tcs.mobility.uy.rmg.ManagerListActivity}: java.lang.NullPointerException 11-06 16:13:46.283: E/AndroidRuntime(924): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180) 11-06 16:13:46.283: E/AndroidRuntime(924): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 11-06 16:13:46.283: E/AndroidRuntime(924): at android.app.ActivityThread.access$600(ActivityThread.java:141) 11-06 16:13:46.283: E/AndroidRuntime(924): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 11-06 16:13:46.283: E/AndroidRuntime(924): at android.os.Handler.dispatchMessage(Handler.java:99) 11-06 16:13:46.283: E/AndroidRuntime(924): at android.os.Looper.loop(Looper.java:137) 11-06 16:13:46.283: E/AndroidRuntime(924): at android.app.ActivityThread.main(ActivityThread.java:5039) 11-06 16:13:46.283: E/AndroidRuntime(924): at java.lang.reflect.Method.invokeNative(Native Method) 11-06 16:13:46.283: E/AndroidRuntime(924): at java.lang.reflect.Method.invoke(Method.java:511) 11-06 16:13:46.283: E/AndroidRuntime(924): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 11-06 16:13:46.283: E/AndroidRuntime(924): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 11-06 16:13:46.283: E/AndroidRuntime(924): at dalvik.system.NativeStart.main(Native Method) 11-06 16:13:46.283: E/AndroidRuntime(924): Caused by: java.lang.NullPointerException 11-06 16:13:46.283: E/AndroidRuntime(924): at com.tcs.mobility.uy.rmg.ManagerListAdapter.(ManagerListAdapter.java:63) 11-06 16:13:46.283: E/AndroidRuntime(924): at com.tcs.mobility.uy.rmg.ManagerListActivity.onCreate(ManagerListActivity.java:146) 11-06 16:13:46.283: E/AndroidRuntime(924): at android.app.Activity.performCreate(Activity.java:5104) 11-06 16:13:46.283: E/AndroidRuntime(924): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 11-06 16:13:46.283: E/AndroidRuntime(924): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) 11-06 16:13:46.283: E/AndroidRuntime(924): ... 11 more

War es hilfreich?

Lösung

I would guess the phone should be included in View's tag (in RowViewHolder to be precise)? It is safer to assume onClickListener depends on data from View only. In your code phone value depends on whichever groupView was refreshed last

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top