因此,我知道Stack上有很多类似的问题;然而,他们中没有人设法解决我的问题。Android:在ListView中获取位置长按
我有一个ListActivity
活动显示用户名列表; 我创建了一个UserObj
类来收集有关每个用户的信息,即UserObj
实例(用户名,密码等)。
现在我成功地显示了用户名我ListView
内,我也成功地显示一个浮动ContextMenu
的部分项目(Delete
,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
内onContextItemSelected
,然后我试图检索与位置:
int selectedId = info.position;
的问题是当我选择一个菜单项(例如,对应于“删除”之一)的ANR对话框显示了与下面的异常报道:
java.lang.NullPointerException: Attempt to read from field 'int android.widget.AdapterView$AdapterContextMenuInfo.position' on a null object reference
什么我可以理解的是,info.position
总是空。但为什么? 我的代码中有什么问题?
正如你可以从上面的代码中看到的,我想看看通过打印测试线单击每个单独的菜单项时发生了什么(例如,"DELETE USER"
),实际上如果我删除int selectedId = info.position;
没有发生崩溃......
在此先感谢
编辑
一些诊断后,我想通了,传递到onCreateContextMenu
的menuInfo
为NULL。所以,我更接近问题的根源。 任何想法为什么我得到一个NULL menuInfo
?
好吧,我已经试图以这种方式注册视图,但它没有工作......无论如何非常感谢你的'setTag()'建议:)我会尝试它希望绕过前面的问题 – NotANumber
我会喜欢也问这个......有没有办法在'onContextItemSelected'而不是'onCreateContextMenu'中执行所需的动作?因为我需要的是将我的注意力限制在一个用户身上,然后为该用户选择一个动作。所选的动作将在'onContextItemSelected'中可用,不是吗? – NotANumber
@rabis我刚刚编辑了我的问题。我意识到我正在向'onCreateContextMenu'传递一个NULL'menuInfo'。 – NotANumber