所以,我知道Stack上有很多类似的问题;然而,他们都没有设法解决我的问题。
我有一个ListActivity
活动用于显示用户名列表;
我创建了一个UserObj
类来收集有关每个用户的信息,即UserObj
实例(用户名,密码等)。
现在我在ListView
内成功显示了用户名,我还设法显示了包含一些项目的ContextMenu
,Delete
,{{1} },ChangeUsername
)长按特定用户名。
我在下面发布了ChangePassword
代码:
ChangeEmail
然而,显然,我需要做的是实际触发执行所选用户的“删除用户”,“更改电子邮件”等任务;我认为需要相应的列表项的ListActivity
才能知道哪个用户应该经历这些修改。
因此,根据关于此主题的大多数问题(以及相应答案)的建议,我在public class ShowAccountList extends ListActivity {
List<UserObj> Allusers = new ArrayList<>(); // this is required to retrieve users from a local database
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_account_list);
final ListView UserList = (ListView)findViewById(android.R.id.list);
UserList.setLongClickable(true);
/*For completeness: here I fetch users from DB*/
DataBaseUserHelper dbusers = new DataBaseUserHelper(getApplicationContext());
dbusers.CreateTables();
Allusers = dbusers.getAllUsers();
dbusers.closeDB();
/*Let's build a 'username' list to display*/
List<String> namelist = new ArrayList<String>();
for(int i=0 ; i< Allusers.size() ; i++){
String uname = Allusers.get(i).username;
namelist.add(uname);
}
final ArrayAdapter<String> nameadapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,namelist);
UserList.setAdapter(nameadapter);
registerForContextMenu(UserList);
UserList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
openContextMenu(parent);
/*This outputs the CORRECT position*/
System.out.println("Position: " + position + ", id: " + id);
return true;
}
});
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo){
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.user_context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item){
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int selectedId = info.position; // HERE the problem shows up
// switch statement for debugging purposes
switch (item.getItemId()){
case R.id.DeleteUser:
System.out.println("DELETE USER");
return true;
case R.id.ChangeName:
System.out.println("CHANGE USERNAME");
return true;
case R.id.ChangeEmail:
System.out.println("CHANGE EMAIL");
return true;
case R.id.ChangePassword:
System.out.println("CHANGE PASSWORD");
return true;
default:
return super.onContextItemSelected(item);
}
}
}
内将position
转换为item.getMenuInfo()
然后我尝试检索该位置:
AdapterContextMenuInfo
问题是,当我选择一个菜单项(例如,对应于'delete'的菜单项)时,ANR对话框出现并报告以下异常:
onContextItemSelected
我能理解的是 int selectedId = info.position;
始终为空。但为什么?
我的代码中可能出现什么问题?
从上面的代码中可以看出,我试图通过打印测试字符串(例如 java.lang.NullPointerException: Attempt to read from field 'int android.widget.AdapterView$AdapterContextMenuInfo.position' on a null object reference
)来查看单击每个菜单项时发生了什么,实际上如果我删除info.position
没有崩溃发生...
提前致谢
修改
经过一些诊断后,我发现传递给"DELETE USER"
的{{1}}为NULL。所以,我更接近问题的根源。
知道为什么我得到一个NULL int selectedId = info.position;
?
答案 0 :(得分:1)
我遇到了类似的问题。我的解决方案是使用activity.registerForContextMenu(view)
可以在视图中将项目或甚至UserObj的位置设置为标记。
您可以在onCreateContextMenu()
电话中获取该标记,并可以调用相应的操作。
答案 1 :(得分:1)
关于你的问题,我认为在实施@rabhis想法时你错了。 试试我在我的应用中实现的解决方案: (在我的代码中,我使用自定义适配器和recycleview,所以尝试合并到你的代码中)
public class ListHistoryAdapter extends RecyclerView.Adapter<ListHistoryAdapter.HistoryViewHolder> implements View.OnCreateContextMenuListener {
holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // your code } }); holder.itemView.setOnCreateContextMenuListener(this); holder.itemView.setTag(position);
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { MenuItem deleteItem = menu.add(Menu.NONE, 1, 1, "Delete"); final int pos = (int) v.getTag(); deleteItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { // your code return true; } }); }