英文:
(mainActifity)fragment --> new fragment passing object from list using an interface
问题
-
我有两个问题。
-
首先,我不知道如何使我的接口
onClickListener
起作用。 -
在解决了第一个问题之后,我不知道如何启动
fragmentB
来显示书籍(fragmentA
有一个包含书籍的RecycleView
)。 -
我是否检查并尝试了堆栈/Google上的解决方案?
-
是的,我尝试过,并且在过去的两天里一直在努力解决这些问题。有些代码已经过时,有些我无法弄清楚如何在我的代码中实现,因为我还是个初学者。
-
FragmentA(mangasSearch)
是MainActivity
的一部分(不确定您是否想看到MainActivity
的代码)。 -
FragmentB
将是一个新的片段,当按返回键时,它将被销毁并返回到fragmentA
。 -
这是我的
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);
}
}
-
这里我创建了接口,然后在
fragmentA
中调用它并创建FragmentB
。 -
这是
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.
- Somehow I cannot make my interface
onClickListener
work. - After I got the first problem solved, I have not an idea about how to start
fragmentB
to display the book (fragmentA
has aRecycleView
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<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("This is book nr: " + position + " and title " + 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<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();
// 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(), "WHAT?!", 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();
}
}
在第二部分,当你需要在FragmentA
的onClickListener
中使用时,传递位置(或使用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<MyAdapterRecyclerView.MyViewHolder> {
......
OnItemInteractListener mListner;
public MyAdapterRecyclerView(ArrayList<Manga> 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'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<MyAdapterRecyclerView.MyViewHolder> {
private ArrayList<Manga> mDataSet;
private Context context;
OnMangaBookClickListener mListener;
public MyAdapterRecyclerView(ArrayList<Manga> 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("This is book nr: " + position + " and title " + 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<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();
// 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(), "item "+position,
Toast.LENGTH_SHORT).show();
}}
----------
**Edit**
**That's for second part use that code where you'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<Manga> 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("position", position);
FragmentB fragmentB = new FragmentB();
fragmentB.setArguments(bundle);
getActivity().getSupportFragmentManager().beginTransaction()
.replace(containerID, fragmentB, "FragmentB")
.addToBackStack(null)
.commit();
}}
and use getArguments() in FragmentB to retrieve the data
int position = getArguments().getInt("position");
----------
add this to Fragment
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论