How to limit this swipe refresh if its only at top?

Related searches

This is my code which I used to make my data fetched from my data base in form of a list.But it is refreshing at all time when scroll down after a scrolled up for an instant . I need to make the refresh avail only when it is at top.

 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.ListView;
 import android.widget.ProgressBar;
 import android.widget.TextView;

 import com.shuan.Project.R;
 import com.shuan.Project.Utils.Common;
 import com.shuan.Project.adapter.ConnectAdapter;
 import com.shuan.Project.asyncTasks.GetHome;
 import com.shuan.Project.asyncTasks.GetPost;
 import com.shuan.Project.employer.PostViewActivity;
 import com.shuan.Project.list.Sample;

 import java.util.ArrayList;
 import java.util.HashMap;

public class OffersFragment extends Fragment {


   private ArrayList<Sample> list;
   private ConnectAdapter adapter;
private ListView listView;
private HashMap<String, String> cData;
private Common mApp;
private Context mContext;
private ProgressBar progressBar;
private SwipeRefreshLayout swipe;


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


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment

    mContext=getActivity();
    mApp= (Common) mContext.getApplicationContext();
    View view = inflater.inflate(R.layout.fragment_employer_home, container, false);

    swipe = (SwipeRefreshLayout) view.findViewById(R.id.swipe);
    listView = (ListView) view.findViewById(R.id.post);
    progressBar = (ProgressBar) view.findViewById(R.id.progress_bar);

    list = new ArrayList<Sample>();

    new GetPost(getActivity(), listView, progressBar, mApp.getPreference().getString(Common.u_id,""),"all", swipe).execute();


    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            TextView txt = (TextView) view.findViewById(R.id.jId);
            TextView txt1= (TextView) view.findViewById(R.id.frm_id);
            Intent in=new Intent(getActivity(),PostViewActivity.class);
            in.putExtra("jId",txt.getText().toString());
            in.putExtra("frmId",txt1.getText().toString());
            in.putExtra("apply","no");
            startActivity(in);
        }
    });
    swipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            new GetHome(getActivity(), listView, progressBar, mApp.getPreference().getString(Common.u_id, ""), "all",swipe).execute();
        }
    });

    return view;
   }

 }

my xml file

   <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipe"
android:layout_width="match_parent"
android:layout_height="match_parent">

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.shuan.Project.fragment.ConnectionFragment">


    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

    <ListView
        android:id="@+id/post"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@null"
        android:visibility="gone" />
</RelativeLayout>

Change your xml layout so SwipeRefreshLayout only wrap a scrollable view (your case the ListView).

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.shuan.Project.fragment.ConnectionFragment">

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ListView
            android:id="@+id/post"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@null"
            android:visibility="gone" />
    </android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>

Android swipe to refresh, only at the top of the list , One minor issue I had with using the standard Android ListView for a SwipeRefreshLayout was that it kept refreshing, even when the user was� Works for me. I had two LinearLayouts and ExpandlableListView in SwipeRefreshLayout and it refreshed everytime I swiped up. Once the SwipeRefreshLayout wraps only the ListView, the refresh event is triggered only on top. Mark this as correct answer! :) – Klemikaze Apr 7 at 8:43

    <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.enhancedListView.EnhancedListView
        android:id="@+id/listaNoticias"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="6dp"
        android:layout_marginRight="6dp"
        android:layout_marginTop="5dp" >
    </com.enhancedListView.EnhancedListView>

</android.support.v4.widget.SwipeRefreshLayout>


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

    // Inflate the layout for this fragment
    view = inflater.inflate(R.layout.principal, container, false);

    swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
    swipeLayout.setOnRefreshListener(this);
    swipeLayout.setColorSchemeColors(android.R.color.holo_green_dark, 
            android.R.color.holo_red_dark, 
            android.R.color.holo_blue_dark, 
            android.R.color.holo_orange_dark); (...)

@Override
public void onRefresh() {
    new myTask().execute();     
}

Adding Swipe-to-Refresh To Your App, Remember that SwipeRefreshLayout only supports a single ListView or If the layout contains a ListView with the ID "@android:id/list" , the� Supporting swipe to refresh Android provides a widget that implements the swipe-to-refresh design pattern, which allows the user to trigger an update with a vertical swipe. This is implemented by the SwipeRefreshLayout widget, which detects the vertical swipe, displays a distinctive progress bar, and triggers callback methods in your app.

