Showing posts with label Android code sample: SwipeRefreshLayout. Show all posts
Showing posts with label Android code sample: SwipeRefreshLayout. Show all posts

Friday, May 20, 2016

SwipeRefreshLayout, work with RecyclerView


Last two post show "Simple example of using SwipeRefreshLayout" and "SwipeRefreshLayout, refresh in background thread", target to ListView.

This example show how SwipeRefreshLayout work with RecyclerView (reference: step-by-step of using RecyclerView).


To use RecyclerView in your Android Studio project, you have to Add Support Libraries of RecyclerView as dependencies.


Create layout/layout_item.xml, to define the layout of RecyclerView item.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="28dp"/>

</LinearLayout>

Create a new class, RecyclerViewAdapter.java.
package com.blogspot.android_er.androidswiperefresh;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ItemHolder>{

    private List<String> itemsList;
    private OnItemClickListener onItemClickListener;
    private LayoutInflater layoutInflater;

    public RecyclerViewAdapter(Context context){
        layoutInflater = LayoutInflater.from(context);
        itemsList = new ArrayList<String>();
    }

    @Override
    public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = layoutInflater.inflate(R.layout.layout_item, parent, false);
        return new ItemHolder(itemView, this);
    }

    @Override
    public void onBindViewHolder(ItemHolder holder, int position) {
        holder.setItemText(itemsList.get(position));
    }

    @Override
    public int getItemCount() {
        return itemsList.size();
    }

    public void setOnItemClickListener(OnItemClickListener listener){
        onItemClickListener = listener;
    }

    public OnItemClickListener getOnItemClickListener(){
        return onItemClickListener;
    }

    public interface OnItemClickListener{
        public void onItemClick(ItemHolder item, int position);
    }

    public void add(int location, String iString){
        itemsList.add(location, iString);
        notifyItemInserted(location);
    }

    public void set(int location, String iString){
        itemsList.set(location, iString);
        notifyItemChanged(location);
    }

    public void clear(){
        itemsList.clear();
        notifyDataSetChanged();
    }

    public static class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        private RecyclerViewAdapter parent;
        TextView textItemText;

        public ItemHolder(View itemView, RecyclerViewAdapter parent) {
            super(itemView);
            itemView.setOnClickListener(this);
            this.parent = parent;
            textItemText = (TextView) itemView.findViewById(R.id.item_text);
        }

        public void setItemText(CharSequence itemString){
            textItemText.setText(itemString);
        }

        public CharSequence getItemText(){
            return textItemText.getText();
        }

        @Override
        public void onClick(View v) {
            final OnItemClickListener listener = parent.getOnItemClickListener();
            if(listener != null){
                listener.onItemClick(this, getAdapterPosition());
            }
        }
    }
}


Modify layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidswiperefresh.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <Button
        android:id="@+id/clearall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Clear All"/>

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

        <android.support.v7.widget.RecyclerView
            android:id="@+id/myrecyclerview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

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

</LinearLayout>


MainActivity.java
package com.blogspot.android_er.androidswiperefresh;

import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.text.DateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.OnItemClickListener{

    SwipeRefreshLayout swipeRefreshLayout;
    Button btnClearAll;

    private RecyclerView myRecyclerView;
    private LinearLayoutManager linearLayoutManager;
    private RecyclerViewAdapter myRecyclerViewAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swiperefreshlayout);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refresh();
            }
        });
        btnClearAll = (Button)findViewById(R.id.clearall);
        btnClearAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //In order to prevent the racing condition of updating removed item in refreshing,
                //disable "Clear All" if refreshing
                if(!swipeRefreshLayout.isRefreshing()){
                    myRecyclerViewAdapter.clear();
                }
            }
        });

        myRecyclerView = (RecyclerView)findViewById(R.id.myrecyclerview);
        linearLayoutManager =
                new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        myRecyclerViewAdapter = new RecyclerViewAdapter(this);
        myRecyclerViewAdapter.setOnItemClickListener(this);
        myRecyclerView.setAdapter(myRecyclerViewAdapter);
        myRecyclerView.setLayoutManager(linearLayoutManager);

    }

    private void refresh(){

        final int pos = myRecyclerViewAdapter.getItemCount();
        myRecyclerViewAdapter.add(pos, "Refreshing...");
        swipeRefreshLayout.setRefreshing(true);

        //refresh long-time task in background thread
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //dummy delay for 2 second
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //update ui on UI thread
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        String currentDateTime =
                                DateFormat.getDateTimeInstance().format(new Date());

                        myRecyclerViewAdapter.set(pos, pos + " - " + currentDateTime);
                        swipeRefreshLayout.setRefreshing(false);
                    }
                });

            }
        }).start();
    }

    @Override
    public void onItemClick(RecyclerViewAdapter.ItemHolder item, int position) {
        Toast.makeText(this,
                position + " : " + item.getItemText(),
                Toast.LENGTH_SHORT).show();
    }
}



download filesDownload the files .

Thursday, May 19, 2016

SwipeRefreshLayout, refresh in background thread


Last post show a basic example of SwipeRefreshLayout. But, normally refreshing involve some longtime task; such as loading data from Internet. This example show how to refresh with longtime task in background thread.


MainActivity.java
package com.blogspot.android_er.androidswiperefresh;

