簡體   English   中英

如何將數據從 Recyclerview 傳遞到 Fragment

[英]How to pass data from Recyclerview to Fragment

我在 Fragment 中填充了一個 recyclerView,我想啟動一個新的 Fragment 並從適配器傳遞數據,我嘗試使用 Bundles 但它總是給我的適配器類一個空值

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private LayoutInflater inflater;
private List<Information> mList;
private FragmentCommunication mCommunicator;

public RecyclerAdapter(Context context, List<Information> list,FragmentCommunication communication) {
    inflater = LayoutInflater.from(context);
    mList = list;
    mCommunicator=communication;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.single_row, parent, false);
    MyViewHolder holder = new MyViewHolder(view,mCommunicator);
    return holder;
}

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

    final Information current = mList.get(position);
    holder.name.setText(current.name);
    holder.job.setText(current.job);

    FragmentB fragmentB=new FragmentB();
    Bundle bundle=new Bundle();
    bundle.putString("NAME",current.name);
    bundle.putString("JOB",current.job);
    fragmentB.setArguments(bundle);

}

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

public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView name;
    TextView job;
    FragmentCommunication mComminication;

    public MyViewHolder(View itemView, FragmentCommunication Communicator) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.tv_name);
        job = (TextView) itemView.findViewById(R.id.tv_gob);
        mComminication=Communicator;
        name.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        mComminication.respond(getAdapterPosition());
    }
}

這是我想要啟動的新 Fragment

public class FragmentB extends Fragment {
TextView textview;
TextView textView2;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view= inflater.inflate(R.layout.fragment_b,container,false);

    textview= (TextView) view.findViewById(R.id.tv_name);
    textView2= (TextView) view.findViewById(R.id.tv_job);
    return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    Bundle arguments = getArguments();


        if (arguments!=null){
        String name= arguments.get("NAME").toString();
        String job= arguments.get("JOB").toString();
            textview.setText(name);
            textView2.setText(job);}

}

}

這就是我將 Fragment 和 recyclerview Adapter 與接口連接的方式

public interface FragmentCommunication {
void respond(int position);

}

這是填充 recyclerview 的 Fragment

public class RecyclerViewFragment extends Fragment {
RecyclerView mRecyclerView;
RecyclerAdapter mRecyclerAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view= inflater.inflate(R.layout.recycler_fragment,container,false);

    mRecyclerView= (RecyclerView) view.findViewById(R.id.recycler);
    mRecyclerAdapter=new RecyclerAdapter(getActivity(),getData(),communication);
    mRecyclerView.setAdapter(mRecyclerAdapter);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    return view;
}

public static List<Information> getData() {
    List<Information>data=new ArrayList<>();
    String[] names={"ahmed","mohammed"};
    String[] jobs={"sacsd","csscs"};

    for (int i=0;i<names.length;i++){
        Information current=new Information();
        current.name=(names[i]);
        current.job=(jobs[i]);
        data.add(current);
    }
    return data;
}

FragmentCommunication communication=new FragmentCommunication() {
    @Override
    public void respond(int position) {
        FragmentB fragmentB=new FragmentB();
        FragmentManager manager=getFragmentManager();
        FragmentTransaction transaction=manager.beginTransaction();
        transaction.replace(R.id.dumper,fragmentB).commit();
    }

};

}

而我的 mainActivity 類只是添加了 RecyclerViewFragment

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RecyclerViewFragment fragment=new RecyclerViewFragment();
    FragmentManager manager=getSupportFragmentManager();
    FragmentTransaction transaction=manager.beginTransaction();
    transaction.add(R.id.dumper,fragment).commit();
}

}

那么啟動 fragmentB 並將數據從 recyclerview Adapter 傳遞給 fragmentB 的正確方法是什么

謝謝你們的回答,我使用帶有字符串值的接口解決了這個問題,將適配器與包含 recyclerview 的片段連接起來,這里的另一個片段正是我所做的:這就是接口

public interface FragmentCommunication {
    void respond(int position,String name,String job);
}

