java - Android PopupMenu 在recycleview 中不起作用?

标签 java android android-studio

我尝试将子菜单添加到recycleview,但是当单击每行中的子菜单时,会出现一条消息:不幸的是应用程序已停止 之后应用程序自动关闭

activity_main.xml 

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rvAnimals"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

// recycleview_row.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp">
    <TextView
        android:id="@+id/tvAnimalName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"/>
    <TextView
        android:id="@+id/textViewOptions"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:text="&#8942;"
        android:textAppearance="?android:textAppearanceLarge" />

</LinearLayout>

// MainActivity class

    package com.example.hamoda.recyvlastexample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {
    MyRecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // data to populate the RecyclerView with
        ArrayList<String> animalNames = new ArrayList<>();
        animalNames.add("Horse");
        animalNames.add("Cow");
        animalNames.add("Camel");
        animalNames.add("Sheep");
        animalNames.add("Goat");
        // set up the RecyclerView
        RecyclerView recyclerView =(RecyclerView) findViewById(R.id.rvAnimals);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new MyRecyclerViewAdapter(this, animalNames);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);
    }


    @Override
    public void onItemClick(View view, int position) {
        Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
    }
}

// MyRecyclerViewAdapter class

    package com.example.hamoda.recyvlastexample;
import android.content.Context;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.Collections;
import java.util.List;

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
    private List<String> mData = Collections.emptyList();
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;
    // data is passed into the constructor
    public MyRecyclerViewAdapter(Context context, List<String> data) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
    }
    // inflates the row layout from xml when needed
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         View view = mInflater.inflate(R.layout.recyclerview_row, parent,false);
         ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }
    // binds the data to the textview in each row
    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        String animal = mData.get(position);
        holder.myTextView.setText(animal);
        holder.buttonViewOption.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //  creating a popup menu
              PopupMenu popup = new PopupMenu((Context)mData,holder.buttonViewOption);
            /*
                //inflating menu from xml resource
                popup.inflate(R.menu.options_menu);
                //adding click listener
                popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        switch (item.getItemId()) {
                            case R.id.menu1:
                                //handle menu1 click
                                break;
                            case R.id.menu2:
                                //handle menu2 click
                                break;
                            case R.id.menu3:
                                //handle menu3 click
                                break;
                        }
                        return false;
                    }
                });
                //displaying the popup
                popup.show();
                */
            }
        });
    }
    // total number of rows
    @Override
    public int getItemCount() {
        return mData.size();
    }
    // stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView myTextView;
        public TextView buttonViewOption;
        public ViewHolder(View itemView) {
            super(itemView);
            myTextView = (TextView) itemView.findViewById(R.id.tvAnimalName);
            itemView.setOnClickListener(this);
            //textViewDesc = (TextView) itemView.findViewById(R.id.textViewDesc);
            buttonViewOption = (TextView) itemView.findViewById(R.id.textViewOptions);
        }
        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view,getAdapterPosition());
        }

    }
    // convenience method for getting data at click position
    public String getItem(int id) {
        return mData.get(id);
    }
    // allows clicks events to be caught
    public void setClickListener(ItemClickListener itemClickListener) {
        this.mClickListener = itemClickListener;
    }
    // parent activity will implement this method to respond to click events
    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

错误日志:

03-31 11:13:57.461 10139-10139/com.example.hamoda.recyvlastexample E/AndroidRuntime: FATAL EXCEPTION: main 
Process: com.example.hamoda.recyvlastexample, PID: 10139
java.lang.ClassCastException: java.util.ArrayList cannot be cast to android.content.Context
at com.example.hamoda.recyvlastexample.MyRecyclerViewAdapter$1.onClick(MyRecyclerViewAdapter.java:38)
at android.view.View.performClick(View.java:5076)
at android.view.View$PerformClick.run(View.java:20279)
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:5910)
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:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)

最佳答案

您尚未在 PopupMenu 构造函数中传递 Context,并且在 Context 中强制转换数据列表对象是错误的。

PopupMenu popup = new PopupMenu((Context)mData,holder.buttonViewOption);

使用下面的行:

PopupMenu popup = new PopupMenu(context,holder.buttonViewOption);

在上面的行上下文中是 Activity 上下文的引用,它在代码中的 MyRecyclerViewAdapter 构造函数中传递,如下所示:

//数据被传入构造函数

public MyRecyclerViewAdapter(Context context, List<String> data) {
    this.mInflater = LayoutInflater.from(context);
    this.mData = data;
}

因此,创建一个 context 的全局引用并传入 PopupMenu 构造函数。

关于java - Android PopupMenu 在recycleview 中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43136559/

相关文章:

java - Android 使用 OpenGL-ES 中的 glBlendFunc 混合获得正确的不透明度/颜色

java - 为 equals() 实现选择字段的最佳实践

android - 删除android按钮上的阴影效果

javascript - 如何通过使用 anchor 标记的链接打开我安装的应用程序,如下图所示

android - 摩托罗拉 EMDK 实现 DataListener 崩溃 |安卓工作室

Android Gradle 从 apk 中删除资源

java - 嵌套资源获取是否需要在 Java 中进行特殊处理?

android - ARCore 3D图像检测

Android Studio 添加图像 Assets 不起作用

java - 如何将我的 Java 应用程序日志记录事件映射到 GCP Felexible 非兼容 App Engine 中相应的云日志记录事件级别?