import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    SwipeRefreshLayout swipeRefreshLayout;
    ListView swipeList;

    List<String> myList;
    ListAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swiperefreshlayout);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refresh();
            }
        });

        swipeList = (ListView)findViewById(R.id.swipelist);

        myList = new ArrayList<>();
        adapter = new ArrayAdapter<String>(
                this, android.R.layout.simple_list_item_1, myList);
        swipeList.setAdapter(adapter);

        swipeList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String item = (String) parent.getItemAtPosition(position);
                Toast.makeText(MainActivity.this, item, Toast.LENGTH_LONG).show();
            }
        });
    }

    private void refresh(){

        final int pos = myList.size();
        myList.add(pos, "Refreshing...");
        swipeList.invalidateViews();
        swipeRefreshLayout.setRefreshing(true);

        //refresh long-time task in background thread
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //dummy delay for 2 second
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //update ui on UI thread
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        String currentDateTime =
                                DateFormat.getDateTimeInstance().format(new Date());
                        myList.set(pos, pos + " - " + currentDateTime);
                        swipeList.invalidateViews();
                        swipeRefreshLayout.setRefreshing(false);
                    }
                });

            }
        }).start();
    }
}


Keep using the layout in last post.

more:
SwipeRefreshLayout, work with RecyclerView

Wednesday, May 18, 2016

Swipe-to-Refresh ListView using SwipeRefreshLayout


With android.support.v4.widget.SwipeRefreshLayout, user can refresh the contents of a view via a vertical swipe gesture. This example show how to implement Swipe-to-Refresh ListView using SwipeRefreshLayout.


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidswiperefresh.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

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

</LinearLayout>


MainActivity.java
package com.blogspot.android_er.androidswiperefresh;

import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    SwipeRefreshLayout swipeRefreshLayout;
    ListView swipeList;

    List<String> myList;
    ListAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swiperefreshlayout);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refresh();
            }
        });

        swipeList = (ListView)findViewById(R.id.swipelist);

        myList = new ArrayList<>();
        adapter = new ArrayAdapter<String>(
                this, android.R.layout.simple_list_item_1, myList);
        swipeList.setAdapter(adapter);
    }

    private void refresh(){
        //insert dummy string of current date/time
        String currentDateTime = DateFormat.getDateTimeInstance().format(new Date());
        myList.add(currentDateTime);
        swipeList.invalidateViews();
        swipeRefreshLayout.setRefreshing(false);
    }
}


In this example, the ListView items is updated in SwipeRefreshLayout.OnRefreshListener(). But normally refreshing involve longtime task, such as loading from Internet. The next example show how to refresh with longtime task run in background thread.


Wednesday, July 16, 2014

Set color scheme of the progress animation in SwipeRefreshLayout

The methods setColorSchemeColors (int color1, int color2, int color3, int color4) and setColorSchemeResources(int colorRes1, int colorRes2, int colorRes3, int colorRes4) of SwipeRefreshLayout set the four colors used in the progress animation. The first color will also be the color of the bar that grows in response to a user swipe gesture.


package com.example.androidswiperefresh;

import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.support.v7.app.ActionBarActivity;
import android.widget.TextView;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;

public class MainActivity extends ActionBarActivity {
 
 SwipeRefreshLayout swipeRefreshLayout;
 TextView textInfo;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  textInfo = (TextView)findViewById(R.id.info);
  
  swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipelayout);
  swipeRefreshLayout.setOnRefreshListener(onRefreshListener);
  
  swipeRefreshLayout.setColorSchemeColors(
   Color.RED, Color.GREEN, Color.BLUE, Color.CYAN);
 }
 
 OnRefreshListener onRefreshListener = new OnRefreshListener(){

  @Override
  public void onRefresh() {
   textInfo.setText("WAIT: doing something");
   
   //simulate doing something
   new Handler().postDelayed(new Runnable() {

    @Override
    public void run() {
     swipeRefreshLayout.setRefreshing(false);
     textInfo.setText("DONE");
    }

   }, 2000);
  }};
}

Use the same layout file in last exercise of SwipeRefreshLayout example.

Tuesday, July 15, 2014

SwipeRefreshLayout example

android.support.v4.widget.SwipeRefreshLayout can be used to detect user's vertical swipe gesture, to refresh the contents. It is a simple example of SwipeRefreshLayout, to detect user swipe to do something.


Layout, /res/layout/activity_main.xml.
<LinearLayout 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"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidswiperefresh.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipelayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#A0A0A0" >

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

            <TextView
                android:id="@+id/info"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
            
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/ic_launcher"/>
            
        </LinearLayout>
        
    </android.support.v4.widget.SwipeRefreshLayout>

</LinearLayout>


MainActivity.java
package com.example.androidswiperefresh;

import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.support.v7.app.ActionBarActivity;
import android.widget.TextView;
import android.os.Bundle;
import android.os.Handler;

public class MainActivity extends ActionBarActivity {
 
 SwipeRefreshLayout swipeRefreshLayout;
 TextView textInfo;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  textInfo = (TextView)findViewById(R.id.info);
  
  swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipelayout);
  swipeRefreshLayout.setOnRefreshListener(onRefreshListener);
 }
 
 OnRefreshListener onRefreshListener = new OnRefreshListener(){

  @Override
  public void onRefresh() {
   textInfo.setText("WAIT: doing something");
   
   //simulate doing something
   new Handler().postDelayed(new Runnable() {

    @Override
    public void run() {
     swipeRefreshLayout.setRefreshing(false);
     textInfo.setText("DONE");
    }

   }, 2000);
  }};
}


Next: Set color scheme of the progress animation in SwipeRefreshLayout