Google has recently published an update to its support library, which now has a new "SwipeRefreshLayout" view.
The view allows to wrap another view, while supporting swiping down in order to perform a refresh operation.
screenshot:
Google hasn't provided a sample (at least not one that I can find, yet), so I've tried using it myself.
At first I got a crash (NPE) whenever I swiped, but then I've found out that's because I didn't provide a "OnRefreshListener" for it.
But I still don't get how to use it, let alone customize it
Here's the XML of the layout file:
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.swiperefreshlayouttest.MainActivity" tools:ignore="MergeRootFrame" > <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TTT" android:textSize="40sp" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TTT" android:textSize="40sp" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TTT" android:textSize="40sp" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TTT" android:textSize="40sp" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TTT" android:textSize="40sp" /> </LinearLayout> </ScrollView> </android.support.v4.widget.SwipeRefreshLayout>
Code, though it doesn't do anything special at all:
public class MainActivity extends ActionBarActivity { @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final SwipeRefreshLayout swipeRefreshLayout=(SwipeRefreshLayout)findViewById(R.id.container); swipeRefreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh() { // do nothing } }); } }
What is the correct way to use this view?
How do I customize it? Currently it's just a black line...
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.
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.
If an activity wishes to show just the progress animation, it should call setRefreshing(true). To disable the gesture and progress animation, call setEnabled(false) on the view.
The SwipeRefreshLayout is a widget that detects vertical swipe, shows a simple progress bar and then triggers a callback so that developers can fetch the data or do some other task in our android app. Step 1: Create a new Project
Swipe refresh layout is a ViewGroup with the particularity that it can only hold one scrollable view as a children. It is basically a layout decorator that manages touch events and shows an indeterminate progress animation below the action bar when the user swipes down. The effect is similar to the one seen in Google Now app.
To add a dependency on SwipeRefreshLayout, you must add the Google Maven repository to your project. Read Google's Maven repository for more information. Add the dependencies for the artifacts you need in the build.gradle file for your app or module: For more information about dependencies, see Add build dependencies.
You can also use the SwipeRefreshLayout widget with a ListFragment. If the layout contains a ListView with the ID "@android:id/list", the swipe-to-refresh functionality is automatically supported. However, explicitly declaring the ListView in this way supersedes the default ListFragment view structure.
I don't know what that ActionBarActivity
class you're extending is, but I got it working just fine using a FragmentActivity
public class ActivityMain extends FragmentActivity implements OnRefreshListener { private SwipeRefreshLayout mSwipeRefreshLayout; @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.container); mSwipeRefreshLayout.setOnRefreshListener(this); super.onCreate(savedInstanceState); } @Override public void onRefresh() { Toast.makeText(this, "Refresh", Toast.LENGTH_SHORT).show(); new Handler().postDelayed(new Runnable() { @Override public void run() { mSwipeRefreshLayout.setRefreshing(false); } }, 2000); } }
Worth Pointing out I copy pasted your xml layout exactly as it is
In terms of customization, there's really not much you can do other than change the color of the colored bar by calling setColorScheme(int colorResId, int colorResId, int colorResId, int colorResId);
e.g.
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="blue">#0099CC</color> <color name="purple">#9933CC</color> <color name="green">#669900</color> <color name="orange">#FF8800</color> </resources>
mSwipeRefreshLayout.setColorScheme(R.color.blue, R.color.purple, R.color.green, R.color.orange);
It's kind of a disappointing addition really. The sensitivity on the refresh is fairly high and there is no setting to change it
Edit
I wrote this when this class (and the ActionBarActivity
class) had just been added to the sdk. As such, some things have changed from when I wrote this answer. Furthermore, the type of Activity you use should not affect this solution.
setColorScheme
is now deprecated, setColorSchemeResources(int... colorResIds)
should be used instead. (you can put as many color ids in there as you like).
setDistanceToTriggerSync(int distance)
can also be used to set how far down a user needs to swipe in order to trigger a refresh.
I recommend checking out the official documentation to see what else the class has to offer.
MainActivity.java
public class MainActivity extends ActionBarActivity { TextView textView; private SwipeRefreshLayout mSwipeRefreshLayout; static int count = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.scrollTextView); // /You will setup the action bar with pull to refresh layout mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.container); mSwipeRefreshLayout.setColorScheme(R.color.blue, R.color.green, R.color.orange, R.color.purple); mSwipeRefreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh() { Log.e(getClass().getSimpleName(), "refresh"); new GetLinks().execute(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } public class GetLinks extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(Void... params) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); //Here you can update the view textView.setText(textView.getText().toString()+"--New Content Added" + ++count); // Notify swipeRefreshLayout that the refresh has finished mSwipeRefreshLayout.setRefreshing(false); } } }
activity_main.xml
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" > <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/scrollTextView" android:text="TTT" android:textSize="40sp" /> </ScrollView> </android.support.v4.widget.SwipeRefreshLayout>
colors.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <item name="blue" type="color">#FF33B5E5</item> <item name="purple" type="color">#FFAA66CC</item> <item name="green" type="color">#FF99CC00</item> <item name="orange" type="color">#FFFFBB33</item> </resources>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With