Here is some code, that I cannot fix myself.

I made a custom ArrayAdapter, to populate my ListView with TextViews containing players' names.

It works as intended when the whole list of player names is specified before the adapter is instantiated. The problem occurs when I click on a list item added after adapter instantiation.


I cant figure out why I get a NullPointerException in:

PlayersArrayAdapter.getItemId(int position)

on this line:

return mIdMap.get(item);

when I click the third player named "Fries" on the list.


Code with explanations:

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

    //arraylist to store players names
    ArrayList<String> playerNames = new ArrayList<String>();

    //players which are on the list from the begining
    //when I click on them, "onPlayerListItemClicked" is properly called
    //and I get clicked player name in my LogCat
    playerNames.add("Pawel");
    playerNames.add("Olga");

    //listview to display players names
    ListView playerListView = (ListView)findViewById(R.id.ms_player_list);

    //custom arrayadapter, which gets ArrayList as one of arguements
    PlayersArrayAdapter playerListAdapter = new PlayersArrayAdapter(this, R.layout.player_list_item, playerNames);  

    playerListView.setAdapter(playerListAdapter);
    playerListView.setOnItemClickListener(onPlayerListItemClicked);


    // THERE IS ROOT OF PROBLEM:
    // player "Fries" is also added to the ListView, and is properly displayed
    // but when I click on it, I get NullPointerException described above
    playerNames.add("Fries");
    playerListAdapter.notifyDataSetChanged();
}

OnItemClickListener onPlayerListItemClicked = new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
        String item = (String)parent.getItemAtPosition(position);
        Logger.i("Clicked at item: " + item);
    }
};

PlayersArrayAdapter class:

class PlayersArrayAdapter extends ArrayAdapter<String>{

    HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();

    public PlayersArrayAdapter(Context context, int textViewResourceId, List<String> objects) {
        super(context, textViewResourceId, objects);

        for (int i = 0; i < objects.size(); i++)
            mIdMap.put(objects.get(i), i);
    }

    @Override
    public long getItemId(int position) {
        String item = getItem(position);
        return mIdMap.get(item); //at this line NullPointerException throws
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

}

Error message from Debug:

Thread [<1> main] (Suspended (exception NullPointerException))  
    <VM does not provide monitor information>   
    PlayersArrayAdapter.getItemId(int) line: 119    
    AbsListView$PerformClick.run() line: 1964   
    ViewRoot(Handler).handleCallback(Message) line: 587 
    ViewRoot(Handler).dispatchMessage(Message) line: 92 
    Looper.loop() line: 130 
    ActivityThread.main(String[]) line: 3687    
    Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
    Method.invoke(Object, Object...) line: 507  
    ZygoteInit$MethodAndArgsCaller.run() line: 867  
    ZygoteInit.main(String[]) line: 625 
    NativeStart.main(String[]) line: not available [native 
有帮助吗?

解决方案

@Override
public long getItemId(int position) {
    return position // this needs to just return a long, position usually is best choice
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top