TeeJ TeeJ - 1 month ago 6
Android Question

How to handle NULL results from JSON when I click on list view row?

Very little experience when it comes to Java. My app pulls data from an API to a list view just fine. Once clicked on the list view I want to display more details. My code is in different files and I can't figure out how handle null results when I set my text view text. Right now it is giving me a few errors. Thank you in advanced. I've tried debugging and my own research to no avail for over a day.

My error was: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference.

MainActivity.java:

public void showMemberDetailsScreen(int _id) {
mMembersListScreen.setVisibility(View.GONE);
mMemberDetailsScreen.setVisibility(View.VISIBLE);

if (NetworkUtils.isConnected(this)) {
GetDetailsTask task = new GetDetailsTask(this);
task.execute(_id);
} else {
Log.i(TAG, "onCreate: NOT CONNECTED");
}
}

/**
* Populate the member details screen with data.
*
* @param _name
* @param _birthday
* @param _gender
* @param _twitterId
* @param _numCommittees
* @param _numRoles
*/
public void populateMemberDetailsScreen(String _name, String _birthday, String _gender,
String _twitterId, String _numCommittees, String _numRoles) {

TextView tv = (TextView)mMembersListScreen.findViewById(R.id.text_name);
tv.setText(_name);

tv = (TextView)mMembersListScreen.findViewById(R.id.text_birthday);
tv.setText(_birthday);

tv = (TextView)mMembersListScreen.findViewById(R.id.text_gender);
tv.setText(_gender);

tv = (TextView)mMembersListScreen.findViewById(R.id.text_twitter_id);
tv.setText(_twitterId);

tv = (TextView)mMembersListScreen.findViewById(R.id.text_num_committees);
tv.setText(_numCommittees);

tv = (TextView)mMembersListScreen.findViewById(R.id.text_num_roles);
tv.setText(_numRoles);
}

OnItemClickListener mItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> _parent, View _view, int _position, long _id) {
// TODO: Show the members detail screen
Log.i(TAG, "onItemClick: RAN");


showMemberDetailsScreen(_position);
Log.i(TAG, "onItemClick: POSITION = " + _position);

}
};


GetDetailsTask.java:

private static final String NAME = "name";
private static final String BIRTHDAY = "birthday";
private static final String GENDER = "gender";
private static final String TWITTER_ID = "twitter_id";
private static final String NUM_COMMITTEES = "num_committees";
private static final String NUM_ROLES = "num_roles";

private MainActivity mActivity;

public GetDetailsTask(MainActivity _activity) {
mActivity = _activity;
}

@Override
protected HashMap<String, String> doInBackground(Integer... _params) {

// Add member ID to the end of the URL
String data = NetworkUtils.getNetworkData(API_URL + _params[0]);
HashMap<String, String> retValues = new HashMap<String, String>();

try {
JSONObject response = new JSONObject(data);

String name = response.optString("name");
retValues.put(NAME, name);

String birthday = response.optString("birthday");
retValues.put(BIRTHDAY, birthday);

String gender = response.optString("gender_label");
retValues.put(GENDER, gender);

String twitterId = response.optString("twitterid");
retValues.put(TWITTER_ID, twitterId);

if (response.has("committeeassignments")) {
JSONArray committeeArray = response.optJSONArray("committeeassignments");
int numCommittees = committeeArray.length();
retValues.put(NUM_COMMITTEES, "" + numCommittees);
Log.i(TAG, "doInBackground: NUM COMMITTESS = " + numCommittees);
} else {
retValues.put(NUM_COMMITTEES, "" + 0);
}

if (response.has("roles")){
JSONArray rolesArray = response.optJSONArray("roles");
int numRoles = rolesArray.length();
retValues.put(NUM_ROLES, "" + numRoles);
} else {
retValues.put(NUM_ROLES, "" + 0);
}

} catch(JSONException e) {
e.printStackTrace();
}
return retValues;
}

@Override
protected void onPostExecute(HashMap<String, String> _result) {
super.onPostExecute(_result);
if (_result != null) {
String name = _result.get(NAME);
String birthday = _result.get(BIRTHDAY);
String gender = _result.get(GENDER);
String twitterId = _result.get(TWITTER_ID);
String numCommittees = _result.get(NUM_COMMITTEES);
String numRoles = _result.get(NUM_ROLES);

mActivity.populateMemberDetailsScreen(name, birthday, gender, twitterId, numCommittees, numRoles);
}
}


activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:id="@+id/members_list_screen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:visibility="gone" >

<ListView
android:id="@+id/members_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>

<LinearLayout
android:id="@+id/member_details_screen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:visibility="gone" >

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/name" />

<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>

<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/birthday" />

<TextView android:id="@+id/text_birthday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />

</LinearLayout>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/gender" />

<TextView
android:id="@+id/text_gender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>

<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/twitter_id" />

<TextView android:id="@+id/text_twitter_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/num_committees" />

<TextView
android:id="@+id/text_num_committees"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/name" />

<TextView
android:id="@+id/text_num_roles"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>



Answer

You are trying to show your details screen but in your method you are finding view by id under your mMembersListScreen when you should use mMemberDetailsScreen. Try this:

public void populateMemberDetailsScreen(String _name, String _birthday, String _gender, 
    String _twitterId, String _numCommittees, String _numRoles) {

    TextView tv = (TextView) mMemberDetailsScreen.findViewById(R.id.text_name);
    tv.setText(_name);

    tv = (TextView) mMemberDetailsScreen.findViewById(R.id.text_birthday);
    tv.setText(_birthday);

    tv = (TextView) mMemberDetailsScreen.findViewById(R.id.text_gender);
    tv.setText(_gender);

    tv = (TextView) mMemberDetailsScreen.findViewById(R.id.text_twitter_id);
    tv.setText(_twitterId);

    tv = (TextView) mMemberDetailsScreen.findViewById(R.id.text_num_committees);
    tv.setText(_numCommittees);

    tv = (TextView) mMemberDetailsScreen.findViewById(R.id.text_num_roles);
    tv.setText(_numRoles);
}