Ali Motameni
Ali Motameni

Reputation: 2787

How can add popupMenu to items of listView in Android?

I want to show popupMenu onLongClick in Android, so I write:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    listView = (ListView) findViewById(R.id.listView);
    adapter = new MyAdapter(getApplicationContext());

}

@Override
protected void onResume() {
    super.onResume();
    connectToDatabase();
}

private void connectToDatabase() {
    //Create database
        listView.setAdapter(adapter);
    }

My Adapter:

        @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        final MyHolder holder;
        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.list_row, null);
            holder = new MyHolder();
            holder.vocabs = (TextView) convertView.findViewById(R.id.textViewVocabs);
            holder.points = (TextView) convertView.findViewById(R.id.textViewPoints);
            holder.tick = (ImageButton) convertView.findViewById(R.id.tick);
            holder.cross = (ImageButton) convertView.findViewById(R.id.cross);
            convertView.setTag(holder);
        } else {
            holder = (MyHolder) convertView.getTag();
        }

        holder.id = id.get(position);
        holder.vocabs.setText(vocabs.get(position));
        holder.points.setText(points.get(position) + "");

        holder.tick.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Toast.makeText(parent.getContext(), "Yes... :D ... You learn it :D", Toast.LENGTH_SHORT).show();
                points.set(position, points.get(position) + 1);
                database.execSQL("UPDATE VOCABS SET POINTS=" + points.get(position) + " WHERE ID=" + id.get(position) + ";");
                notifyDataSetChanged();
            }
        });

        holder.cross.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Toast.makeText(parent.getContext(), "Yes... :D ... You learn it :D", Toast.LENGTH_SHORT).show();
                if (points.get(position) != 0) {
                    points.set(position, points.get(position) - 1);
                    database.execSQL("UPDATE VOCABS SET POINTS=" + points.get(position) + " WHERE ID=" + id.get(position) + ";");
                }
                notifyDataSetChanged();
            }
        });

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(parent.getContext(), means.get(position), Toast.LENGTH_LONG).show();
            }
        });

        final View finalConvertView = convertView;
        convertView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                //popup-menu for delete item.
                PopupMenu popupMenu = new PopupMenu(parent.getContext(),finalConvertView);
                popupMenu.getMenuInflater().inflate(R.menu.popup_menu, popupMenu.getMenu());
                popupMenu.show();

                popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        if (item.getTitle().equals("Delete")) {
                            database.execSQL("DELETE FROM VOCABS WHERE ID=" + holder.id + ";");
                            id.remove(position);
                            vocabs.remove(position);
                            means.remove(position);
                            points.remove(position);
                            notifyDataSetChanged();
                        }
                        return false;
                    }
                });
                //Toast.makeText(parent.getContext(), "onLongClickFunction! " + position, Toast.LENGTH_LONG).show();
                return false;
            }
        });
        return convertView;
    }

I work with Itellij IDEA 13.1.4. I add appcompat to supports popup_Menu on APIs older than 11. now when I run application, Everythings are ok. but when Long Click on an item in the listView get below Error:

04-01 15:50:29.749  17078-17078/net.motameni.apps.vocabs_box E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: net.motameni.apps.vocabs_box, PID: 17078
java.lang.RuntimeException: Failed to resolve attribute at index 6
        at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:603)
        at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:6423)
        at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:6591)
        at android.widget.FrameLayout$LayoutParams.<init>(FrameLayout.java:735)
        at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:679)
        at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:62)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
        at android.support.v7.internal.view.menu.MenuPopupHelper$MenuAdapter.getView(MenuPopupHelper.java:370)
        at android.support.v7.internal.view.menu.MenuPopupHelper.measureContentWidth(MenuPopupHelper.java:219)
        at android.support.v7.internal.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:153)
        at android.support.v7.internal.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:125)
        at android.support.v7.widget.PopupMenu.show(PopupMenu.java:193)
        at net.motameni.apps.vocabs_box.MainActivity$MyAdapter$4.onLongClick(MainActivity.java:154)
        at android.view.View.performLongClick(View.java:4795)
        at android.view.View$CheckForLongPress.run(View.java:19723)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

What is wrong???

Upvotes: 0

Views: 1558

Answers (1)

The Original Android
The Original Android

Reputation: 6215

I suspect you're not getting the correct view when calling PopupMenu constructor.

Change code FROM:

PopupMenu popupMenu = new PopupMenu(parent.getContext(),finalConvertView);

TO:

PopupMenu popupMenu = new PopupMenu(parent.getContext(), v);

I admit maybe it is the same view but depending on the layout design. The suggested code under TO is more accurate. The View parameter v points to a certain row item in ListView.

Please post your menu xml R.menu.popup_menu also.

Upvotes: 2

Related Questions