Search code examples
javaandroidandroid-fragmentsandroid-viewpagerandroid-tablayout

Send data to fragment after is initialized


I have problem when I send data to initialized tab. In method getData() I received adapter is null and recyclerview is also null.

TabOne one = new TabOne()
one.getData(populatedList)

The error is next =>

java.lang.NullPointerException: Attempt to invoke virtual method 'void OneAdapter.setData(java.util.List)' on a null object reference.

Is maybe better idea to send data through bundle in fragment or maybe any other idea.

I called getData() becuse here is response from API.

public class TabOne extends Fragment {

        private Unbinder unbinder;

        @BindView(R.id.fab)
        FloatingActionButton floatingActionButton;

        @BindView(R.id.recycler_view_recycler)
        RecyclerView recyclerView;

        private OneAdapter oneAdapter;

        private List<Response> response = new ArrayList<>();

        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.tab_one, container, false);
            unbinder = ButterKnife.bind(this, view);

            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
            oneAdapter = new OneAdapter(getContext(), response);

            recyclerView.setLayoutManager(linearLayoutManager);
            recyclerView.setAdapter(oneAdapter);

            return view;
        }

        public void getData(List<Response> response){
            oneAdapter.setData(response);
        }

        @Override
        public void onDestroyView() {
            super.onDestroyView();
            unbinder.unbind();
        }

    }

Solution

  • You can not call method of fragment from an other Activity/Fragment.

    You have several way for solve this problem

    plan A (suggested)

    Use EventBus library

    1 : Create EventClass.java like this

    public class EventClass{
    
        private List<FILL IT WITH YOUR OBJECT> populatedList;
    
        public EventClass(int populatedList) {
            this.populatedList= populatedList;
        }
    
        public int getPopulatedList() {
            return populatedList;
        }
    }
    

    2 : Use it

    in your activity instead of this

    TabOne one = new TabOne()
    one.getData(populatedList)
    

    Use EventBus and post your event like this

    EventBus.getDefault().postSticky(new EventClass(populatedList));
    

    3 Grap your data inside fragment. Add this function to your Fragment

    @Subscribe
    public void onEvent(EventClass event) {
         oneAdapter.setData(event.getPopulatedList());
    }
    

    4 don't forget to register and unregister your EventBus in Fragmet

    EventBus.getDefault().register(this);//add in onCreateView
    //...
    EventBus.getDefault().unregister(this);//add in onDestroyView
    

    plan B

    Use interface design for callback in fragment. You must create an interface for change data like changingDataListener and implements that in your Fragment and call the callBack from Activity

    plan C (Advanced)

    Use RxJava with PublishSubject you can create Observable for observes new data and whe new data arrives you can update your adapter.

    BELIEVE ME plan A is mush more simple!