“`java (mainActivity)fragment –> 使用接口从列表传递对象至新的fragment “`

huangapple go评论75阅读模式
英文:

(mainActifity)fragment --> new fragment passing object from list using an interface

问题

  1. 我有两个问题。

  2. 首先,我不知道如何使我的接口 onClickListener 起作用。

  3. 在解决了第一个问题之后,我不知道如何启动 fragmentB 来显示书籍(fragmentA 有一个包含书籍的 RecycleView)。

  4. 我是否检查并尝试了堆栈/Google上的解决方案?

  5. 是的,我尝试过,并且在过去的两天里一直在努力解决这些问题。有些代码已经过时,有些我无法弄清楚如何在我的代码中实现,因为我还是个初学者。

  6. FragmentA(mangasSearch)MainActivity 的一部分(不确定您是否想看到 MainActivity 的代码)。

  7. FragmentB 将是一个新的片段,当按返回键时,它将被销毁并返回到 fragmentA

  8. 这是我的 RecycleView 代码:

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.squareup.picasso.Picasso;

import java.util.ArrayList;

import Classes.Manga;

public class MyAdapterRecyclerView extends RecyclerView.Adapter<MyAdapterRecyclerView.MyViewHolder> {
    private ArrayList<Manga> mDataSet;
    private Context context;

    public MyAdapterRecyclerView(ArrayList<Manga> dataSet, Context context) {
        mDataSet = dataSet;
        this.context = context;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleview_item, parent, false);
        //  final RecyclerView.ViewHolder holder = new MyViewHolder(view);

        return new MyViewHolder(view);//, communicator);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Picasso.get().load(mDataSet.get(position).getPosterPicture()).into(holder.imageviewBookCover);
        holder.tvBookTitle.setText("这是第 " + position + " 本书,标题是 " + mDataSet.get(position).getTitle());
    }

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

    private static OnMangaBookClickListener onMangaBookClickListener;

    public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public ImageView imageviewBookCover;
        public TextView tvBookTitle;
        OnMangaBookClickListener onMangaBookClickListener;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            imageviewBookCover = itemView.findViewById(R.id.imageView_bookcover);
            tvBookTitle = itemView.findViewById(R.id.textView_booktitle);

            itemView.setOnClickListener((View.OnClickListener) onMangaBookClickListener);
        }

        @Override
        public void onClick(View view) {
            onMangaBookClickListener.onMangaBookClick(getAdapterPosition(), view);
        }
    }

    public void setOnMangaBookClickListener(OnMangaBookClickListener onMangaBookClickListener) {
        MyAdapterRecyclerView.onMangaBookClickListener = onMangaBookClickListener;
    }

    public interface OnMangaBookClickListener {
        void onMangaBookClick(int position, View view);
    }
}
  1. 这里我创建了接口,然后在 fragmentA 中调用它并创建 FragmentB

  2. 这是 fragmentA 的代码:

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

import Classes.JsonHandling;
import Classes.Manga;

public class MangasSearchFragment extends Fragment {

    private RecyclerView recyclerView;
    private MyAdapterRecyclerView mAdapter;
    private RecyclerView.LayoutManager layoutManager;
    private Bundle results;
    private ArrayList<Manga> mangaTempList;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_mangas_to_search, container, false);
        Context context = getActivity();
        recyclerView = view.findViewById(R.id.recyclerview_manga_book);
        mangaTempList = new JsonHandling(context).getMangaBookJson();

        recyclerView.setHasFixedSize(true);

        layoutManager = new LinearLayoutManager(context);
        recyclerView.setLayoutManager(new GridLayoutManager(context, 3));

        mAdapter = new MyAdapterRecyclerView(mangaTempList, context);

        mAdapter.setOnMangaBookClickListener(new MyAdapterRecyclerView.OnMangaBookClickListener() {
            @Override
            public void onMangaBookClick(int position, View view) {
                Toast.makeText(getContext(), "什么?!", Toast.LENGTH_SHORT).show();
            }
        });

        recyclerView.setAdapter(mAdapter);

        return view;
    }
}

