Andrea
Andrea

Reputation: 369

setOnClickListener returns right position but wrong item

I lost a whole day trying to figure out how to make this work. I successfully set a custom adapter and my ListView. The problem is that I get the right position of the item I click, but the item is always the last one in the list.
What's more is that I'm calling all of this inside another thread to execute a PostCall.

I tried following other examples, also of course following from the official developer resources, but I can't get a clue of what I am doing wrong.

protected void onPostExecute(String result) {
        try {
            ListView serviceList = (ListView)findViewById(android.R.id.list);

            String[] menu = result.split("_");
            ListaMenuActivity adapter = new ListaMenuActivity(ListaCibo.this, menu);
            serviceList.setAdapter(adapter);
            serviceList.setOnItemClickListener(new AdapterView.OnItemClickListener()
            {
                @Override
                public void onItemClick(AdapterView<?> parent, View view,int position, long id)
                {

                    Toast.makeText(ListaCibo.this, String.valueOf(position) + parent.getAdapter().getItem(position), Toast.LENGTH_SHORT).show();
             }
        }catch (Exception e){
            e.printStackTrace();
            Toast.makeText(getApplicationContext(), R.string.error_string, Toast.LENGTH_LONG).show();

        }

    }

I also tried using parent.getItemAtPosition(), also using the View, always same result.

EDIT Here it is the code of my Adapter public ListaMenuActivity(Activity context, String[] itemname) { super(context, R.layout.menu_custom, itemname);

    this.context=context;
    this.itemname=itemname;
}

public View getView(int position, View view, ViewGroup parent) {

    LayoutInflater inflater=context.getLayoutInflater();
    View rowView=inflater.inflate(R.layout.menu_custom, null,true);


    TextView txtTitle = (TextView) rowView.findViewById(R.id.item);
    TextView extratxt = (TextView) rowView.findViewById(R.id.ingredienti);
    ImageView image = (ImageView) rowView.findViewById(R.id.vegan);
    try{
        if(itemname[position]!="Medium Text") {
            Log.e("basd", itemname[position]);
            String [] elems = itemname[position].split(", ");
            txtTitle.setText(elems[0] + ", " + elems[2]);
            extratxt.setText(elems[1].replace("-", ", "));

            if(!elems[3].equals("1")) {
                Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.leaf);
                vegan.setImageBitmap(icon);
            }
            desc_piatto = elems[4];
            nome_foto = elems[5];
            nomepiatto = elems[0];
        }
    } catch (Exception e){e.printStackTrace();}
    return rowView;

}
@Override
public String getItem(int position) {
    return nomepiatto + "," +nome_foto + "," + desc_piatto;
}

Upvotes: 0

Views: 91

Answers (3)

Romadro
Romadro

Reputation: 626

Bad idea to set something inside getView and after that get it inside getItem().

That how your code works (example)

  1. You see on the screen 4th and 5th items of the list
  2. Adapter's getView called for position = 4
  3. You set adapter global varibales desc_piatto, nome_foto, nomepiatto and to data of item number 4
  4. Immediately getView called for item with position 5
  5. You set global varibales to data of item 5
  6. You call getItem from onItemClick, it returns last values of Adapter's global variables.

This is wrong use of Adapter's getItem. Read something about how ListView inflate views and about Adapter lifecycle

P.S. Use lowerCamelCase for variable naming and use ViewHolder for adapter

EDIT: MUCH better, but not the best solution

class YourAwesomeObject {

    String[] elems = null;

    public YourAwesomeObject(String inputString) {
        elems = inputString.split(", ");
    }

    public String getTitle() {
        return elems[0] + ", " + elems[2];
    }

    public String getExtraTxt() {
        return elems[1].replace("-", ", ");
    }

    public boolean isShowImage() {
        return !elems[3].equals("1");
    }

    public String getDescPiatto() {
        return elems[4];
    }

    public String getNomeFoto() {
        return elems[5];
    }

    public String getNomePiatto() {
        return elems[0];
    }

    @Override
    public String toString() {
        return getNomePiatto() + "," +getNomeFoto() + "," + getDescPiatto();
    }
}

public View getView(int position, View view, ViewGroup parent) {

    LayoutInflater inflater = context.getLayoutInflater();
    View rowView = inflater.inflate(R.layout.menu_custom, null, true);


    TextView txtTitle = (TextView) rowView.findViewById(R.id.item);
    TextView extratxt = (TextView) rowView.findViewById(R.id.ingredienti);
    ImageView image = (ImageView) rowView.findViewById(R.id.vegan);
    try {
        if (itemname[position] != "Medium Text") {
            Log.e("basd", itemname[position]);
            YourAwesomeObject item = getItem(itemname[position])
            txtTitle.setText(item.getTitle());
            extratxt.setText(item.getExtraTxt());

            if (item.isShowImage()) {
                Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
                        R.drawable.leaf);
                vegan.setImageBitmap(icon);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return rowView;
}

@Override
public YourAwesomeObject getItem(int position) {
    return new YourAwesomeObject(itemname[position]);
}

Upvotes: 1

Sumit Jha
Sumit Jha

Reputation: 2195

You should re-write your getItem as :

@Override
public String getItem(int position) {
    String [] elems = itemname[position].split(", ");
    return elems[0] + "," +elems[5] + "," + elems[4];
}

Upvotes: 0

Kuls
Kuls

Reputation: 2067

If your list have complete and proper data and if you are getting right position then you can directly fetch the value from the list with the use of position you get. Try below snippet

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {               
        String data = menu[position];
        Toast.makeText(ListaCibo.this, String.valueOf(position) + data, Toast.LENGTH_SHORT).show();
 }

Upvotes: 0

Related Questions