【问题标题】:Popup Menu in custom ListView自定义 ListView 中的弹出菜单
【发布时间】:2015-03-03 04:28:42
【问题描述】:

我想要达到的目标:

我有一个自定义 ListView 适配器。我想为每个 Listitem 添加一个弹出菜单,与当前 Google Play 应用程序中的 ListView 非常相似。

这是我尝试过的: 我的大部分代码都来自这个 Android 示例 samples\android-19\ui\ActionBarCompat-ListPopupMenu

CustomFragmentPageAdapter.java

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

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

<?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 输出

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

错误是在我的 CustomFragment 中的 popup.show() 处引发的。

这个错误显然让我发疯了,非常感谢任何帮助解决这个问题!

【问题讨论】:

标签: java android listview android-adapter runtimeexception


【解决方案1】:

只要您导入以下内容,Rick 的行代码就可以完美运行:

import android.widget.PopupMenu;

不是下面那个:

import android.support.v7.widget.PopupMenu;

【讨论】:

    【解决方案2】:
        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();
        }
    

    注意:
    别忘了导入这个....

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

    【讨论】:

      【解决方案3】:

      使用this作为(活动上下文)应用上下文或上下文

           PopupMenu popup = new PopupMenu(this, v);
      

      【讨论】:

        【解决方案4】:

        我只是通过将静态活动作为参数传递来修复了类似的错误。例如:

        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();
                }
           });
        }
        

        另外,你的问题可能是这个:Issue 152141

        希望它对您有所帮助,尊重 android.support.v7.widget.PopupMenu 导入。

        问候。

        【讨论】:

          【解决方案5】:

          我终于找到了我的问题的解决方案,尽管我无法解释为什么这个解决方案有效。

          使用以下导入我总是遇到错误:

          import android.support.v7.widget.PopupMenu;
          

          它适用于以下导入:

          import android.widget.PopupMenu;
          

          我测试了 Ric 提供的代码(感谢您的大力帮助!)和我自己的。两人现在都在工作。也许有人解释了为什么在这种情况下导入很重要。

          【讨论】:

            【解决方案6】:

            我在修改主题父样式时遇到了同样的问题: 来自

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

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

            也许您的应用使用 Theme.Base 样式,它没有定义 PopupMenu 使用的必需的第 6 个参数。从 SO 问题How to use ActionBarActivity with Theme.Material,Theme.AppCompat 扩展 Theme.Base.AppCompat

            【讨论】:

            • 我正在使用 Theme.Holo.Light.DarkActionBar,我认为这不是我的问题。另外,我找到了解决我的问题的另一种方法,请参阅我发布的答案。
            【解决方案7】:

            首先在你的custom-item-listview.xml中创建一个button,然后添加下面的代码:

            Button:

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

            类:

            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();
            

            编辑: 这对我很有效:

            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:

            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;
            
            }
            

            【讨论】:

            • 不幸的是,这给了我同样的错误,再次在 popup.show();
            • 我已经尝试过使用上下文而不是 getActivity()。还有其他我没有看到的主要编辑吗?
            • 你能发布你的整个 CustomAdapter 类吗?
            • 测试了一下,又出现同样的错误。请注意,适配器在 Fragment 中使用,而不是在 Activity 中使用。我知道我可以在 Fragment 中使用 getActivity() 获取 Activity,但也许这是主要问题?
            • CustomFragment 应该在您创建 CustomAdapter 时扩展 Fragment
            猜你喜欢
            • 2015-07-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-15
            • 1970-01-01
            • 1970-01-01
            • 2017-03-11
            相关资源
            最近更新 更多