Android ListView working on emulator, but not on device

I am using ListView with a custom ArrayAdapter, and everything is working fine when I run my app in AVD emulator, but when I install it on my phone my app crashes when I touch any ListView item.

Activity xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/login_background"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.frequentbuyer.ui.activity.ShoppingListListActivity" >

<ListView
    android:id="@+id/shoppingListsListView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/addShoppingListButton"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:cacheColorHint="#00000000" >

</ListView>

<Button
    android:id="@+id/addShoppingListButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignEnd="@+id/shoppingListsListView"
    android:layout_alignParentBottom="true"
    android:layout_alignRight="@+id/shoppingListsListView"
    android:text="@string/add_shopping_list" />

</RelativeLayout>

List item 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="match_parent"
    android:background="@drawable/list_item_gradient" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentEnd="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentStart="true"
    android:background="@drawable/border_rectangle_shape"
    android:orientation="horizontal" >

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

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="1" />

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

</RelativeLayout>

Activity class:

package com.frequentbuyer.ui.activity;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;

import roboguice.inject.ContentView;
import roboguice.inject.InjectExtra;
import roboguice.inject.InjectView;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;

import com.frequentbuyer.R;
import com.frequentbuyer.exception.DataAccessException;
import com.frequentbuyer.model.ShoppingList;
import com.frequentbuyer.model.User;
import com.frequentbuyer.service.contract.IShoppingListService;
import com.frequentbuyer.ui.adapters.ShoppingListListViewAdapter;
import com.google.inject.Inject;

@ContentView(R.layout.activity_shoppinglist_list)
public class ShoppingListListActivity extends AbstractBaseActivity {

/* shopping list list activity UI components */

@InjectView(R.id.shoppingListsListView)
private ListView shoppingListsListView;

@InjectView(R.id.addShoppingListButton)
private Button addShoppingListButton;

/* shopping list list activity injected services */
@Inject
private IShoppingListService shoppingListService;

/* shopping list list activity received extras */

// received from login activity
@InjectExtra(ActivityParameterNames.AUTHENTICATED_USER)
User loggedInUser;

private List<ShoppingList> allShoppingLists;

/* activity events */

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initializeShoppingListView();
    // add listeners
    addListeners();
    registerForContextMenu(shoppingListsListView);
}

@Override
public void onBackPressed() {
    showExitDialog();
}

@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
    if (view.getId() == R.id.shoppingListsListView) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        menu.setHeaderTitle(allShoppingLists.get(info.position).getName());
        menu.add(Menu.NONE, 0, 0, R.string.delete_shopping_list);
    }
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    try {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        long shoppingListToDeleteId = info.id;
        shoppingListService.deleteShoppingList(this, shoppingListToDeleteId);
        reloadCurrentActivity();
    } catch (DataAccessException e) {
        showErrorMessageDialog(e.getLocalizedMessage());
    }
    return true;
}

/* activity methods */

private void initializeShoppingListView() {
    try {
        allShoppingLists = shoppingListService.getAllShoppingListsForUser(ShoppingListListActivity.this, loggedInUser.getId());
        // pass context and data to the custom shopping list list adapter
        ShoppingListListViewAdapter shoppingListListViewAdapter = new ShoppingListListViewAdapter(this, allShoppingLists);
        // set shopping list list adapter
        shoppingListsListView.setAdapter(shoppingListListViewAdapter);
    } catch (DataAccessException e) {
        showErrorMessageDialog(e.toString());
    }
}

private void addListeners() {
    shoppingListsListView.setOnItemClickListener(shoppingListListItemOnClickListener);
    addShoppingListButton.setOnClickListener(addShoppingListButtonOnClickListener);
}

/* activity listeners */

private OnItemClickListener shoppingListListItemOnClickListener = new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long shoppingListId) {
        try {
            HashMap<String, Serializable> activityParametersMap = new HashMap<String, Serializable>();
            activityParametersMap.put(ActivityParameterNames.SELECTED_SHOPPING_LIST, shoppingListService.getShoppingListById(ShoppingListListActivity.this, shoppingListId));
            activityParametersMap.put(ActivityParameterNames.AUTHENTICATED_USER, loggedInUser);
            startAnotherActivity(ShoppingListListActivity.this, EditShoppingListActivity.class, activityParametersMap);
        } catch (DataAccessException e) {
            showErrorMessageDialog(e.getLocalizedMessage());
        }

    }
};

View.OnClickListener addShoppingListButtonOnClickListener = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        HashMap<String, Serializable> shoppingListListActivityParametersMap = new HashMap<String, Serializable>();
        shoppingListListActivityParametersMap.put(ActivityParameterNames.AUTHENTICATED_USER, loggedInUser);
        ShoppingListListActivity.startAnotherActivity(ShoppingListListActivity.this, CreateShoppingListActivity.class, shoppingListListActivityParametersMap);
    }
};
}

Custom adapter class:

package com.frequentbuyer.ui.adapters;

import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.frequentbuyer.R;
import com.frequentbuyer.model.ShoppingList;

public class ShoppingListListViewAdapter extends ArrayAdapter<ShoppingList> {

private final Context context;
private final List<ShoppingList> shoppingLists;

public ShoppingListListViewAdapter(Context context, List<ShoppingList> shoppingLists) {
    super(context, R.layout.shoppinglist_list_item, shoppingLists);
    this.context = context;
    this.shoppingLists = shoppingLists;
}

@SuppressLint("ViewHolder")
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    // create inflater
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    // get rowView from inflater
    View rowView = inflater.inflate(R.layout.shoppinglist_list_item, parent, false);

    // get the two text view from the rowView
    TextView shoppingListNameView = (TextView) rowView.findViewById(R.id.shoppingListName);

    // set the text for textView
    shoppingListNameView.setText(shoppingLists.get(position).getName());

    // get the two text view from the rowView
    TextView shoppingListItemNumberView = (TextView) rowView.findViewById(R.id.shoppingListItemsNumber);

    // set the text for textView
    int shoppingListSize = shoppingLists.get(position).getShoppingItems().size();
    shoppingListItemNumberView.setText("(" + shoppingListSize + " item" + (shoppingListSize == 1 ? ")" : "s)"));

    // return rowView
    return rowView;
}

@Override
public long getItemId(int position) {
    return shoppingLists.get(position).getId();
}
}

In some previous version of the app I used ListView in the same way on my phone without any problems, and now it is causing my app to crash. Any idea why this is happening?


Source: xml

Leave a Reply