带有 AlertDialog 的 Fragment ListView ContextMenu

Fragment ListView ContextMenu with AlertDialog

我有一个 ListViewFragment 内。 ListView 有一个 ContextMenu 可以编辑和删除条目。我正在尝试设置一个DialogFragment,以在选择我的ContextMenuEDIT选项的选择上启动,但是选择编辑时什么都不会显示。这是视图问题吗?提前致谢。

原文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(); 作为 LayoutInflaterContext 解决了这个问题。然而,虽然没有发生错误,但屏幕只是变暗了,就好像启动了 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"。