Send Object from One Fragment to Another

2019-02-28 14:52发布

问题:

I have two fragments in which1st fragment(Business) there is a object stringlist that needs to be transferred to 2nd fragment(Businessdetail).\

I want to know what is the best method of practise and how should i do it?

public class Business extends Fragment {

        public List<StringList> businessNews = new ArrayList<>();
        private RecyclerView recyclerView;
        StringList stringList; //object need to transfered to other fragment 
        public Business() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {

            View view = inflater.inflate(R.layout.fragment_business, container, false);
            recyclerView = (RecyclerView) view.findViewById(R.id.business_recycler_view);

            FetchLists f = new FetchLists();
            f.execute(10, 0);
            return view;
        }

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


        public class FetchLists extends AsyncTask<Integer, Void, List<StringList>> {

            @Override
            protected List<StringList> doInBackground(Integer... params) {

                int count = params[0];
                int offset = params[1];

                String urlString = "https://nei.org/v1/articlesbjkbknklnmlmerg&sortBy=top&apiKey=50e2bjkbbkba5a5f476ff528a8";
                urlString = urlString + "&count=" + count + "&offset=" + offset;

                try {
                    URL url = new URL(urlString);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    InputStream stream = connection.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
                    String line = reader.readLine();
                    String response = "";
                    while (line != null) {
                        response += line;
                        line = reader.readLine();
                    }

                    JSONObject object = new JSONObject(response);
                    JSONArray emailLists = object.getJSONArray("articles");

                    for (int i = 0; i < emailLists.length(); i++) {
                        JSONObject listData = (JSONObject) emailLists.get(i);

                         stringList = new StringList();
                        stringList.authorName = listData.getString("author");
                        stringList.headline = listData.getString("title");
                        stringList.publishedTime = listData.getString("publishedAt");
                        stringList.newsDetail = listData.getString("description");

                        businessNews.add(stringList);
                        Log.d("ashu", "authorname" + stringList.authorName);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
                return businessNews;
            }

        public class BusinessAdapter extends RecyclerView.Adapter<BusinessHolder> {



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

                Context context = parent.getContext();
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                View view = inflater.inflate(R.layout.layout_news, parent, false);
                return new BusinessHolder(view);
            }

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

                StringList m = c.get(position);
                holder.bindListName(m, position);
     }}

        public class BusinessHolder extends RecyclerView.ViewHolder {

            public TextView headlineTextview;
            public TextView authorTextview;
            public TextView timeTextview;

            public BusinessHolder(View itemView) {
                super(itemView);

                headlineTextview = (TextView) itemView.findViewById(R.id.id_headline);
                authorTextview = (TextView) itemView.findViewById(R.id.id_author);
                timeTextview = (TextView) itemView.findViewById(R.id.id_time);

            }

2nd Fragment:

In this fragment i want to set the object data to the Textview Parameters

public class BusinessDetail extends Fragment {
 StringList mstringList;
    private TextView headlineSecond;
    public TextView authorSecond;
    private TextView detailsSecond;


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

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


    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        headlineSecond = (TextView) view.findViewById(R.id.id_headline_second);
        authorSecond = (TextView) view.findViewById(R.id.id_author_second);
        detailsSecond = (TextView) view.findViewById(R.id.id_details_second);
   }}

回答1:

Fragments are not supposed to know about each other.

Instead of tranfering from one fragment to another, declare the object list in the activity and have each fragment get it from there:

To do that in main activity declare the object list and a getter for the list:

public List<StringList> businessNews = new ArrayList<>();

public List<StringList> getObjectList(){
    return objectList;
}

Then in the Fragments, you can get the list:

((MainActivity) getActivity()).getObjectList();

You could make this call in onResume() to make sure the Fragment and the Activity are ready.

For a more correct solution, this part ((MainActivity) getActivity())could be implemented using an interface so as to avoid the casting.



回答2:

If BusinessDetail and Business are children of the same activity, you should provide an interface between both fragments and the activity. In your Business fragment, you could make this call (in the fragment's onAttach or after):

((MyActivity)getActivity()).showObjectOnBusiness(stringList);

In the MyActivity showObjectOnBusiness method, you should pass the object to the BusinessDetail fragment:

Bundle bundle = new Bundle();
bundle.putParcelable(BusinessDetail.OBJECT_KEY, stringList);
new BusinessDetail().setArguments(bundle);

Inside your BusinessDetail, you may obtain your object through the arguments:

Bundle bundle = getArguments();

if (bundle == null || !bundle.containsKey(OBJECT_KEY)) {
    throw new IllegalArgumentException("StringList should not be null");
}
StringList stringList = bundle.getParcelable(OBJECT_KEY);

StringList should implement Parcelable.



回答3:

Saving reference to fragment in another one - bad practice. You can use this method, it works fine.



回答4:

You can achieve this through following code

Bundle bundle = new Bundle();
bundle.putParcelableArrayList("Key_List", businessNews);
fragmentInstance.setArguments(bundle);

You can also use Serializable but serializable is slower than parcelable

 Bundle bundle = new Bundle();
bundles.putSerializable("Key_List", businessNews);
fragmentInstance.setArguments(bundle);


回答5:

You can use Event Bus library

It will simplify the communication between components,

works on publisher/subscriber pattern.