带有 AlertDialog 的 Fragment ListView ContextMenu
Fragment ListView ContextMenu with AlertDialog
我有一个 ListView
在 Fragment
内。 ListView
有一个 ContextMenu
可以编辑和删除条目。我正在尝试设置一个DialogFragment
,以在选择我的ContextMenu
的EDIT
选项的选择上启动,但是选择编辑时什么都不会显示。这是视图问题吗?提前致谢。
原文Post:
public static class FragmentS extends Fragment {
private ListView saveListView;
private List<LiftSave> LiftSaves = new ArrayList<LiftSave>();
private static final int EDIT = 0, DELETE = 1;
LiftSave longClickedItemLiftSave;
DatabaseHandler dbHandler;
ArrayAdapter<LiftSave> saveAdapter;
public FragmentS() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listview_s,
container, false);
saveListView = (ListView) rootView.findViewById(R.id.saveListView);
registerForContextMenu(saveListView);
DatabaseHandler dbHandler;
dbHandler = new DatabaseHandler (getActivity().getApplicationContext());
if (dbHandler.getLiftSavesCount() != 0)
LiftSaves.addAll(dbHandler.getAllLiftSaves());
populateList();
saveListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
longClickedItemLiftSave = (LiftSave) parent.getItemAtPosition(position);
return false;
}
});
return rootView;
}
private void populateList() {
saveAdapter = new SaveListAdapter();
saveListView.setAdapter(saveAdapter);
}
public class SaveListAdapter extends ArrayAdapter<LiftSave> {
public SaveListAdapter() {
super(getActivity(), R.layout.listview_item, LiftSaves);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null)
view = getActivity().getLayoutInflater().inflate(R.layout.listview_item, parent, false);
LiftSave currentLiftSave = LiftSaves.get(position);
TextView liftName = (TextView) view.findViewById(R.id.liftName);
liftName.setText(currentLiftSave.getLiftName());
TextView maxValue = (TextView) view.findViewById(R.id.maxValue);
maxValue.setText(currentLiftSave.getMaxValue());
TextView weightAndReps = (TextView) view.findViewById(R.id.weightAndReps);
weightAndReps.setText(currentLiftSave.getRepsAndWeight());
TextView liftNotes = (TextView) view.findViewById(R.id.liftNotes);
liftNotes.setText(currentLiftSave.getLiftNotes());
TextView date = (TextView) view.findViewById(R.id.todayDate);
date.setText(currentLiftSave.getTodayDate());
return view;
}
}
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
menu.setHeaderIcon(R.drawable.pencil_icon);
menu.setHeaderTitle("Save Options");
menu.add(Menu.NONE, EDIT, menu.NONE, "Edit Save");
menu.add(Menu.NONE, DELETE, menu.NONE, "Delete Save");
}
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case EDIT:
// TODO: Add save edit code
break;
case DELETE:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Are you sure you want to delete?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dbHandler = new DatabaseHandler(getActivity().getApplicationContext());
dbHandler.deleteLiftSave(longClickedItemLiftSave);
saveAdapter.remove(longClickedItemLiftSave);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
break;
}
return super.
onContextItemSelected(item);
}
}
根据建议更新:
public static class FragmentS extends Fragment {
private ListView saveListView;
private List<LiftSave> LiftSaves = new ArrayList<LiftSave>();
private static final int EDIT = 0, DELETE = 1;
LiftSave longClickedItemLiftSave;
DatabaseHandler dbHandler;
ArrayAdapter<LiftSave> saveAdapter;
public FragmentS() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listview_s,
container, false);
saveListView = (ListView) rootView.findViewById(R.id.saveListView);
registerForContextMenu(saveListView);
DatabaseHandler dbHandler;
dbHandler = new DatabaseHandler (getActivity().getApplicationContext());
if (dbHandler.getLiftSavesCount() != 0)
LiftSaves.addAll(dbHandler.getAllLiftSaves());
populateList();
saveListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
longClickedItemLiftSave = (LiftSave) parent.getItemAtPosition(position);
return false;
}
});
return rootView;
}
private void populateList() {
saveAdapter = new SaveListAdapter();
saveListView.setAdapter(saveAdapter);
}
public class SaveListAdapter extends ArrayAdapter<LiftSave> {
public SaveListAdapter() {
super(getActivity(), R.layout.listview_item, LiftSaves);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null)
view = getActivity().getLayoutInflater().inflate(R.layout.listview_item, parent, false);
LiftSave currentLiftSave = LiftSaves.get(position);
TextView liftName = (TextView) view.findViewById(R.id.liftName);
liftName.setText(currentLiftSave.getLiftName());
TextView maxValue = (TextView) view.findViewById(R.id.maxValue);
maxValue.setText(currentLiftSave.getMaxValue());
TextView weightAndReps = (TextView) view.findViewById(R.id.weightAndReps);
weightAndReps.setText(currentLiftSave.getRepsAndWeight());
TextView liftNotes = (TextView) view.findViewById(R.id.liftNotes);
liftNotes.setText(currentLiftSave.getLiftNotes());
TextView date = (TextView) view.findViewById(R.id.todayDate);
date.setText(currentLiftSave.getTodayDate());
return view;
}
}
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
menu.setHeaderIcon(R.drawable.pencil_icon);
menu.setHeaderTitle("Save Options");
menu.add(Menu.NONE, EDIT, menu.NONE, "Edit Save");
menu.add(Menu.NONE, DELETE, menu.NONE, "Delete Save");
}
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case EDIT:
// TODO: Add save edit code
Context thisContext = getActivity().getBaseContext();
View dialogViewEdit = LayoutInflater.from(thisContext).inflate(R.layout.edit_save, null, false);
final EditText editName = (EditText) dialogViewEdit.findViewById(R.id.editLiftName);
AlertDialog.Builder builderE = new AlertDialog.Builder(this.getActivity());
AlertDialog dialog = builderE.create();
builderE.setView(dialogViewEdit);
dialog.show();
break;
case DELETE: //WORKING!
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
builder.setMessage("Are you sure you want to delete this save?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dbHandler = new DatabaseHandler(getActivity().getApplicationContext());
dbHandler.deleteLiftSave(longClickedItemLiftSave);
saveAdapter.remove(longClickedItemLiftSave);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog dialogD = builder.create();
dialogD.show();
break;
}
return super.
onContextItemSelected(item);
}
}
EDIT
选项反映了来自 XML Layout
的自定义视图。在选择时它显示 android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
。指向行 dialog.show();
。通过调用 Context thisContext = getActivity().getBaseContext();
作为 LayoutInflater
的 Context
解决了这个问题。然而,虽然没有发生错误,但屏幕只是变暗了,就好像启动了 Dialog
一样,但什么也没有出现。 DELETE
选项在正确选择时通过调用 new AlertDialog.Builder(this.getActivity());
启动并运行。然而,当 this.getActivity()
代替 EDIT
选项的 thisContext
时,会产生相同的结果。任何建议将不胜感激。
您仍然需要在构建器设置后显示对话框,例如:
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
...
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
// Create the AlertDialog
AlertDialog dialog = builder.create();
dialog.show();
设置和控制您自己的视图也是一个好主意,例如:
Context thisContext = this.getActivity().getBaseContext();
View dialogView = LayoutInflater.from(thisContext).inflate(R.layout.dialog_edit_1, null, false);
final EditText editName = (EditText) dialogView.findViewById(R.id.editName);
builder.setView(dialogView);
如果您在获取正确的上下文方面遇到问题,而且看起来您确实遇到了问题。代码示例:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
thisContext = view.getContext();
}
备注:
- 由于 DELETE 选项位于嵌套的 class 中,奇怪的是,在 this.getActivity() 中使用
this
对象似乎是必要的。
- 代码
AlertDialog dialog = builder.create()
应该放在按钮设置之后,就像示例代码一样。
- 我在
setPositiveButton
调用之前执行 setView
()。
- editName 是获取用户选择名称的变量,例如。
- 首先尝试
dialog.show()
,因为这是必需的。
- 有一个很好的Google网页@Dialogs,搜索"Adding buttons"。
我有一个 ListView
在 Fragment
内。 ListView
有一个 ContextMenu
可以编辑和删除条目。我正在尝试设置一个DialogFragment
,以在选择我的ContextMenu
的EDIT
选项的选择上启动,但是选择编辑时什么都不会显示。这是视图问题吗?提前致谢。
原文Post:
public static class FragmentS extends Fragment {
private ListView saveListView;
private List<LiftSave> LiftSaves = new ArrayList<LiftSave>();
private static final int EDIT = 0, DELETE = 1;
LiftSave longClickedItemLiftSave;
DatabaseHandler dbHandler;
ArrayAdapter<LiftSave> saveAdapter;
public FragmentS() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listview_s,
container, false);
saveListView = (ListView) rootView.findViewById(R.id.saveListView);
registerForContextMenu(saveListView);
DatabaseHandler dbHandler;
dbHandler = new DatabaseHandler (getActivity().getApplicationContext());
if (dbHandler.getLiftSavesCount() != 0)
LiftSaves.addAll(dbHandler.getAllLiftSaves());
populateList();
saveListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
longClickedItemLiftSave = (LiftSave) parent.getItemAtPosition(position);
return false;
}
});
return rootView;
}
private void populateList() {
saveAdapter = new SaveListAdapter();
saveListView.setAdapter(saveAdapter);
}
public class SaveListAdapter extends ArrayAdapter<LiftSave> {
public SaveListAdapter() {
super(getActivity(), R.layout.listview_item, LiftSaves);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null)
view = getActivity().getLayoutInflater().inflate(R.layout.listview_item, parent, false);
LiftSave currentLiftSave = LiftSaves.get(position);
TextView liftName = (TextView) view.findViewById(R.id.liftName);
liftName.setText(currentLiftSave.getLiftName());
TextView maxValue = (TextView) view.findViewById(R.id.maxValue);
maxValue.setText(currentLiftSave.getMaxValue());
TextView weightAndReps = (TextView) view.findViewById(R.id.weightAndReps);
weightAndReps.setText(currentLiftSave.getRepsAndWeight());
TextView liftNotes = (TextView) view.findViewById(R.id.liftNotes);
liftNotes.setText(currentLiftSave.getLiftNotes());
TextView date = (TextView) view.findViewById(R.id.todayDate);
date.setText(currentLiftSave.getTodayDate());
return view;
}
}
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
menu.setHeaderIcon(R.drawable.pencil_icon);
menu.setHeaderTitle("Save Options");
menu.add(Menu.NONE, EDIT, menu.NONE, "Edit Save");
menu.add(Menu.NONE, DELETE, menu.NONE, "Delete Save");
}
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case EDIT:
// TODO: Add save edit code
break;
case DELETE:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Are you sure you want to delete?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dbHandler = new DatabaseHandler(getActivity().getApplicationContext());
dbHandler.deleteLiftSave(longClickedItemLiftSave);
saveAdapter.remove(longClickedItemLiftSave);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
break;
}
return super.
onContextItemSelected(item);
}
}
根据建议更新:
public static class FragmentS extends Fragment {
private ListView saveListView;
private List<LiftSave> LiftSaves = new ArrayList<LiftSave>();
private static final int EDIT = 0, DELETE = 1;
LiftSave longClickedItemLiftSave;
DatabaseHandler dbHandler;
ArrayAdapter<LiftSave> saveAdapter;
public FragmentS() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listview_s,
container, false);
saveListView = (ListView) rootView.findViewById(R.id.saveListView);
registerForContextMenu(saveListView);
DatabaseHandler dbHandler;
dbHandler = new DatabaseHandler (getActivity().getApplicationContext());
if (dbHandler.getLiftSavesCount() != 0)
LiftSaves.addAll(dbHandler.getAllLiftSaves());
populateList();
saveListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
longClickedItemLiftSave = (LiftSave) parent.getItemAtPosition(position);
return false;
}
});
return rootView;
}
private void populateList() {
saveAdapter = new SaveListAdapter();
saveListView.setAdapter(saveAdapter);
}
public class SaveListAdapter extends ArrayAdapter<LiftSave> {
public SaveListAdapter() {
super(getActivity(), R.layout.listview_item, LiftSaves);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null)
view = getActivity().getLayoutInflater().inflate(R.layout.listview_item, parent, false);
LiftSave currentLiftSave = LiftSaves.get(position);
TextView liftName = (TextView) view.findViewById(R.id.liftName);
liftName.setText(currentLiftSave.getLiftName());
TextView maxValue = (TextView) view.findViewById(R.id.maxValue);
maxValue.setText(currentLiftSave.getMaxValue());
TextView weightAndReps = (TextView) view.findViewById(R.id.weightAndReps);
weightAndReps.setText(currentLiftSave.getRepsAndWeight());
TextView liftNotes = (TextView) view.findViewById(R.id.liftNotes);
liftNotes.setText(currentLiftSave.getLiftNotes());
TextView date = (TextView) view.findViewById(R.id.todayDate);
date.setText(currentLiftSave.getTodayDate());
return view;
}
}
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
menu.setHeaderIcon(R.drawable.pencil_icon);
menu.setHeaderTitle("Save Options");
menu.add(Menu.NONE, EDIT, menu.NONE, "Edit Save");
menu.add(Menu.NONE, DELETE, menu.NONE, "Delete Save");
}
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case EDIT:
// TODO: Add save edit code
Context thisContext = getActivity().getBaseContext();
View dialogViewEdit = LayoutInflater.from(thisContext).inflate(R.layout.edit_save, null, false);
final EditText editName = (EditText) dialogViewEdit.findViewById(R.id.editLiftName);
AlertDialog.Builder builderE = new AlertDialog.Builder(this.getActivity());
AlertDialog dialog = builderE.create();
builderE.setView(dialogViewEdit);
dialog.show();
break;
case DELETE: //WORKING!
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
builder.setMessage("Are you sure you want to delete this save?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dbHandler = new DatabaseHandler(getActivity().getApplicationContext());
dbHandler.deleteLiftSave(longClickedItemLiftSave);
saveAdapter.remove(longClickedItemLiftSave);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog dialogD = builder.create();
dialogD.show();
break;
}
return super.
onContextItemSelected(item);
}
}
EDIT
选项反映了来自 XML Layout
的自定义视图。在选择时它显示 android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
。指向行 dialog.show();
。通过调用 Context thisContext = getActivity().getBaseContext();
作为 LayoutInflater
的 Context
解决了这个问题。然而,虽然没有发生错误,但屏幕只是变暗了,就好像启动了 Dialog
一样,但什么也没有出现。 DELETE
选项在正确选择时通过调用 new AlertDialog.Builder(this.getActivity());
启动并运行。然而,当 this.getActivity()
代替 EDIT
选项的 thisContext
时,会产生相同的结果。任何建议将不胜感激。
您仍然需要在构建器设置后显示对话框,例如:
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
...
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
// Create the AlertDialog
AlertDialog dialog = builder.create();
dialog.show();
设置和控制您自己的视图也是一个好主意,例如:
Context thisContext = this.getActivity().getBaseContext();
View dialogView = LayoutInflater.from(thisContext).inflate(R.layout.dialog_edit_1, null, false);
final EditText editName = (EditText) dialogView.findViewById(R.id.editName);
builder.setView(dialogView);
如果您在获取正确的上下文方面遇到问题,而且看起来您确实遇到了问题。代码示例:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
thisContext = view.getContext();
}
备注:
- 由于 DELETE 选项位于嵌套的 class 中,奇怪的是,在 this.getActivity() 中使用
this
对象似乎是必要的。 - 代码
AlertDialog dialog = builder.create()
应该放在按钮设置之后,就像示例代码一样。 - 我在
setPositiveButton
调用之前执行setView
()。 - editName 是获取用户选择名称的变量,例如。
- 首先尝试
dialog.show()
,因为这是必需的。 - 有一个很好的Google网页@Dialogs,搜索"Adding buttons"。