简体   繁体   中英

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?

I used USB debugging, and found NullPointerException in logcat. It was thrown in getItemId method of my custom adapter, because my entities had null value for id field in database, for some reason. I defined id fields by using ORMLite with:

@DatabaseField(generatedId = true) private Long id;

I changed type of id fields from Long to int and reinstalled app on phone and it worked, id fields were populated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM