0

I came across a really frustrating problem. I have a button with an onClick event that should display a dialog pop up with a ExpandableListView inside of it.

This is the code:

public class Home extends Activity {

List<String> groupList;
List<String> childList;
Map<String, List<String>> laptopCollection;
ExpandableListView expListView; 

private Context thisContext = this; 

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

    createGroupList();

    createCollection();


    Intent myDataIntent = this.getIntent();
    // getting the municipality name, the year and the versed money from the prev. intent
    this.municipalityName = myDataIntent.getStringExtra(TAG_COMUNE);
    this.year = myDataIntent.getStringExtra(TAG_ANNO);
    this.versedMoney = myDataIntent.getStringExtra(TAG_VERSED_MONEY);


    Button infoListButton = (Button) findViewById(R.id.infoButton);

    infoListButton.setOnClickListener(new OnClickListener() {

         @Override
          public void onClick(View arg0) {

            // custom dialog
            final Dialog dialog = new Dialog(thisContext);
            dialog.setContentView(R.layout.institutional_info_custom_list);
            dialog.setTitle("Info");

            LayoutInflater li = (LayoutInflater) thisContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View v = li.inflate(R.layout.institutional_info_custom_list, null, false);
            dialog.setContentView(v);

            expListView = (ExpandableListView) findViewById(android.R.id.list);
                 final ExpandableListAdapter expListAdapter = new ExpandableListAdapter(
                        Home.this, groupList, laptopCollection);
            /// THE APP CRASHES HERE
            expListView.setAdapter(expListAdapter);

            // getting the window manager and changing the dialog position
            WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
            params.gravity = Gravity.TOP | Gravity.LEFT;
            params.y = 80;
            dialog.getWindow().setAttributes(params);
            // dialog width and height.
            dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);         

            // set the custom dialog components

            dialog.show();
          }
    });
}


 private void createGroupList() {
        groupList = new ArrayList<String>();
        groupList.add("HP");
        groupList.add("Dell");
        groupList.add("Lenovo");
        groupList.add("Sony");
        groupList.add("HCL");
        groupList.add("Samsung");
    }

    private void createCollection() {
        // preparing laptops collection(child)
        String[] hpModels = { "HP Pavilion G6-2014TX", "ProBook HP 4540",
                "HP Envy 4-1025TX" };
        String[] hclModels = { "HCL S2101", "HCL L2102", "HCL V2002" };
        String[] lenovoModels = { "IdeaPad Z Series", "Essential G Series",
                "ThinkPad X Series", "Ideapad Z Series" };
        String[] sonyModels = { "VAIO E Series", "VAIO Z Series",
                "VAIO S Series", "VAIO YB Series" };
        String[] dellModels = { "Inspiron", "Vostro", "XPS" };
        String[] samsungModels = { "NP Series", "Series 5", "SF Series" };

        laptopCollection = new LinkedHashMap<String, List<String>>();

        for (String laptop : groupList) {
            if (laptop.equals("HP")) {
                loadChild(hpModels);
            } else if (laptop.equals("Dell"))
                loadChild(dellModels);
            else if (laptop.equals("Sony"))
                loadChild(sonyModels);
            else if (laptop.equals("HCL"))
                loadChild(hclModels);
            else if (laptop.equals("Samsung"))
                loadChild(samsungModels);
            else
                loadChild(lenovoModels);

            laptopCollection.put(laptop, childList);
        }
    }

    private void loadChild(String[] laptopModels) {
        childList = new ArrayList<String>();
        for (String model : laptopModels)
            childList.add(model);
    }


}

Here is the ExpandableListAdapter class:

public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Activity context;
private Map<String, List<String>> laptopCollections;
private List<String> laptops;

public ExpandableListAdapter(Activity context, List<String> laptops,
        Map<String, List<String>> laptopCollections) {
    this.context = context;
    this.laptopCollections = laptopCollections;
    this.laptops = laptops;
}

public Object getChild(int groupPosition, int childPosition) {
    return laptopCollections.get(laptops.get(groupPosition)).get(childPosition);
}

public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

public View getChildView(final int groupPosition, final int childPosition,
        boolean isLastChild, View convertView, ViewGroup parent) {
    final String laptop = (String) getChild(groupPosition, childPosition);
    LayoutInflater inflater = context.getLayoutInflater();

    if (convertView == null) {
        convertView = inflater.inflate(R.layout.institutional_rowlist_detail, null);
    }

    TextView item = (TextView) convertView.findViewById(R.id.institutional_detail_name);

    item.setText(laptop);
    return convertView;
}

public int getChildrenCount(int groupPosition) {
    return laptopCollections.get(laptops.get(groupPosition)).size();
}

public Object getGroup(int groupPosition) {
    return laptops.get(groupPosition);
}

public int getGroupCount() {
    return laptops.size();
}

public long getGroupId(int groupPosition) {
    return groupPosition;
}

public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    String laptopName = (String) getGroup(groupPosition);
    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.institutional_rowlist_master,
                null);
    }
    TextView item = (TextView) convertView.findViewById(R.id.institutional_detail_name);
    item.setTypeface(null, Typeface.BOLD);
    item.setText(laptopName);
    return convertView;
}

public boolean hasStableIds() {
    return true;
}

public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}
}

And here are the 4 .xml files I am using (the first is the Home activity XML, called activity_home.xml, which has the button, the second is the one with the ExpandableListView, the third is the one with the group entry Text View, and the last is the detail one):