希望这些信息对你有帮助。

英文:

I have trouble with 2 things.

  1. Somehow I cannot make my interface onClickListener work.
  2. After I got the first problem solved, I have not an idea about how to start fragmentB to display the book (fragmentA has a RecycleView with books)

Did I check and tried solutions on stack/google?

Yes, I did, have been struggling with these problems for the last 2 days.
Some codes are old, some I cannot figure out how to implement it in my code, as I am still a beginner.

FragmentA(mangasSearch) is part of MainActivity (not sure if you want to see the code of MainActivity)

FragmentB will be a new Fragment that when pressed back, will be destroyed and get back to fragmentA

Here is my RecycleView

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import Classes.Manga;
public class MyAdapterRecyclerView extends RecyclerView.Adapter&lt;MyAdapterRecyclerView.MyViewHolder&gt; {
private ArrayList&lt;Manga&gt; mDataSet;
private Context context;
public MyAdapterRecyclerView(ArrayList&lt;Manga&gt; dataSet, Context context) {
mDataSet = dataSet;
this.context = context;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleview_item, parent, false);
//  final RecyclerView.ViewHolder holder = new MyViewHolder(view);
return new MyViewHolder(view);//, communicator);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Picasso.get().load(mDataSet.get(position).getPosterPicture()).into(holder.imageviewBookCover);
holder.tvBookTitle.setText(&quot;This is book nr: &quot; + position + &quot; and title &quot; + mDataSet.get(position).getTitle());
}
@Override
public int getItemCount() {
return mDataSet.size();
}
private static OnMangaBookClickListener onMangaBookClickListener;
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView imageviewBookCover;
public TextView tvBookTitle;
OnMangaBookClickListener onMangaBookClickListener;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
imageviewBookCover = itemView.findViewById(R.id.imageView_bookcover);
tvBookTitle = itemView.findViewById(R.id.textView_booktitle);
itemView.setOnClickListener((View.OnClickListener) onMangaBookClickListener);
}
@Override
public void onClick(View view) {
onMangaBookClickListener.onMangaBookClick(getAdapterPosition(), view);
}
}
public void setOnMangaBookClickListener(OnMangaBookClickListener onMangaBookClickListener) {
MyAdapterRecyclerView.onMangaBookClickListener = onMangaBookClickListener;
}
public interface OnMangaBookClickListener {
void onMangaBookClick(int position, View view);
}
}

Here I made the interface, so I call it on fragmentA and create FragmentB.

Here is fragmentA code

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import Classes.JsonHandling;
import Classes.Manga;
public class MangasSearchFragment extends Fragment {
private RecyclerView recyclerView;
private MyAdapterRecyclerView mAdapter;
private RecyclerView.LayoutManager layoutManager;
private Bundle results;
private ArrayList&lt;Manga&gt; mangaTempList;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mangas_to_search, container, false);
Context context = getActivity();
recyclerView = view.findViewById(R.id.recyclerview_manga_book);
mangaTempList = new JsonHandling(context).getMangaBookJson();
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
// use a linear layout manager
layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(new GridLayoutManager(context, 3));
// specify an adapter (see also next example)
mAdapter = new MyAdapterRecyclerView(mangaTempList, context);
mAdapter.setOnMangaBookClickListener(new MyAdapterRecyclerView.OnMangaBookClickListener() {
@Override
public void onMangaBookClick(int position, View view) {
Toast.makeText(getContext(), &quot;WHAT?!&quot;, Toast.LENGTH_SHORT).show();
}
});
recyclerView.setAdapter(mAdapter);
return view;
}
}

答案1

得分: 1

OK对于`onClickListener`,你在你的适配器中创建一个接口让片段实现它并将其传递给适配器的构造函数例如