這是適配器

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
    private LayoutInflater inflater;
    private List<Information> mList;
    private FragmentCommunication mCommunicator;

    public RecyclerAdapter(Context context, List<Information> list,FragmentCommunication communication) {
        inflater = LayoutInflater.from(context);
        mList = list;
        mCommunicator=communication;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.single_row, parent, false);
        MyViewHolder holder = new MyViewHolder(view,mCommunicator);
        return holder;
    }

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

        final Information current = mList.get(position);
        holder.name.setText(current.name);
        holder.job.setText(current.job);

        FragmentB fragmentB=new FragmentB();
        Bundle bundle=new Bundle();
        bundle.putString("NAME",current.name);
        bundle.putString("JOB",current.job);
        fragmentB.setArguments(bundle);

    }

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

    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView name;
        TextView job;
        FragmentCommunication mComminication;

        public MyViewHolder(View itemView, FragmentCommunication Communicator) {
            super(itemView);
            name = (TextView) itemView.findViewById(R.id.tv_name);
            job = (TextView) itemView.findViewById(R.id.tv_gob);
            mComminication=Communicator;
            name.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            mComminication.respond(getAdapterPosition(),mList.get(getAdapterPosition()).name,mList.get(getAdapterPosition()).job);
        }
    }
}

包含 recyclerview 的片段

public class RecyclerViewFragment extends Fragment {
    RecyclerView mRecyclerView;
    RecyclerAdapter mRecyclerAdapter;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view= inflater.inflate(R.layout.recycler_fragment,container,false);

        mRecyclerView= (RecyclerView) view.findViewById(R.id.recycler);
        mRecyclerAdapter=new RecyclerAdapter(getActivity(),getData(),communication);
        mRecyclerView.setAdapter(mRecyclerAdapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        return view;
    }

    public static List<Information> getData() {
        List<Information>data=new ArrayList<>();
        String[] names={"ahmed","mohammed"};
        String[] jobs={"sacsd","csscs"};

        for (int i=0;i<names.length;i++){
            Information current=new Information();
            current.name=(names[i]);
            current.job=(jobs[i]);
            data.add(current);
        }
        return data;
    }

    FragmentCommunication communication=new FragmentCommunication() {
        @Override
        public void respond(int position,String name,String job) {
            FragmentB fragmentB=new FragmentB();
            Bundle bundle=new Bundle();
            bundle.putString("NAME",name);
            bundle.putString("JOB",job);
            fragmentB.setArguments(bundle);
            FragmentManager manager=getFragmentManager();
            FragmentTransaction transaction=manager.beginTransaction();
            transaction.replace(R.id.dumper,fragmentB).commit();
        }

    };

}

this is the fragmentB where I get the Strings from the Adapter

    public class FragmentB extends Fragment {
    TextView textview;
    TextView textview2;
    String name;
    String job;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        name=getArguments().getString("NAME");
        job=getArguments().getString("JOB");

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view= inflater.inflate(R.layout.fragment_b,container,false);

        textview= (TextView) view.findViewById(R.id.getName);
        textview2= (TextView) view.findViewById(R.id.getJob);
        textview.setText(name);
        textview2.setText(job);


        return view;

    }


}

如果您使用 kotlin,解決方案要簡單得多。 原答案在這里

將函數val itemClick: (Int) -> Unit傳遞給您的適配器。

class MyRecyclerViewAdapter(params , val itemClick: (Int) -> Unit): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
internal inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    ...
    itemView.setOnClickListener( {itemClick(layoutPosition)} )
  } 
}  

在您的片段中使用返回值position

val myAdapter = MyRecyclerViewAdapter(params) { position ->
    // do something
}

如果我正確理解您的問題,可以在適配器中創建偵聽器接口或使用常規的舊 getter。

使用Bundle想法是正確的。 您只需要通過調用setArguments()將其傳遞給Fragment 然后使用getArguments()檢索FragmentBundle

請注意,您可以執行current.name而不是mList.get(position).name 同樣對於job

問題的另一部分是您在兩個不同的地方創建 FragmentB。 在一處,您還調用了 setArguments() 但不顯示片段。 在另一個中,您顯示片段但不調用 setArguments()。 如果您確實需要從代碼的多個部分執行此操作,您應該編寫一種方法來避免這些不一致。

您需要通過 setArguments(Bundle args) 方法將 Bundle 傳遞給片段。 由於您尚未設置參數,因此您嘗試在 Fragment 中提取的包解析為 null。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM