Home > front end >  Swipe to refresh data using SwipeRefreshLayout in fragment?
Swipe to refresh data using SwipeRefreshLayout in fragment?

Time:05-11

I want my layout to be refreshed when the app starts and the data should show in and when the user swipes the data should be updated and show new data if new data is available on the server.

The actual problem is that the data is not loading when the app is started. Rather it is happening only on swiping. How can I achieve that on opening the app the data is loaded first and then the data is updated on swiping?

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = FragmentFirstBinding.inflate(inflater, container, false);
        MyAdapter adapter = new MyAdapter(list,getContext());
        binding.myRecyclerView.setAdapter(adapter);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(),2);
        binding.myRecyclerView.setLayoutManager(gridLayoutManager);
        interfaces = RetrofitInstance.getRetrofit().create(APIInterfaces.class);
        binding.swipeToRefresh.setRefreshing(true);
        binding.swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                interfaces.getPosts().enqueue(new Callback<List<VideoModels>>() {
                    @SuppressLint("NotifyDataSetChanged")
                    @Override
                    public void onResponse(@NonNull Call<List<VideoModels>> call, @NonNull Response<List<VideoModels>> response) {
                        list.clear();
                        if (response.isSuccessful()) {
                            assert response.body() != null;
                            list.addAll(response.body());
                            adapter.notifyDataSetChanged();
                            binding.swipeToRefresh.setRefreshing(false);
                        }
                    }

                    @Override
                    public void onFailure(@NonNull Call<List<VideoModels>> call, @NonNull Throwable t) {
                        Toast.makeText(getContext(), "Check you Internet", Toast.LENGTH_SHORT).show();
                        binding.swipeToRefresh.setRefreshing(false);
                    }
                });
            }
        });
        binding.swipeToRefresh.setRefreshing(false);

        return binding.getRoot();
    }

Your answer will helpful for me.

CodePudding user response:

You need to call this method in onResume() state

  public void getData() {
            interfaces.getPosts().enqueue(new Callback<List<VideoModels>>() {
                @SuppressLint("NotifyDataSetChanged")
                @Override
                public void onResponse(@NonNull Call<List<VideoModels>> call, @NonNull Response<List<VideoModels>> response) {
                    list.clear();
                    if (response.isSuccessful()) {
                        assert response.body() != null;
                        list.addAll(response.body());
                        adapter.notifyDataSetChanged();
                        binding.swipeToRefresh.setRefreshing(false);
                    }
                }

                @Override
                public void onFailure(@NonNull Call<List<VideoModels>> call, @NonNull Throwable t) {
                    Toast.makeText(getContext(), "Check you Internet", Toast.LENGTH_SHORT).show();
                    binding.swipeToRefresh.setRefreshing(false);
                }
            });
        }

CodePudding user response:

if you call binding.swipeLayout.isRefreshing = true
in SwipeRefreshLayout source code, mNotify boolean value is false so cannot do anything in setOnRefreshListener

public void onAnimationEnd(Animation animation) {
        if (mRefreshing) {
            // Make sure the progress view is fully visible
            mProgress.setAlpha(MAX_ALPHA);
            mProgress.start();
            if (mNotify) {
                if (mListener != null) {
                    mListener.onRefresh();
                }
            }
            mCurrentTargetOffsetTop = mCircleView.getTop();
        } else {
            reset();
        }
    }

this is why setOnRefreshListener not invoke if you want manual invoke it do like this by reflect set mNotify boolean value is true

val swipeClass = SwipeRefreshLayout::class.java
val method = swipeClass.getDeclaredMethod("setRefreshing", Boolean::class.java, Boolean::class.java)
method.isAccessible = true
method.invoke(binding.swipeLayout, true, true)
  • Related