简体   繁体   English

自定义 ListView 中的弹出菜单

[英]Popup Menu in custom ListView

What I want to achieve:我想要达到的目标:

I have a custom ListView adapter.我有一个自定义 ListView 适配器。 To each Listitem I want to add a popup menu, pretty similar to the ListView in the current Google Play application.我想为每个 Listitem 添加一个弹出菜单,与当前 Google Play 应用程序中的 ListView 非常相似。

Google Play 项目的屏幕截图

This is what I tried: Most of my code comes from this Android sample samples\\android-19\\ui\\ActionBarCompat-ListPopupMenu这是我尝试过的:我的大部分代码来自这个 Android 示例samples\\android-19\\ui\\ActionBarCompat-ListPopupMenu

CustomFragmentPageAdapter.java : CustomFragmentPageAdapter.java

// create new fragment
mCustomFragment = CustomFragment.newInstance(position);

CustomFragment.java自定义片段.java

public class CustomFragment extends ListFragment implements View.OnClickListener{

...

@Override
public void onClick(final View v) {
    v.post(new Runnable() {
        @Override
        public void run() {
            showPopupMenu(v);
        }
    });
}

private void showPopupMenu(View view) {

    PopupMenu popup = new PopupMenu(getActivity(), view);

    popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());

    popup.show();
}

CustomArrayAdapter :自定义阵列适配器

public class CustomAdapter extends ArrayAdapter<WatchListPlayerItem> {
    ...    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int pos = position;

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        final View rowView = inflater.inflate(R.layout.watch_list_row, parent, false);

        View popupButton = rowView.findViewById(R.id.imgPopUp);

        popupButton.setTag(getItem(position));

        popupButton.setOnClickListener(mFragment);

        return rowView;
    }
}

popup_menu.xml : popup_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/install"
        android:title="Install" />
    <item
        android:id="@+id/addtowishlist"
        android:title="Add to wishlist" />
</menu>

Logcat output :日志输出

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)
...

The error is thrown at popup.show() in my CustomFragment.该错误在我的 CustomFragment 中的 popup.show() 处引发。

This error is clearly driving me crazy and ANY help to solve this issue is highly appreciated!这个错误显然让我发疯,非常感谢任何帮助解决这个问题!

I finally found the solution to my problem, eventhough I have no explanation why this solution works. 我终于找到了我的问题的解决方案,尽管我没有解释为什么这个解决方案有效。

With the following import I always had the error: 使用以下导入我总是有错误:

import android.support.v7.widget.PopupMenu;

It works fine with the following import: 它可以正常使用以下导入:

import android.widget.PopupMenu;

I tested the code provided by Ric (Thanks for the great help!) and my own. 我测试了Ric提供的代码(感谢您的帮助!)和我自己的代码。 Both are working now. 两者现在都在运作。 Maybe someone has an explanation why the import matters in this case. 也许某人有解释为什么导入在这种情况下很重要。

First create a button in your custom-item-listview.xml and then add the code below: 首先在custom-item-listview.xml中创建一个button ,然后添加以下代码:

Button : Button

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_text"
android:id="@+id/button1"
... />

class: 类:

public class CustomAdapter extends ArrayAdapter<CustomItem> {

    private static Activity context = null;
    private final ArrayList<CustomItem> mItemsArrayList;
    private CustomFragment mFragment;


    public CustomAdapter(Activity context, ArrayList<CustomItem> itemsArrayList, CustomFragment fragment) {

        super(context, R.layout.watch_list_row, itemsArrayList);

        CustomAdapter.context = context;
        this.mItemsArrayList = itemsArrayList;
        this.mFragment = fragment;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int pos = position;
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        final View rowView = inflater.inflate(R.layout.watch_list_row, parent, false);
    final Button popUp_btn = (Button)rowView.findViewById(R.id.button1);
    popUp_btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            final PopupMenu popup = new PopupMenu(context, popUp_btn);
            popup.getMenuInflater().inflate(R.menu.context_menu, popup.getMenu());
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                    int i = item.getItemId();
                    if (i == R.id.item1) {
                        //do something
                        return true;
                    }
                    else if (i == R.id.item2){
                        //do something
                        return true;
                    }
                    else if (i == R.id.item3) {
                        //do something
                        return true;
                    }
                    else {
                        return onMenuItemClick(item);
                    }
                }
            });

            popup.show();

EDIT: This works well for me: 编辑:这适合我:

TAB1

