0

Could I get a NullPointerException because the button I am referencing is nested inside several layouts? Any time I reference browseEditBtn I get an exception. It's a simple button! Come'on.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

 android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<TableLayout 
android:layout_width="wrap_content" 
android:layout_height="wrap_content"
android:orientation="horizontal" 
android:stretchColumns="*">
<!-- <include layout="@layout/mydesctextview" /> -->
<TableRow 
android:id="@+id/tableRow1" 
android:layout_width="wrap_content"
android:layout_height="wrap_content" 
android:orientation="horizontal">

        <TextView 
        android:text="TextView" 
        android:layout_width="wrap_content"
        android:layout_gravity="left|center_vertical" 
        android:id="@+id/txtItem" 
        android:textSize="20dip" 

        ></TextView>



        <ImageButton

        android:src="@drawable/editbtn"
        android:layout_marginRight="10dip" 
        android:layout_gravity="right|center_vertical"
        android:id="@+id/browseEditBtn"
        android:background="@drawable/my_group_statelist"
        ></ImageButton>

</TableRow>
</TableLayout>
</LinearLayout>

Source Code (The Button is called in the main onCreate()):

public class BrowseActivity extends ExpandableListActivity {

final private String[] asColumnsToReturn = {
        Items.ITEMS_TABLE_NAME + "." + Items.ITEMS_ITEM,
        Items.ITEMS_TABLE_NAME + "." + Items.ITEMS_DESC,
        Items.ITEMS_TABLE_NAME + "." + Items.ITEMS_MANU,
        Items.ITEMS_TABLE_NAME + "." + Items.ITEMS_ID };

@SuppressWarnings("unchecked")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.browse);
    DbHelper dbh = new DbHelper(this.getApplicationContext());
    SQLiteDatabase db = dbh.getWritableDatabase();
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    queryBuilder.setTables(Items.ITEMS_TABLE_NAME);

    ExpandableListView browseView = (ExpandableListView)    findViewById(android.R.id.list);
    Button editBrowseBtn = (Button) findViewById(R.id.browseEditBtn);

    Cursor mCursor = queryBuilder.query(db, asColumnsToReturn, null, null,
            null, null, Items.DEFAULT_SORT_ORDER);
    startManagingCursor(mCursor);

    SimpleExpandableListAdapter mAdapter = new SimpleExpandableListAdapter(
            this, createGroup(), R.layout.row, R.layout.row, new String[] {
                    Items.ITEMS_ITEM, Items.ITEMS_DESC }, new int[] {
                    R.id.txtItem, R.id.dscItem }, createChildren(),
            R.layout.exprow, new String[] { Items.ITEMS_DESC,
                    Items.ITEMS_MANU }, new int[] { R.id.dscItem,
                    R.id.manuItem });
    browseView.setAdapter(mAdapter);

    editBrowseBtn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent = new Intent(BrowseActivity.this,
                    EditItemActivity.class);
            startActivity(intent);

        }
    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    menu.add("Add Item").setIntent(new Intent(this, AddItemActivity.class));

    return super.onCreateOptionsMenu(menu);
}

@SuppressWarnings("rawtypes")
public List createGroup() {
    DbHelper dbh = new DbHelper(this.getApplicationContext());
    SQLiteDatabase db = dbh.getWritableDatabase();
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    queryBuilder.setTables(Items.ITEMS_TABLE_NAME);

    Cursor mCursor = queryBuilder.query(db, new String[] {
            Items.ITEMS_ITEM, Items.ITEMS_DESC }, null, null, null, null,
            Items.DEFAULT_SORT_ORDER);
    startManagingCursor(mCursor);

    ArrayList<HashMap<String, String>> groupList = new ArrayList<HashMap<String,   String>>();
    mCursor.moveToFirst();
    while (!(mCursor.isAfterLast())) {

        HashMap<String, String> groupMap = new HashMap<String, String>();
        groupMap.put(Items.ITEMS_ITEM,
                mCursor.getString(mCursor.getColumnIndex(Items.ITEMS_ITEM)));
        groupMap.put(Items.ITEMS_DESC,
                      mCursor.getString(mCursor.getColumnIndex(Items.ITEMS_DESC)));

        groupList.add(groupMap);
        mCursor.moveToNext();
    }

    return (List) groupList;
}