```java
public class MyAdapterRecyclerView extends RecyclerView.Adapter<MyAdapterRecyclerView.MyViewHolder> {
    // ...
    OnItemInteractListener mListener;
    
    public MyAdapterRecyclerView(ArrayList<Manga> dataSet, OnItemInteractListener listener) {
        this.mListener = listener;
        // ...
    }
    
    // ...
    
    public interface OnItemInteractListener {
        void onItemInteract(int position);
    }
}

然后在你的片段中:

public class MangasSearchFragment extends Fragment implements MyAdapterRecyclerView.OnItemInteractListener {
    // ...
    mAdapter = new MyAdapterRecyclerView(mangaTempList, this); // 将监听器传递给适配器
    // ...
    @Override
    public void onItemInteract(int position) {
        // 处理点击事件,例如显示 Toast 或打开片段
    }
}

这基本上是适配器和片段之间如何通信的方法。在适配器中,当用户点击某个项时,你可以在onBindViewHolder方法内使用mListener变量:

viewHolder.YourView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mListener.onItemInteract(position);
    }
});

这是你的代码的最终样式:

public class MyAdapterRecyclerView extends RecyclerView.Adapter<MyAdapterRecyclerView.MyViewHolder> {
    // ...
    OnMangaBookClickListener mListener;
    public MyAdapterRecyclerView(ArrayList<Manga> dataSet, OnMangaBookClickListener listener) {
        // ...
        this.mListener = listener;
    }
    // ...
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, final int position) {
        // ...
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.onMangaBookClick(position);
            }
        });
    }
    // ...
    public interface OnMangaBookClickListener {
        void onMangaBookClick(int position);
    }
}

对于MangasSearchFragment

public class MangasSearchFragment extends Fragment implements MyAdapterRecyclerView.OnMangaBookClickListener {
    // ...
    mAdapter = new MyAdapterRecyclerView(mangaTempList, this);
    // ...
    @Override
    public void onMangaBookClick(int position) {
        Toast.makeText(getContext(), "item " + position, Toast.LENGTH_SHORT).show();
    }
}

在第二部分,当你需要在FragmentAonClickListener中使用时,传递位置(或使用Bundle传递任何数据),可以这样做:

public class MangasSearchFragment extends Fragment implements MyAdapterRecyclerView.OnMangaBookClickListener {
    // ...
    @Override
    public void onMangaBookClick(int position) {
        Bundle bundle = new Bundle();
        bundle.putInt("position", position);
        FragmentB fragmentB = new FragmentB();
        fragmentB.setArguments(bundle);
        getActivity().getSupportFragmentManager().beginTransaction()
            .replace(containerID, fragmentB, "FragmentB")
            .addToBackStack(null)
            .commit();
    }
}

然后在FragmentB中使用getArguments()来检索数据:

int position = getArguments().getInt("position");

在片段中添加这部分代码。


<details>
<summary>英文:</summary>
OK for onClickListener you create an Interface in your adapter and make the Fragment implements it and pass it to the adapter constructor f.e 
public class MyAdapterRecyclerView extends RecyclerView.Adapter&lt;MyAdapterRecyclerView.MyViewHolder&gt; {
......
OnItemInteractListener mListner;
public MyAdapterRecyclerView(ArrayList&lt;Manga&gt; dataSet, OnItemInteractListener listener){
this.mListner = listener;
......
// your adapter code
public interface OnItemInteractListener{
void onItemInteract(int position);
}
}
and in your fragment 
public class MangasSearchFragment extends Fragment implements MyAdapterRecyclerView.OnItemInteractListener{
// this will automatically ask you to override the onItemIteract method where you&#39;ll display your toast or open your fragment 
....
// your fragment code 
mAdapter = new MyAdapterRecyclerView(mangaTempList, this); // pass the listener to adapter using this 
this is basically how you communicate between adapter and fragment 
you use that mListener variable in adapter whenever the user clicks on an item 
and the easy way to listen to user click is inside onBindViewHolder method
using 
viewHolder.YourView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onItemInteract(position);
}
}
so the final code of yours should be like this 
**MyAdapterRecyclerView**
public class MyAdapterRecyclerView extends RecyclerView.Adapter&lt;MyAdapterRecyclerView.MyViewHolder&gt; {
private ArrayList&lt;Manga&gt; mDataSet;
private Context context;
OnMangaBookClickListener mListener;
public MyAdapterRecyclerView(ArrayList&lt;Manga&gt; dataSet, OnMangaBookClickListener listener) {
mDataSet = dataSet;
this.mListener = listener;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleview_item, parent, false);
//  final RecyclerView.ViewHolder holder = new MyViewHolder(view);
this.context = parent.getContext();
return new MyViewHolder(view);//, communicator);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, final int position) {
Picasso.get().load(mDataSet.get(position).getPosterPicture()).into(holder.imageviewBookCover);
holder.tvBookTitle.setText(&quot;This is book nr: &quot; + position + &quot; and title &quot; + mDataSet.get(position).getTitle());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onMangaBookClick(position);
}
});
}
@Override
public int getItemCount() {
return mDataSet.size();
}
private static OnMangaBookClickListener onMangaBookClickListener;
public static class MyViewHolder extends RecyclerView.ViewHolder  {
public ImageView imageviewBookCover;
public TextView tvBookTitle;
public View itemView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
this.itemView = itemView;
imageviewBookCover = itemView.findViewById(R.id.imageView_bookcover);
tvBookTitle = itemView.findViewById(R.id.textView_booktitle);
}
}
public interface OnMangaBookClickListener {
void onMangaBookClick(int position);
}
}
and for **MangasSearchFragment** 
public class MangasSearchFragment extends Fragment implements  MyAdapterRecyclerView.OnMangaBookClickListener{
private RecyclerView recyclerView;
private MyAdapterRecyclerView mAdapter;
private RecyclerView.LayoutManager layoutManager;
private Bundle results;
private ArrayList&lt;Manga&gt; mangaTempList;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mangas_to_search, container, false);
Context context = getActivity();
recyclerView = view.findViewById(R.id.recyclerview_manga_book);
mangaTempList = new JsonHandling(context).getMangaBookJson();
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
// use a linear layout manager
layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(new GridLayoutManager(context, 3));
// specify an adapter (see also next example)
mAdapter = new MyAdapterRecyclerView(mangaTempList, this);
recyclerView.setAdapter(mAdapter);
return view;
}
@Override
public void onMangaBookClick(int position) {
Toast.makeText(getContext(), &quot;item &quot;+position, 
Toast.LENGTH_SHORT).show();
}}
----------
**Edit**
**That&#39;s for second part use that code where you&#39;re using Toast** 
in FragmentA use this inside the onClickLisnter and pass the position ( or any data using bundle ) 
public class MangasSearchFragment extends Fragment implements  MyAdapterRecyclerView.OnMangaBookClickListener{
private RecyclerView recyclerView;
private MyAdapterRecyclerView mAdapter;
private RecyclerView.LayoutManager layoutManager;
private Bundle results;
private ArrayList&lt;Manga&gt; mangaTempList;
int containerID = 0;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
containerID = container.getId();
... // your code 
}
@Override
public void onMangaBookClick(int position) {
Bundle bundle = new Bundle();
bundle.putInt(&quot;position&quot;, position);
FragmentB fragmentB = new FragmentB();
fragmentB.setArguments(bundle);
getActivity().getSupportFragmentManager().beginTransaction()
.replace(containerID, fragmentB, &quot;FragmentB&quot;)
.addToBackStack(null)
.commit();
}}
and use getArguments() in FragmentB to retrieve the data
int position =  getArguments().getInt(&quot;position&quot;);
----------
add this to Fragment 
</details>

huangapple
  • 本文由 发表于 2020年7月27日 04:48:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63105546.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定