0

In my application I want get some data from server and show it into RecyclerView and for this I should use Fragment.

I want when users see fragment call my API call method. but when use below code, show me Force close error.

Code:

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser){
        getData(getActivity());
    }
}

Error :

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ProgressBar.setVisibility(int)' on a null object reference
    at com.app.test.Fragments.MainNotificationFrags.NotificationAllFrag.getData(NotificationAllFrag.java:157)
    at com.app.test.Fragments.MainNotificationFrags.NotificationAllFrag.setUserVisibleHint(NotificationAllFrag.java:142)
    at android.support.v4.app.FragmentStatePagerAdapter.setPrimaryItem(FragmentStatePagerAdapter.java:157)
    at android.support.v4.view.ViewPager.populate(ViewPager.java:1266)
    at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
    at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1642)
    at android.view.View.measure(View.java:17496)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:728)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:464)
    at android.view.View.measure(View.java:17496)
    at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1658)
    at android.view.View.measure(View.java:17496)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:728)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:464)
    at android.view.View.measure(View.java:17496)
    at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1081)
    at android.view.View.measure(View.java:17496)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
    at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
    at android.view.View.measure(View.java:17496)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
    at android.view.View.measure(View.java:17496)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
    at android.view.View.measure(View.java:17496)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
    at android.view.View.measure(View.java:17496)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2636)
    at android.view.View.measure(View.java:17496)
    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2031)
    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1193)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1400)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1078)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5875)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
    at android.view.Choreographer.doCallbacks(Choreographer.java:580)
    at android.view.Choreographer.doFrame(Choreographer.java:550)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5349)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)

Fragment full code:

public class NotificationAllFrag extends Fragment {

    @BindView(R.id.mainNotification_recyclerView)
    RecyclerView mainNotification_recyclerView;
    @BindView(R.id.mainNotification_noNotificationTxt)
    TextView mainNotification_noNotificationTxt;
    @BindView(R.id.mainNotification_progressBar)
    ProgressBar mainNotification_progressBar;
    @BindView(R.id.newsPageLoadLay)
    RelativeLayout newsPageLoadLay;
    private Context context;
    private List<Datum> model = new ArrayList<>();
    public static NotificationListAdapter notificationListAdapter;
    private SharedPrefrencesHandler prefrencesHandler;
    private String token = "";
    private LinearLayoutManager layoutManager;

    public NotificationAllFrag() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_notification_all, container, false);

        //Initialize
        ButterKnife.bind(this, view);
        context = getActivity();
        notificationListAdapter = new NotificationListAdapter(context, model);
        prefrencesHandler = new SharedPrefrencesHandler(context);
        layoutManager = new LinearLayoutManager(context);
        //RecyclerView
        mainNotification_recyclerView.setLayoutManager(layoutManager);
        mainNotification_recyclerView.setHasFixedSize(true);

        //Get token
        token = prefrencesHandler.getFromShared(SharedPrefrencesKeys.TOKEN.name());
        // Lazy loader
        newsPageLoadLay.setVisibility(View.GONE);
        mainNotification_recyclerView.setOnScrollListener(new EndlessRecyclerLinearPage1(layoutManager) {
            @Override
            public void onLoadMore(int current_page) {
                ExploreSendData sendData = new ExploreSendData();
                sendData.setPageIndex(current_page);
                sendData.setPageSize(10);
                sendData.setShowFollows(true);
                sendData.setShowMovies(false);
                sendData.setShowNews(false);
                sendData.setShowReplies(true);
                sendData.setShowSeries(false);
                sendData.setShowSuggestions(true);

                newsPageLoadLay.setVisibility(View.VISIBLE);

                InterfaceApi api = ApiClient.getClient().create(InterfaceApi.class);
                Call<ExploreResponse> call = api.getExplore(token, sendData);

                call.enqueue(new Callback<ExploreResponse>() {
                    @Override
                    public void onResponse(Call<ExploreResponse> call, Response<ExploreResponse> response) {
                        if (response.body().getData() != null && response.body().getStatusCode() != 401
                                && response.body().getStatusCode() != 402) {
                            if (response.body().getData().size() > 0) {
                                notificationListAdapter.addNewItem(response.body().getData());
                                //Gone no explore
                                newsPageLoadLay.setVisibility(View.GONE);
                            }
                        } else {
                            prefrencesHandler.remove(SharedPrefrencesKeys.TOKEN.name());
                            startActivity(new Intent(context, LoginActivity.class));
                        }

                        newsPageLoadLay.setVisibility(View.GONE);
                    }

                    @Override
                    public void onFailure(Call<ExploreResponse> call, Throwable t) {
                        newsPageLoadLay.setVisibility(View.GONE);
                    }
                });
            }
        });

        getData(getActivity());

        return view;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser){
            getData(getActivity());
        }
    }

    public void getData(final Context context) {
        ExploreSendData sendData = new ExploreSendData();
        sendData.setPageIndex(1);
        sendData.setPageSize(10);
        sendData.setShowFollows(true);
        sendData.setShowMovies(false);
        sendData.setShowNews(false);
        sendData.setShowReplies(true);
        sendData.setShowSeries(false);
        sendData.setShowSuggestions(true);

        mainNotification_progressBar.setVisibility(View.VISIBLE);

        InterfaceApi api = ApiClient.getClient().create(InterfaceApi.class);
        Call<ExploreResponse> call = api.getExplore(
                new SharedPrefrencesHandler(context).getFromShared(SharedPrefrencesKeys.TOKEN.name()), sendData);

        call.enqueue(new Callback<ExploreResponse>() {
            @Override
            public void onResponse(Call<ExploreResponse> call, Response<ExploreResponse> response) {
                if (response.body().getData() != null && response.body().getStatusCode() != 401
                        && response.body().getStatusCode() != 402) {
                    if (response.body().getData().size() > 0) {
                        model.clear();
                        model.addAll(response.body().getData());
                        notificationListAdapter.notifyDataSetChanged();
                        mainNotification_recyclerView.setAdapter(notificationListAdapter);
                        //Gone no explore
                        mainNotification_noNotificationTxt.setVisibility(View.GONE);

                    } else {
                        mainNotification_noNotificationTxt.setVisibility(View.VISIBLE);
                        mainNotification_recyclerView.setVisibility(View.GONE);
                    }
                } else {
                    prefrencesHandler.remove(SharedPrefrencesKeys.TOKEN.name());
                    startActivity(new Intent(context, LoginActivity.class));
                }

                mainNotification_progressBar.setVisibility(View.GONE);
            }

            @Override
            public void onFailure(Call<ExploreResponse> call, Throwable t) {
                mainNotification_progressBar.setVisibility(View.GONE);
            }
        });
    }