@SuppressWarnings("rawtypes")
public List createChildren() {
    DbHelper dbh = new DbHelper(this.getApplicationContext());
    SQLiteDatabase db = dbh.getWritableDatabase();
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    queryBuilder.setTables(Items.ITEMS_TABLE_NAME);

    Cursor mCursor = queryBuilder.query(db, new String[] {
            Items.ITEMS_ITEM, Items.ITEMS_DESC, Items.ITEMS_MANU }, null,
            null, null, null, Items.DEFAULT_SORT_ORDER);
    startManagingCursor(mCursor);
    mCursor.moveToFirst();

    ArrayList<ArrayList<HashMap<String, String>>> childList = new ArrayList<ArrayList<HashMap<String, String>>>();

    while (!(mCursor.isAfterLast())) {

        ArrayList<HashMap<String, String>> childListDesc = new                      ArrayList<HashMap<String, String>>();

        for (int i = 0; i < 1; i++) {
            HashMap<String, String> childMap = new HashMap<String, String>();
            childMap.put(Items.ITEMS_DESC, mCursor.getString(mCursor
                    .getColumnIndex(Items.ITEMS_DESC)));
            childMap.put(Items.ITEMS_MANU, mCursor.getString(mCursor
                    .getColumnIndex(Items.ITEMS_MANU)));

            childListDesc.add(childMap);

        }

        childList.add(childListDesc);
        mCursor.moveToNext();
    }

    return (List) childList;
}
}

And finally the logcat, I think...

06-30 13:01:29.390: ERROR/AndroidRuntime(9189): FATAL EXCEPTION: main 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.simplyDesign.mdk/com.simplyDesign.mdk.BrowseActivity}: java.lang.NullPointerException 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at android.app.ActivityThread.access$2300(ActivityThread.java:125) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at android.os.Handler.dispatchMessage(Handler.java:99) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at android.os.Looper.loop(Looper.java:123) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at android.app.ActivityThread.main(ActivityThread.java:4627) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at java.lang.reflect.Method.invokeNative(Native Method) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at java.lang.reflect.Method.invoke(Method.java:521) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at dalvik.system.NativeStart.main(Native Method) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): Caused by: java.lang.NullPointerException 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at com.simplyDesign.mdk.BrowseActivity.onCreate(BrowseActivity.java:62) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 06-30 13:01:29.390: ERROR/AndroidRuntime(9189): ... 11 more

edit_01

public void doAction(View v) {

    startActivity(new Intent(getApplicationContext(),
            EditItemActivity.class));

}

I have used other buttons in the past to point to EditItemActivity and they have worked fine.

atomSmasher
  • 1,465
  • 2
  • 15
  • 37
  • Show us the code where you reference it and have a problem. Also, try going to Project -> Clean first if you're developing in Eclipse. – Glendon Trullinger Jun 30 '11 at 16:50
  • add the stack of the exception that you have on the logcat, and add the part of code in your activity which is the source of the problem – Houcine Jun 30 '11 at 16:50
  • Can you post the code you're trying to retrieve the button with? Can't really help much without it. – AC2MO Jun 30 '11 at 16:51
  • Sure, coming right up. I have tried cleaning. Doesn't do anything. – atomSmasher Jun 30 '11 at 16:53

5 Answers5

1

What is the name of the layout XML file that you posted? It doesn't appear to be browse.xml because that one has your ExpandableListView in it. The IDs that you reference in your Java code must appear in the content View that you set; otherwise, you must inflate the View yourself.

Edit

You would add something like

android:onClick="doAction"

to the XML of that ImageButton.

Then you would have a doAction(View v) method in your Activity that would do your onClick actions.

