私はListViewを持ち、各ListItemにはクリックされたときに2つのボタンを持つオーバーフローメニューを表示するImageButtonがあります。 TrackedRunというオブジェクトから継承したカスタムArrayAdapterを使用しています。私はオーバーフローメニューを介してクリックされたListItemに対応するTrackedRunオブジェクトへの参照を取得したいと思います。ボタンをクリックすると、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を呼び出すとし、私のアダプタのonDeleteClick、currentItemからのidは、常に最後に追加されたListItemのIDであり、クリックされたものではありません。正しいIDを取得するために、クリックされたListItemに対応するTrackedRunオブジェクトを取得するにはどうすればよいですか?
ありがとうございました!あなたが私になぜこれが起こるのか説明することができますか?私の推測では、新しいListItemが追加されるたびにgetViewメソッドが実行され、コードは最後の項目で終了するまで上書きされます。 – TobiasP
@TobiasPあなたは正しいです。リストビューの仕組みを理解する。 getViewメソッド内にログを追加することをお勧めします。再度アプリケーションを実行して、logcatを確認してください。私はあなたの問題がなぜ解決するのか知っていると思います –