How can I fix it? Please help

user1506104
  • 6,554
  • 4
  • 71
  • 89
  • I guess the visibility method is called before the actual view of the fragment is made which leaves you with the exception. Try a different approach on when the fragment is visible or not. – Sarthak Gandhi Oct 10 '17 at 06:24
  • you can write logic inside setUserVisibleHint() method because that method call before onCreateView. otherwise you can set handler and delay getData() method for some time – Mahesh Vayak Oct 10 '17 at 06:26
  • 1
    i would suggest you to call the getData method in onCreateView itself after all the views are initialized – Sarthak Gandhi Oct 10 '17 at 06:27
  • else if you are switching fragments then what you can do is create an interface implement it on the fragment and call the interface method whenever you are switching the fragment from your activity – Sarthak Gandhi Oct 10 '17 at 06:28
  • @MaheshVayak, I write Handler code and set 5s , but after 5s again show me error –  Oct 10 '17 at 06:30
  • `setUserVisibleHint` is used for when the fragment are visible to user or not , for example when you are switching the multiple fragments in the view pager and u need to load the data in the `onCreateView` or `onViewCreated` – Ko Vartthan Oct 10 '17 at 06:44
  • U can check your adapter , getItemCount and everyThing – Ko Vartthan Oct 10 '17 at 06:46
  • @KoVartthan, can you send to me your skype ID my bro? –  Oct 10 '17 at 06:48
  • I cant use skype right now @Gone , u can ask your doubts here , post your code fully for clear reference – Ko Vartthan Oct 10 '17 at 06:53

4 Answers4

1

it seems that setUserVisibleHint() called before onCreateView()

watch this link

kam.r
  • 61
  • 6
1

that is not proper solution but it 100% working

 @Override
 public void setUserVisibleHint(boolean isVisibleToUser) {
     super.setUserVisibleHint(isVisibleToUser);
     if (isVisibleToUser && mainNotification_recyclerView!=null){
         getData(getActivity());
     }
 }



 @Override
 public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
     super.onViewCreated(view, savedInstanceState);
     if (getUserVisibleHint()) {
         getData(getActivity());
     }
 }

it was work with multiple or single tab when user was go on tab that time initialize data

it can help to load data faster even load in all fragment at same time

vishal
  • 542
  • 6
  • 12
1

Try this

We should know that setUserVisibleHint is loaded before onCreateView .

private boolean isVisible = false;
private View view;

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        isVisible = true;
        onVisible();
    }
}

// onVisible method
private void onVisible() {
    // edited here 
    if (isVisible && view != null && mainNotification_progressBar != null) {
        getData(getActivity());
    }
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_notification_all, container, false);
    // add ButterKnife here
    ButterKnife.bind(this, view);
    onVisible();
    return view;
}
KeLiuyue
  • 8,149
  • 4
  • 25
  • 42
0

Try this one

 @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser){
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                getData(getActivity());
            }
        },3000);

    }
}

Hope this help you...if you need any help you can ask

Mahesh Vayak
  • 1,056
  • 12
  • 25