(mainActifity)fragment --> 使用接口从列表传递对象的新片段
(mainActifity)fragment --> new fragment passing object from list using an interface
我有两件事有问题。
- 不知何故我无法让我的界面
onClickListener
工作。
- 在第一个问题解决后,我不知道如何开始
fragmentB
展示这本书(fragmentA
有RecycleView
有书)
我是否检查并尝试了 stack/google 上的解决方案?
是的,过去 2 天我一直在努力解决这些问题。
有些代码很旧,有些我不知道如何在我的代码中实现它,因为我还是个初学者。
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("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);
}
}
这里我做了界面,所以我在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();
// 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;
}
}
对于 onClickListener,您可以在适配器中创建一个接口,并使 Fragment 实现它并将其传递给适配器构造函数 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);
}
}
在你的片段中
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
这基本上就是适配器和片段之间的通信方式
每当用户单击某个项目时,您都会在适配器中使用该 mListener 变量
监听用户点击的简单方法是在 onBindViewHolder 方法中
使用
viewHolder.YourView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onItemInteract(position);
}
}
所以你的最终代码应该是这样的
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);
}
}
和 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();
}}
编辑
这是第二部分,在您使用 Toast 的地方使用该代码
在 FragmentA 中,在 onClickListenter 中使用它并传递位置(或使用 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();
}}
并在 FragmentB 中使用 getArguments() 来检索数据
int position = getArguments().getInt("position");
将此添加到片段
我有两件事有问题。
- 不知何故我无法让我的界面
onClickListener
工作。 - 在第一个问题解决后,我不知道如何开始
fragmentB
展示这本书(fragmentA
有RecycleView
有书)
我是否检查并尝试了 stack/google 上的解决方案?
是的,过去 2 天我一直在努力解决这些问题。 有些代码很旧,有些我不知道如何在我的代码中实现它,因为我还是个初学者。
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("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);
}
}
这里我做了界面,所以我在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();
// 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;
}
}
对于 onClickListener,您可以在适配器中创建一个接口,并使 Fragment 实现它并将其传递给适配器构造函数 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);
}
}
在你的片段中
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
这基本上就是适配器和片段之间的通信方式 每当用户单击某个项目时,您都会在适配器中使用该 mListener 变量 监听用户点击的简单方法是在 onBindViewHolder 方法中 使用
viewHolder.YourView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onItemInteract(position);
}
}
所以你的最终代码应该是这样的 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);
}
}
和 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();
}}
编辑 这是第二部分,在您使用 Toast 的地方使用该代码
在 FragmentA 中,在 onClickListenter 中使用它并传递位置(或使用 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();
}}
并在 FragmentB 中使用 getArguments() 来检索数据
int position = getArguments().getInt("position");
将此添加到片段