2017-02-21 10 views
0

У меня есть ListView, и у каждого Listitem есть ImageButton, который отображает меню переполнения с двумя кнопками при нажатии. Я использую настраиваемый ArrayAdapter, который простирается от объекта TrackedRun. Я хотел бы получить ссылку на объект TrackedRun, который соответствует элементу ListItem, который был нажат через меню переполнения.Android получает позицию элемента списка при нажатии кнопки

Это мой адаптер (входит в комплект только соответствующий код):

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(); 
     } 
    }); 
} 

} 

И это фрагмент, где я инициализировать ListView (соответствующий код):

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. 
} 

} 

Когда я называю onEditClick и onDeleteНажмите в моем адаптере, идентификатор из currentItem всегда является идентификатором из последнего добавленного ListItem, а не щелчком. Как я могу получить объект TrackedRun, который соответствует элементу ListItem, который был нажат, чтобы получить правильный идентификатор?

ответ

2

При инициализации каждого меню переполнения, необходимо передать текущий элемент, как этот

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

И изменить private TrackedRun currentItem от глобальной переменной локальной переменной

+0

Спасибо! Любой шанс, который вы могли бы объяснить мне, почему это происходит? Я предполагаю, что метод getView запускается каждый раз, когда добавляется новый ListItem, и код перезаписывается до тех пор, пока он не закончится на последнем элементе. – TobiasP

+1

@TobiasP вы правы. для понимания работы списка. Я предлагаю вам добавить журнал внутри метода getView. затем снова запустите приложение и проверьте логарифм. Я думаю, вы узнаете, почему ваша проблема решает –

1

При накачивании ListView, getView метод будет excuted getCount() раз. Так что, когда ваш ListView завышен, завершен, currentItem является последним. Вот мое предложение:

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

Использование позиции более просто потому, что у вас уже есть массив в Activity.

Смежные вопросы