我有一个ListView,每个Listitem都有一个ImageButton,当点击时会显示一个带有两个按钮的溢出菜单。我使用的是从名为TrackedRun的对象扩展的自定义ArrayAdapter。我想引用与通过溢出菜单单击的ListItem对应的TrackedRun对象。
这是我的适配器(仅包含相关代码):
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对象,以便获得正确的ID?
答案 0 :(得分:2)
当你初始化每个溢出菜单时,你需要像这样传递当前项目
private void setOverflowMenu(final TrackedRun currentItem){
...
}
将private TrackedRun currentItem
从全局变量更改为局部变量
答案 1 :(得分:1)
当膨胀ListView时,<!doctype html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>AngularJS Bootstrap Duallistbox example</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="../bower_components/bootstrap-duallistbox/src/bootstrap-duallistbox.css">
</head>
<body ng-app="bsDuallistboxApp">
<!--[if lt IE 9]>
<script src="../bower_components/es5-shim/es5-shim.js"></script>
<script src="../bower_components/json3/lib/json3.min.js"></script>
<![endif]-->
<div class="container" ng-controller="MainCtrl">
<select
ng-model="model"
ng-options="obj as obj.text for obj in list track by obj.id"
multiple
bs-duallistbox
bootstrap2="{{ settings.bootstrap2 }}"
move-on-select="{{ settings.moveOnSelect }}"
preserve-selection="{{ settings.preserveSelection }}"
move-selected-label="{{ settings.moveSelectedLabel }}"
move-all-label="{{ settings.moveAllLabel }}"
remove-selected-label="{{ settings.removeSelectedLabel }}"
remove-all-label="{{ settings.removeAllLabel }}"
non-selected-list-label="{{ settings.nonSelectedListLabel }}"
selected-list-label="{{ settings.selectedListLabel }}"
postfix="{{ settings.postfix }}"
select-min-height="{{ settings.selectMinHeight }}"
filter="{{ settings.filter }}"
filter-values="{{ settings.filterValues }}"
filter-non-selected="settings.filterNonSelected"
filter-selected="settings.filterSelected"
filter-placeholder="{{ settings.filterPlaceholder }}"
filter-clear="{{ settings.filterClear }}"
info-all="{{ settings.infoAll }}"
info-filtered="{{ settings.infoFiltered }}"
info-empty="{{ settings.infoEmpty }}"
</select>
<div class="row">
<button class="btn btn-large" ng-click="reset()">Reset</button>
<button class="btn btn-large" ng-click="add()">Add</button>
</div>
</div>
<script src="../jquery/jquery.js"></script>
<script src="../angular/angular.js"></script>
<script src="../bootstrap-duallistbox/src/jquery.bootstrap-duallistbox.js"> </script>
<script src="../common/module.js"></script>
<script src="../bootstrap/dist/js/bootstrap.js"></script>
<script src="../src/directives/bsDuallistbox.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/controllers/main.js"></script>
</body>
</html>
方法将被执行getView
次。所以当你的ListView被夸大完成时,currentItem就是最后一个。我的建议是:
getCount()
使用位置更简单,因为您已在Activity中拥有数组。