I found my own solution for the question above. We can solve the issue by change the above code like below.

 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AbsListView;
 import android.widget.AdapterView;
 import android.widget.ListView;
 import android.widget.ProgressBar;
 import android.widget.TextView;

 import com.shuan.Project.R;
 import com.shuan.Project.Utils.Common;
 import com.shuan.Project.adapter.ConnectAdapter;
 import com.shuan.Project.asyncTasks.GetHome;
 import com.shuan.Project.asyncTasks.GetPost;
 import com.shuan.Project.employer.PostViewActivity;
 import com.shuan.Project.list.Sample;

 import java.util.ArrayList;
 import java.util.HashMap;

 public class OffersFragment extends Fragment implements AbsListView.OnScrollListener {


private ArrayList<Sample> list;
private ConnectAdapter adapter;
private ListView listView;
private HashMap<String, String> cData;
private Common mApp;
private Context mContext;
private ProgressBar progressBar;
private SwipeRefreshLayout swipe;
private int preLast;


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


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment

    mContext=getActivity();
    mApp= (Common) mContext.getApplicationContext();
    View view = inflater.inflate(R.layout.fragment_employer_home, container, false);

    swipe = (SwipeRefreshLayout) view.findViewById(R.id.swipe);
    listView = (ListView) view.findViewById(R.id.post);
    progressBar = (ProgressBar) view.findViewById(R.id.progress_bar);

    list = new ArrayList<Sample>();

    new GetPost(getActivity(), listView, progressBar, mApp.getPreference().getString(Common.u_id,""),"all", swipe).execute();


    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            TextView txt = (TextView) view.findViewById(R.id.jId);
            TextView txt1= (TextView) view.findViewById(R.id.frm_id);
            Intent in=new Intent(getActivity(),PostViewActivity.class);
            in.putExtra("jId",txt.getText().toString());
            in.putExtra("frmId",txt1.getText().toString());
            in.putExtra("apply","no");
            startActivity(in);
        }
    });
    listView.setOnScrollListener(this);
    swipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            new GetHome(getActivity(), listView, progressBar, mApp.getPreference().getString(Common.u_id, ""), "all",swipe).execute();
        }
    });

    return view;
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {

}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    if (view.getId() == R.id.post) {
        if (firstVisibleItem == 0) {
            swipe.setEnabled(true);
            int lastItem = firstVisibleItem + visibleItemCount;
            if (lastItem == totalItemCount) {
                if (preLast != lastItem) {
                    preLast = lastItem;
                    //Toast.makeText(getActivity(), "In Last", Toast.LENGTH_SHORT).show();
                }

            }else{

            }
        } else {
            swipe.setEnabled(false);
        }
    }
  }
}

Implementing Pull to Refresh Guide, SwipeRefreshLayout is a ViewGroup that can hold only one scrollable view as a is responsible for correctly determining when to actually initiate a refresh of its the top setContentView(R.layout.activity_main); // Lookup the swipe container� To add the swipe to refresh widget to an existing app, add SwipeRefreshLayout as the parent of a single ListView or GridView. Remember that SwipeRefreshLayout only supports a single ListView or GridView child. The following example demonstrates how to add the SwipeRefreshLayout widget to an existing layout file containing a ListView:

This is a bit old, but in 2019 this is the correct answer: you have to include RecyclerView inside of NestedScrollView in order for SwipeRefreshLayout to behave properly, like this:

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:id="@+id/swipeRefreshLayout"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

Android SwipeRefreshLayout Tutorial, We talked about a custom implementation of this refresh pattern in this post where we by the SDK and it is already used in some App provided by Android ( i.e Gmail). Android SwipeRefreshLayout component accepts only one child: the It allows to call the refresh method only when you are at the top of your listView. Android SwipeRefreshLayout is a ViewGroup that can hold only one scrollable child. It can be either a ScrollView, ListView or RecyclerView. The basic need for a SwipeRefreshLayout is to allow the users to refresh the screen manually. This is pretty common in the Facebook Newsfeed screen.

add this lines of code note : LinearLayoutManager should be define separately

mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mLayoutManager = new LinearLayoutManager(getActivity());    
mRecyclerView.setLayoutManager(mLayoutManager);       
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);


      mSwipeRefreshLayout.setEnabled
(mLinearLayoutManager.findFirstCompletelyVisibleItemPosition() == 0);
}
});

findFirstCompletelyVisibleItemPosition() == 0 means at the top of recyclerview

Android SwipeRefreshLayout, Android SwipeRefreshLayout is used for pull down to refresh or Swipe down to Android SwipeRefreshLayout is a ViewGroup that can hold only one consists of a ListView that on swipe down, refreshes the screen and shuffles the list rows. in your case it's greyish but in my case it's orange i want to change it to blue. Now we have all the required files in place, let’s start implementing the actual swipe refresh view. Open the layout file of your main activity (activity_main.xml) and modify the layout as shown below. I have added a ListView to show list of movies and wrapped it around SwipeRefreshLayout to get the swipe to refresh.

This Medium article is a short tutorial about Android development and how to quickly implement a Pull To Refresh feature in your app. SwipeRefreshLayout is very easy to use, I will show you how !

A little swipe down will trigger the SwipeRefreshLayout refresh too. I want to set a limit to when horizontal swipe starts, then force horizontal only until swiping is over. In other words, I want to cancel vertical swipping when finger is moving horizontally.

Comments
  • add you xml file to question'
  • I am using the same xml file in my home too ,but no issues there. There i have written onscroll function
  • So there is actually an issue but you tackle it by writing codes inside onScroll method and listen whether the list reaches the top, then run the refresh method. Sometimes we need that hack (For example if there are more than one scrollable views) , but in your case, you just have to put the SwipeRefreshLayout to wrap ListView only and they will do the job for you.
  • Works for me. I had two LinearLayouts and ExpandlableListView in SwipeRefreshLayout and it refreshed everytime I swiped up. Once the SwipeRefreshLayout wraps only the ListView, the refresh event is triggered only on top. Mark this as correct answer! :)