TobiasP
TobiasP

Reputation: 183

Android get position of List Item when button clicked

I have a ListView, and each Listitem has an ImageButton which displays an overflow menu with two buttons when clicked. I'm using a custom ArrayAdapter that extends from an object called TrackedRun. I'd like to get reference to the TrackedRun object that corresponds to the ListItem that was clicked via the overflow menu.

This is my adapter (included just relevant code) :

public class HistoryListItemAdapter extends ArrayAdapter<TrackedRun> {

public interface OnOverflowButtonListener {
    void onDeleteClick(int id);
    void onEditClick(int id);
}


private Context context;
private TrackedRun currentItem;
private View rootView;
private OnOverflowButtonListener listener;
private int position;

public HistoryListItemAdapter(Context context, ArrayList<TrackedRun> items,
                              HistoryFragment historyFragment, OnOverflowButtonListener listener){
    super(context, 0, items);
    this.context = context;
    this.listener = listener;
}

@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    rootView = convertView;
    currentItem = getItem(position);
    this.position = position;

    if (null == rootView) {
        rootView = inflater.inflate(
                R.layout.history_list_item,
                parent,
                false);
    }
    setOverflowMenu();

    return rootView;
}

private void setOverflowMenu(){
    final ImageButton button = (ImageButton) rootView.findViewById(R.id.overflow_icon);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {

            final PopupMenu menu = new PopupMenu(getContext(), button);
            menu.getMenuInflater().inflate(R.menu.list_item_overflow, menu.getMenu());
            menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {

                    switch (item.getItemId()){

                        case R.id.edit_button :
                            listener.onEditClick(currentItem.getId());
                            break;

                        case R.id.delete_button :
                            listener.onDeleteClick(currentItem.getId());
                            break;
                    }
                    return true;
                }
            });
            menu.show();
        }
    });
}

}

And this is the Fragment where I initialize the ListView (relevant code) :

public class HistoryFragment extends Fragment {

private View rootView;
private HistoryListItemAdapter adapter;
private ListView listView;

public HistoryFragment(){
    //Required empty constructor.
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    rootView = inflater.inflate(R.layout.fragment_history, container, false);
    initListView();

    return rootView;
}

private void initListView(){
    listView = (ListView) rootView.findViewById(R.id.history_listview);
    ArrayList<TrackedRun> trackedRuns = new DatabaseHandler(getContext()).getAllTrackedRuns();
    adapter = new HistoryListItemAdapter(getContext(), trackedRuns, this, new HistoryListItemAdapter.OnOverflowButtonListener() {
        @Override
        public void onDeleteClick(int id) {
            System.out.println(id);
        }

        @Override
        public void onEditClick(int id) {
            System.out.println(id);
        }
    });
    listView.setAdapter(adapter);
    listView.setEmptyView(rootView.findViewById(R.id.empty_view));

}

private void loadRecords() {
   //Gets records from database, and reloads ListView with new records.
}

}

When I call the onEditClick and onDeleteClick in my adapter, the id from the currentItem always is the id from the last added ListItem, and not the clicked one. How can I get the TrackedRun object that corresponds to the ListItem that was clicked, so as to get the correct id?

Upvotes: 0

Views: 241

Answers (2)

xiaoyuan
xiaoyuan

Reputation: 423

When inflating ListView , getViewmethod will be excuted getCount() times.So when your ListView is inflated finished, the currentItem is the last.here is my suggestion:

private void setOverflowMenu(final int position){
   ...
}

Use position is more simple cause you already have your array in Activity.

Upvotes: 1

Linh
Linh

Reputation: 60913

When you init each overflow menu, you need pass the current item like this

private void setOverflowMenu(final TrackedRun currentItem){
...
}

And change private TrackedRun currentItem from a global variable to a local variable

Upvotes: 2

Related Questions