Glendon Trullinger
  • 4,052
  • 1
  • 28
  • 35
  • You should set the `android:onClick` of that button in your row XML to some method in your class that does your onClick action. You can't reference the `View` like that. – Glendon Trullinger Jun 30 '11 at 17:16
  • I edited my answer to include an example of what I mean. If you want every `ImageButton` to start the same `Intent`, that will work fine. Otherwise, you'll need to create a custom adapter. – Glendon Trullinger Jun 30 '11 at 17:19
  • The example here http://stackoverflow.com/questions/5188196/how-to-write-custom-expandablelistadapter should get you started with an adapter for an ExpandableList. – Glendon Trullinger Jun 30 '11 at 17:43
  • This seems to work well. It gets rid of the first exception. Now the activity will load! But wait.... don't change the channel there's more! Now if I click on the button I get another nullpointerexception! See edit_01 in question above. – atomSmasher Jun 30 '11 at 17:54
  • What is it saying is null? From what I understand, if you used the XML onClick attribute, it passes the View that was clicked as a parameter, so you would need to have your doAction accept a `View`. – Glendon Trullinger Jun 30 '11 at 18:01
  • Sorry that is a typo, (View v) is inside the parenthesis. Throws NPE. – atomSmasher Jun 30 '11 at 18:03
  • Could you post the stacktrace associated with the NPE and indicate which line throws it? – Glendon Trullinger Jun 30 '11 at 18:04
  • Nevermind.. I looked at the stacktrace (still getting use to it) and found the problem. IThe NPE was on the next activity. The last version of the application, which I torched, pushed a bundle through, obviously it couldn't find it! Thanks for all your help. – atomSmasher Jun 30 '11 at 18:12
1

It seems like the layout you provided is for R.layout.row. If so, then that makes a lot of sense that you can't find the button. The button is dynamically created for each row. You probably want to create a custom adapter and then in the getView, set the click handler.

kabuko
  • 36,028
  • 10
  • 80
  • 93
0

Try this code,

 <ImageButton
    android:layout_height="wrap_content"
    android:layout_width="wrap_content" 
    android:src="@drawable/editbtn"
    android:layout_marginRight="10dip" 
    android:layout_gravity="right|center_vertical"
    android:id="@+id/browseEditBtn"
    android:background="@drawable/my_group_statelist"
    ></ImageButton>

You cannot skip layout_height and layout_width

dcanh121
  • 4,665
  • 11
  • 37
  • 84
  • 1
    The `ImageButton` is in a `TableRow`. Therefore, yes, you can skip layout_height and layout_width. – Glendon Trullinger Jun 30 '11 at 17:00
  • I think no matter what, if you use a View in xml layout file, you need to atleast specify these two parameters. Its not the case if you create a view in java code. – dcanh121 Jun 30 '11 at 17:04
  • "The children of a TableRow do not need to specify the layout_width and layout_height attributes in the XML file. TableRow always enforces those values to be respectively MATCH_PARENT and WRAP_CONTENT." from the Android Developer's website. – Glendon Trullinger Jun 30 '11 at 17:05
0

using tables i have had problems receiving inner elements. Try getting the table as a whole findViewById(R.id.the_table) and the use myTableView.findViewById(R.id.a_row_in_the_table) and get the row then use myTableRow.findViewById(R.id.my_element_in_this_row)

O'Mutt
  • 1,557
  • 1
  • 13
  • 27
0
Button editBrowseBtn = (Button) findViewById(R.id.browseEditBtn);

You're casting the ImageButton to a Button. An ImageButton is not a Button:

Object -> View -> TextView -> Button

Object -> View -> ImageView -> ImageButton

So try this:

ImageButton editBrowseBtn = (ImageButton) findViewById(R.id.browseEditBtn);
nhaarman
  • 98,571
  • 55
  • 246
  • 278
  • I originally had it has ImageButton but changed it to Button thinking maybe that was the problem. I will change it back. – atomSmasher Jun 30 '11 at 17:14