public  class TAB1 extends Fragment {
View view;

public TAB1() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.tab1, null);


            ListView list = (ListView) view.findViewById(android.R.id.list);
            CustomList adapter = new CustomList(getActivity());
            adapter.addAll();
            list.setAdapter(adapter);


    return view;
}

CustomList : CustomList

public class CustomList extends ArrayAdapter<YourArrayAdapter> {

private static Activity context = null;

public CustomList(Activity context) {
    super(context, R.layout.custom_listview, web);
    CustomList.context = context;
}
@Override
public View getView(final int position, View view, ViewGroup parent) {
    LayoutInflater inflater = context.getLayoutInflater();
    final View rowView = inflater.inflate(R.layout.custom_listview, null, true);

    //your stuff here

    final Button popUp_btn = (Button)rowView.findViewById(R.id.button1);
    popUp_btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            final PopupMenu popup = new PopupMenu(context, popUp_btn);
            popup.getMenuInflater().inflate(R.menu.context_menu, popup.getMenu());
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                public boolean onMenuItemClick(MenuItem item) {
                    int i = item.getItemId();
                    if (i == R.id.item1) {
                        //do something
                        return true;
                    }
                    else if (i == R.id.item2){
                        //do something
                        return true;
                    }
                    else if (i == R.id.item3) {
                        //do something
                        return true;
                    }
                    else {
                        return onMenuItemClick(item);
                    }
                }
            });

            popup.show();

        }
    });

    return rowView;

}

将此用作(活动上下文) 而非应用程序上下文或上下文

     PopupMenu popup = new PopupMenu(this, v);
    popup = (Button)findViewById(R.id.button);

    popup.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            PopupMenu popup = new PopupMenu(MainActivity.this,view);
            popup.getMenuInflater().inflate(R.menu.popup_menu,popup.getMenu());
            popup.show();
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    int id = item.getItemId();
                    if(id==R.id.install){
                        show_toast("Install Clicked");
                    }else{
                        show_toast("WishList Clicked");                            
                    }
                    return true;
                }
            });
        }
    });



    public void show_toast(String message){
        Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
    }

Note: 注意:
Don't forgot to import this.... 别忘了导入这个....

import android.support.v7.widget.PopupMenu;
import android.view.MenuItem;

Rick's code of lines works perfect as long as you import the following: 只要您导入以下内容,Rick的行代码就可以完美运行:

import android.widget.PopupMenu;

Not the one below: 不是下面那个:

import android.support.v7.widget.PopupMenu;

I've just had the same issue when I modified the theme parent style: from 当我修改主题父样式时,我遇到了同样的问题:来自

<style name="MainAppTheme" parent="@style/Theme.AppCompat.Light">

to

<style name="MainAppTheme" parent="@style/Theme.Base.AppCompat.Light">

Maybe your app uses the Theme.Base style, which does not define the required 6th parameter used by PopupMenu. 也许您的应用程序使用Theme.Base样式,该样式未定义PopupMenu使用的所需第6个参数。 From SO question How to use ActionBarActivity with Theme.Material , Theme.AppCompat extends Theme.Base.AppCompat 从SO问题如何在Theme.Material中使用ActionBarActivity ,Theme.AppCompat扩展了Theme.Base.AppCompat

I fixed a similar error just by passing as parameter a static activity. 我通过将参数作为静态活动传递来修复类似的错误。 For example: 例如:

static AppCompatActivity sActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    sActivity = this;

yourLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        PopupMenu popup = new PopupMenu(sActivity, v);
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.my_popup_menu, popup.getMenu());
        popup.show();
        }
   });
}

Also, you problem might be this one: Issue 152141 此外,您的问题可能是这个问题: 问题152141

Hopefully it will help you, respecting the android.support.v7.widget.PopupMenu import. 希望它能帮到你,尊重android.support.v7.widget.PopupMenu导入。

Regards. 问候。

Firstly required to import首先需要导入
import android.widget.PopupMenu;导入 android.widget.PopupMenu;

And your it must be look like this你的它一定是这样的

holder.dayDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PopupMenu popupMenu = new PopupMenu(context, holder.dayDate);
                popupMenu.getMenu().add("Futa");
                popupMenu.getMenu().add("Acha");
                popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        switch (item.getTitle().toString()) {
                            case "View" :
                                Toast.makeText(context, "Bidhaa imefutwa.", Toast.LENGTH_SHORT).show();
                                break;
                            case "Edit":
//                                popupMenu.dismiss();
                                break;
                        }
                        return false;
                    }
                });
                popupMenu.show();
            }
        });

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM