Android 获取空指针异常-使用接口将数据从适配器传递到子片段

Android 获取空指针异常-使用接口将数据从适配器传递到子片段,android,android-fragments,nullpointerexception,android-adapter,Android,Android Fragments,Nullpointerexception,Android Adapter,我有一个适配器和一个子片段。我正在使用一个接口将数据从适配器传递到子片段。我遇到的问题是,我一直得到一个空指针异常。我已经通读了这里有关这个问题的各种帖子,不知道哪里出了问题。我在“passAdapterVariable.passAdapterVariable(mname)”行获得NPE。根据我读到的内容,我怀疑这可能是因为我没有正确初始化PassaAdapterVariable。我尝试了基于其他示例的几种不同的初始化方法,但我一直得到NPE 这是适配器 public class MatchAd

我有一个
适配器
和一个子片段。我正在使用一个接口将数据从
适配器
传递到
子片段
。我遇到的问题是,我一直得到一个
空指针异常
。我已经通读了这里有关这个问题的各种帖子,不知道哪里出了问题。我在“passAdapterVariable.passAdapterVariable(mname)”行获得NPE。根据我读到的内容,我怀疑这可能是因为我没有正确初始化PassaAdapterVariable。我尝试了基于其他示例的几种不同的初始化方法,但我一直得到NPE

这是适配器

public class MatchAdapter extends RecyclerView.Adapter<MatchAdapter.MatchViewHolder> {

    //declaration of variables
    private Fragment fragment;
    private FragmentManager fragmentManager;
    private DiscoverPage discoverPage;
    private Context context;
    private int size;
    private int mposition;
    private TextView txt_matchname;
    private ImageView img_matchpic;
    List<String> maImg = new ArrayList<>();
    private String mname;
    PassAdapterVariable passAdapterVariable;


    public interface PassAdapterVariable {

        void passAdapterVariable(String mname);
    }


    //the constructor
    public MatchAdapter(List<String> maImg, int size, Context context, DiscoverPage discoverPage){//, PassAdapterVariable passAdapterVariable) {

        this.maImg = maImg;
        this.context = context;
        this.discoverPage = discoverPage;
        this.size = size;
        //this.passAdapterVariable = (PassAdapterVariable)context;
    }

    public MatchAdapter(String mname, Context context) {
        this.context = context;
        this.passAdapterVariable  = (PassAdapterVariable)context;
    }


    //PassAdapterVariable passAdapterVariable = (PassAdapterVariable) context;


    @Override
    public MatchAdapter.MatchViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.match_items, parent, false);
        MatchViewHolder matchViewHolder = new MatchViewHolder(view, maImg, discoverPage);


        return matchViewHolder;
    }


    @Override
    public void onBindViewHolder(MatchViewHolder holder, int position) {

        Picasso.with(context).load(maImg.get(position)).into(holder.img_match);
        holder.setIsRecyclable(false);

    }


    @Override
    public int getItemCount() {
        return maImg.size();
    }


    //viewholder class
    public class MatchViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private static final String TAG = "error";
        //declare variables
        private DiscoverPage discoverPage;
        private ImageView img_match;


        //ViewHolder constructor
        public MatchViewHolder(View itemView, final List<String> maImg, final DiscoverPage discoverPage) {
            super(itemView);

            //initialize variables inside the viewholder constructor
            this.discoverPage = discoverPage;
            img_match = (ImageView) itemView.findViewById(R.id.img_match);
            txt_matchname = (TextView) itemView.findViewById(R.id.txt_matchname);
            img_matchpic = (ImageView) itemView.findViewById(R.id.img_matchpic);


            //set click listener for the img_match
            img_match.setOnClickListener(this);

        }


        @Override
        public void onClick(View view) {
            if (view == img_match) {
                //discoverPage.isHidden();
                Fragment currentFragment;
                fragment = new ClickedMatch();
                fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(android.R.id.content, fragment);
                transaction.addToBackStack("DiscoverPage");

                if ((currentFragment = ((AppCompatActivity) context).getSupportFragmentManager().findFragmentById(R.id.main_container)) != null) {
                    transaction.hide(currentFragment);
                }
                else {
                    transaction.commit();
                }


                mname = maImg.get(getAdapterPosition());
                mposition = getAdapterPosition();
                mname = maImg.get(mposition);
                passAdapterVariable.passAdapterVariable(mname);

            }

        }
    }
}
为了添加更多的上下文,我有一个主活动(UserMainPage)。底部导航菜单选择器用一个片段(DiscoverPage)替换UserMainPage

DiscoverPage调用适配器(MatchAdapter)。单击DiscoverPage上的按钮将DiscoverPage替换为子片段(ClickedMatch)

我正在尝试将一个变量从MatchAdapter传递到ClickedMatch。

调用passAdapterVariable时,字符串“mname”似乎为null。passAdapterVariable(mname)

您的列表maImg为空| | null或提供的适配器位置错误

尝试日志记录

            Log.d(TAG, "pos: " + getAdapterPosition());
            mname = maImg.get(getAdapterPosition());
            Log.d(TAG, "name: " + mname);
只是适配器类中的声明+赋值语句。此时,上下文为空

变量上下文仅在构造函数中赋值。在分配了上下文后,分配您的PassaAdapterVariable

public MatchAdapter(List<String> maImg, int size, Context context, DiscoverPage discoverPage) {

        this.maImg = maImg;
        this.context = context;
        this.discoverPage = discoverPage;
        this.size = size;
        passAdapterVariable = (PassAdapterVariable) context;

    }
公共匹配适配器(列出maImg、int-size、上下文上下文、DiscoverPage DiscoverPage){
this.maImg=maImg;
this.context=上下文;
this.discoverPage=discoverPage;
这个。大小=大小;
passAdapterVariable=(passAdapterVariable)上下文;
}
内部匹配适配器------ 在构造函数中将实例添加到接口,该构造函数将作为

{
DataInterface passInterface;
Context context;
public MatchAdapter(String mname, Context context1, DataPass pass) {

        this.passAdapterVariable  = mname;
        this.context = context1;
        this.passInterface = pass;
    }
}
现在,在作为调用适配器时获取该接口的实例

{

MatchAdapter matAdapter = new MatchAdapter(pname, getActivity(),this);
}

我能够使用
将数据从适配器传递到子片段

我修改了我的代码如下:

在适配器中,我添加了:

fragment = new ClickedMatch();
Bundle bundle = new Bundle();
bundle.putString("matchname",mname);
fragment.setArguments(bundle); 

...

transaction.commit();
在我的子片段中,我添加了:

Bundle bundle = this.getArguments();
if(bundle != null){
   pname = bundle.getString("matchname");
}

没有必要使用接口。根据我所做的研究,我认为(我可能错了)在片段之间通信时,创建接口然后实现接口比在适配器和子片段之间通信更好。

在语句PassAdapterVariable PassAdapterVariable=(PassAdapterVariable)上下文上,您的上下文为空;,将其移动到适配器类构造函数。我移动了PassAdapterVariable PassAdapterVariable=(PassAdapterVariable)上下文。我有两个构造函数(不确定这是否是好的做法),当我放置它不是第二个构造函数时,我得到相同的NPE。当我把它放在第一个构造函数中时,程序崩溃,我得到错误消息用户主页(这是主要活动)无法转换为MatchAdapter.PassAdapterVariable@darwindid你在你的活动中实现了PassAdapterVariable接口?你必须使用带有活动参数的构造函数,并在同一个活动中实现PassAdapterVariable接口否,我只在片段中实现了它。我是否也应该在活动中实施它@达尔文列表maImg不是空的。按照建议执行日志,我得到值08-13 23:20:59.943 29966-29966/com.test.jack D/错误:pos:0 08-13 23:20:59.943 29966-29966/com.test.jack D/错误:名称:@gekn76I在上下文之后分配了passAdapterVariable,我仍然得到了NPE@Arun Shankarc你能发布更改后的代码吗?让我编辑一下我的答案,看看我的意思。我确实试过了。当我在那里初始化passAdapterVariable时,程序崩溃,我得到一个强制转换异常UserMainPage无法转换为MatchAdapter.PassAdapterVariable.“@Arun ShankarTried如建议。我仍然得到NPE。我发布了更新的代码,并为问题添加了更多的上下文。@Sushil Chaudhary当我添加DataInterace passInterface时,我得到消息“无法识别符号DataInterface”。我无法写入”this.passAdapterVariable=mname“。它们是不兼容的类型@Sushil ChaudharyDataInterface是您创建的接口,编写为接口指定的类名,并在构造函数之前将passAdapterVariable初始化为字符串passAdapterVariable;使用itCheck out@RookyCoderi尝试了您的代码,但值不会转移到其他代码fragment@Adnanhaider我不确定您在什么环境下尝试了该代码,但它对我来说(3年前)没有任何问题。这篇文章中还有其他的建议,也许你可以尝试一下他们的建议。
{
DataInterface passInterface;
Context context;
public MatchAdapter(String mname, Context context1, DataPass pass) {

        this.passAdapterVariable  = mname;
        this.context = context1;
        this.passInterface = pass;
    }
}
{

MatchAdapter matAdapter = new MatchAdapter(pname, getActivity(),this);
}
fragment = new ClickedMatch();
Bundle bundle = new Bundle();
bundle.putString("matchname",mname);
fragment.setArguments(bundle); 

...

transaction.commit();
Bundle bundle = this.getArguments();
if(bundle != null){
   pname = bundle.getString("matchname");
}