1) activity_home.xml:

  <?xml version="1.0" encoding="utf-8"?>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/scrollView1"
         android:layout_width="match_parent"
         android:layout_height="wrap_content" >

 <RelativeLayout
    android:id="@+id/RelativeLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingBottom="40dp"
    android:paddingLeft="30dp"
    android:paddingRight="30dp"
    android:paddingTop="20dp" >

<Button
    android:id="@+id/investStatButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/linearLayout1"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="40dp"
    android:text="@string/investStatButton" />

   </RelativeLayout>
    </ScrollView>

2) institutional_info_custom_list.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="fill_parent" >

   <ExpandableListView
       android:id="@android:id/list"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_centerHorizontal="true"
       android:layout_marginBottom="50dp"
       android:layout_marginLeft="50dp"
       android:layout_marginTop="30dp" >

</ExpandableListView>

3) institutional_rowlist_master.xml:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/institutional_master_name"
android:layout_width="wrap_content"
android:layout_height="?android:attr/listPreferredItemHeight"
android:layout_marginLeft="8dp"
android:gravity="left"
android:paddingLeft="32dp"
android:paddingTop="8dp"
android:textSize="14sp"
android:textAlignment="textEnd"
android:textStyle="bold" /> 

4) institutional_rowlist_detail.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="40dp"
android:clickable="true"
android:orientation="vertical"
android:paddingLeft="40dp"
tools:context=".MainActivity" >

<TextView
    android:id="@+id/institutional_detail_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawableLeft="@drawable/ic_launcher"
    android:drawablePadding="5dp"
    android:gravity="center_vertical"
    android:textSize="14sp"
    android:textStyle="bold" >
</TextView>

<TextView
    android:id="@+id/institutional_detail_value"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawableLeft="@drawable/ic_launcher"
    android:drawablePadding="5dp"
    android:gravity="center_vertical"
    android:textSize="14sp"
    android:textStyle="bold" >
</TextView>

</LinearLayout> 

When I click on the button the app crashes and I get a Java Null Pointer exception at the expListView.setAdapter(expListAdapter); line in the Home activity.

Please help me cause it is all day I am surfing the net in search for some clues... I do not know what to do.

Thanks!

EDIT: this is the image

enter image description here

EDIT: thank you codeMagic, I made it: enter image description here

Now I would like to customize the Info Title bar, i.e. add a button with an onclick event to dismiss() the dialog and some text views. Is it possible??? How can I do that?

tonix
  • 6,671
  • 13
  • 75
  • 136
  • Now that I can show the expandablelist, is there a way to show the details in that way? – tonix Mar 16 '14 at 08:36

1 Answers1

2

Right now, it is looking for the ExpandableListView inside of activity_home.xml when it should be looking in the layout that you inflate for your Dialog. Change it to

expListView = (ExpandableListView) v.findViewById(android.R.id.list);

Edit

you are using "@android:id/list" for the id of your ListView. This should be used if your Activity extends ListActivity otherwise you should give it your own id and use that to access it in findViewById(). Either way, you need to be looking in the correct layout file as I have originally noted in my answer.

codeMagic
  • 44,549
  • 13
  • 77
  • 93
  • Is the declaration of this id correct that way? Will @android:id/list even add the id to the ressources? – fweigl Mar 16 '14 at 00:41
  • @Ascorbin it doesn't need to add it to the `resources` because it's an Android `resource` so it is already there – codeMagic Mar 16 '14 at 00:44
  • Don't really get it, he's inflating his own layout from institutional_info_custom_list.xml there, how does his own ListView already have an id within the android resources? – fweigl Mar 16 '14 at 00:46
  • @Ascorbin Ah, you are right, the OP isn't extending `ListActivity`. I guess I was just assuming without paying attention. I will update my answer. Thanks – codeMagic Mar 16 '14 at 00:48
  • @codeMagic Man you did it!!! Thank you Thank you so much I was getting mad of trying ot understand what was going on. Now it works perfectly! I would like to ask only one more thing: at the moment the dialog displays an expandable list with a group and the details displayed when I click on the group textView. Is there a way to display both the Group and the proper details without having to click on the group textView? I edit my question and attach an image so it can be clearer. – tonix Mar 16 '14 at 08:34
  • @user3019105 if you want just headers and don't need it to be expandable, which I think is what you are saying, [see this post](http://stackoverflow.com/questions/13590627/android-listview-headers/13634801#13634801) – codeMagic Mar 16 '14 at 12:23
  • Thank you so much for the post! I made it. I have only the last a last question, in the EDIT I posted my result image. If you see the dialog title has an "Info" title I have set with .setTitle("Info"). Is there a way to add textViews and a Button on which I can bind an event in order to .dismiss() the dialog on the dialog title bar? And anyway, is it possible to customize the dialog bar? I mean, padding, margin, etc??? Thanks! – tonix Mar 16 '14 at 17:16
  • You would probably want to either want to create a class which `extends Dialog` and you could do it all in there. Or it may be easier to just make this a separate `Activity` and give it a `Dialog Theme` in your `manifest.xml` then you can just create the `View`s you need. I do this in some cases to have `Button`s etc... and get the full functionality of an `Activity` while looking like a `Dialog`. – codeMagic Mar 16 '14 at 17:22