Showing posts with label Android code sample: Detecting Gestures. Show all posts
Showing posts with label Android code sample: Detecting Gestures. Show all posts

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.


Monday, May 16, 2016

Implement ScaleGestureDetector on individual ImageView


Last example show Implementing ScaleGestureDetector on whole activity screen, to set scale of a ImageView. Now we modify to apply ScaleGestureDetector to individual ImageView, to scale the selected ImageView only.


Remark:
It can be noticed in the video, pinch-to-zoom cannot be detect after sometimes - I don't know why, but tap-and-slide still function as expected.

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

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    ImageView myImage1, myImage2;

    private ScaleGestureDetector scaleGestureDetector1, scaleGestureDetector2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myImage1 = (ImageView)findViewById(R.id.myimage1);
        myImage2 = (ImageView)findViewById(R.id.myimage2);

        scaleGestureDetector1 = new ScaleGestureDetector(
                this, new MySimpleOnScaleGestureListener(myImage1));
        scaleGestureDetector2 = new ScaleGestureDetector(
                this, new MySimpleOnScaleGestureListener(myImage2));

        myImage1.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                scaleGestureDetector1.onTouchEvent(event);
                return true;
            }
        });

        myImage2.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                scaleGestureDetector2.onTouchEvent(event);
                return true;
            }
        });
    }


    private class MySimpleOnScaleGestureListener
            extends ScaleGestureDetector.SimpleOnScaleGestureListener{

        ImageView viewMyImage;

        float factor;

        public MySimpleOnScaleGestureListener(ImageView iv) {
            super();
            viewMyImage = iv;
            factor = 1.0f;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {

            float scaleFactor = detector.getScaleFactor() - 1;
            factor += scaleFactor;
            viewMyImage.setScaleX(factor);
            viewMyImage.setScaleY(factor);
            return true;
            //return super.onScale(detector);
        }
    }
}


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.androidscalegesturedetector.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" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:background="@android:color/black">
        <ImageView
            android:id="@+id/myimage1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"
            android:background="#A00000"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:background="@android:color/darker_gray">
        <ImageView
            android:id="@+id/myimage2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"
            android:background="#0000A0"/>
    </LinearLayout>

</LinearLayout>


Implement pinch-to-zoom with ScaleGestureDetector


Last post show how to implement ScaleGestureDetector, this post show how to implement pinch-to-zoom on ImageView with ScaleGestureDetector.


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

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView textMsg;
    ImageView myImage;

    private ScaleGestureDetector scaleGestureDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textMsg = (TextView)findViewById(R.id.msg);
        myImage = (ImageView)findViewById(R.id.myimage);

        scaleGestureDetector = new ScaleGestureDetector(
                this, new MySimpleOnScaleGestureListener(textMsg, myImage));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        scaleGestureDetector.onTouchEvent(event);
        return true;
        //return super.onTouchEvent(event);
    }

    private class MySimpleOnScaleGestureListener
            extends ScaleGestureDetector.SimpleOnScaleGestureListener{

        TextView viewMessage;
        ImageView viewMyImage;

        float factor;

        public MySimpleOnScaleGestureListener(TextView v, ImageView iv) {
            super();
            viewMessage = v;
            viewMyImage = iv;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            factor = 1.0f;
            return true;
            //return super.onScaleBegin(detector);
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {

            float scaleFactor = detector.getScaleFactor() - 1;
            factor += scaleFactor;
            viewMessage.setText(String.valueOf(scaleFactor)
                    + "\n" + String.valueOf(factor));
            viewMyImage.setScaleX(factor);
            viewMyImage.setScaleY(factor);
            return true;
            //return super.onScale(detector);
        }
    }
}


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.androidscalegesturedetector.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" />
    <TextView
        android:id="@+id/msg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textSize="24sp"/>
    <ImageView
        android:id="@+id/myimage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>
</LinearLayout>


Next:
Implement ScaleGestureDetector on individual ImageView

Sunday, May 15, 2016

Android example: ScaleGestureDetector


android.view.ScaleGestureDetector detects scaling transformation gestures using the supplied MotionEvents. The ScaleGestureDetector.OnScaleGestureListener callback will notify users when a particular gesture event has occurred.


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

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView textMsg;

    private ScaleGestureDetector scaleGestureDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textMsg = (TextView)findViewById(R.id.msg);

        scaleGestureDetector = new ScaleGestureDetector(
                this, new MySimpleOnScaleGestureListener(textMsg));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        scaleGestureDetector.onTouchEvent(event);
        return true;
        //return super.onTouchEvent(event);
    }

    private class MySimpleOnScaleGestureListener
            extends ScaleGestureDetector.SimpleOnScaleGestureListener{

        TextView viewMessage;

        public MySimpleOnScaleGestureListener(TextView v) {
            super();
            viewMessage = v;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            float scaleFactor = detector.getScaleFactor();
            viewMessage.setText(String.valueOf(scaleFactor));
            return true;
            //return super.onScale(detector);
        }
    }
}


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.androidscalegesturedetector.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" />
    <TextView
        android:id="@+id/msg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textSize="24sp"/>
</LinearLayout>


Next:
Implement pinch-to-zoom with ScaleGestureDetector

Thursday, May 12, 2016

Detect user touch with GestureDetectorCompat


Android example to Detect user touch with GestureDetectorCompat:


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

import android.os.Bundle;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private GestureDetectorCompat gestureDetectorCompat;
    TextView textInfo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textInfo = (TextView)findViewById(R.id.info);

        gestureDetectorCompat = new GestureDetectorCompat(
                this, new MySimpleOnGestureListener(textInfo));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        gestureDetectorCompat.onTouchEvent(event);
        return super.onTouchEvent(event);
    }

    private class MySimpleOnGestureListener
            extends GestureDetector.SimpleOnGestureListener{

        TextView textView;


        public MySimpleOnGestureListener(TextView v) {
            super();
            textView = v;
        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            textView.append("\n- onSingleTapUp -");
            return super.onSingleTapUp(e);
        }

        @Override
        public void onLongPress(MotionEvent e) {
            textView.append("\n- onLongPress -");
            super.onLongPress(e);
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            textView.append("\n- onScroll -");
            return super.onScroll(e1, e2, distanceX, distanceY);
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            textView.append("\n- onFling -");
            return super.onFling(e1, e2, velocityX, velocityY);
        }

        @Override
        public void onShowPress(MotionEvent e) {
            textView.append("\n- onShowPress -");
            super.onShowPress(e);
        }

        @Override
        public boolean onDown(MotionEvent e) {
            textView.append("\n- onDown -");
            return super.onDown(e);
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            textView.append("\n- onDoubleTap -");
            return super.onDoubleTap(e);
        }

        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            textView.append("\n- onDoubleTapEvent -");
            return super.onDoubleTapEvent(e);
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            textView.append("\n- onSingleTapConfirmed -");
            return super.onSingleTapConfirmed(e);
        }

        @Override
        public boolean onContextClick(MotionEvent e) {
            textView.append("\n- onContextClick -");
            return super.onContextClick(e);
        }
    }
}


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.androidgesturedetector.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" />

    <TextView
        android:id="@+id/info"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom"
        android:textStyle="italic" />
</LinearLayout>


Tuesday, December 16, 2014

Swipe to Slide animated activity switching

Last post show how to detect Swipe to start another activity. In this post, animation of Slide-in/Slide-out are added in switching activity.


Create xml files of animation in /res/anim/ folder.

/res/anim/slide_left_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="500"
        android:fromXDelta="100%p"
        android:toXDelta="0" />

</set>

/res/anim/slide_left_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:toXDelta="-100%p" />

</set>

/res/anim/slide_right_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:toXDelta="100%p" />

</set>

/res/anim/slide_right_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="500"
        android:fromXDelta="-100%p"
        android:toXDelta="0" />

</set>

Modify onFling() of MyGestureListener of MainActivity.java in last post, to call overridePendingTransition() after startActivity().
        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, 
                float velocityX, float velocityY) {
            
         /*
         Toast.makeText(getBaseContext(), 
          event1.toString() + "\n\n" +event2.toString(), 
          Toast.LENGTH_SHORT).show();
         */
         
         if(event2.getX() < event1.getX()){
          Toast.makeText(getBaseContext(), 
           "Swipe left - startActivity()", 
           Toast.LENGTH_SHORT).show();
          
          //switch another activity
             Intent intent = new Intent(
               MainActivity.this, SecondActivity.class);
             startActivity(intent);
             overridePendingTransition(R.anim.slide_left_in, R.anim.slide_left_out);
         }

            return true;
        }

Modify onFling() of My2ndGestureListener of SecondActivity.java in last post, to call overridePendingTransition() after finish().
        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, 
                float velocityX, float velocityY) {
            
         /*
         Toast.makeText(getBaseContext(), 
          event1.toString() + "\n\n" +event2.toString(), 
          Toast.LENGTH_SHORT).show();
         */
         
         if(event2.getX() > event1.getX()){
          Toast.makeText(getBaseContext(), 
           "Swipe right - finish()", 
           Toast.LENGTH_SHORT).show();
          
          finish();
          overridePendingTransition(R.anim.slide_right_in, R.anim.slide_right_out);
         }

            return true;
        }

For /res/layout/activity_main.xml and AndroidManifest.xml refer to last post.

download filesDownload the files.

Saturday, December 13, 2014

Detect Gestures of Swipe to switch between activity

Example to detect Gestures of Swipe using GestureDetectorCompat, to switch between activity by override onFling() of GestureDetector.SimpleOnGestureListener.


In main activity, override onFling() to switch to SecondActivity if Swipe left Gestures detected.
package com.example.androidswipeactivity;

import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.Toast;
import android.content.Intent;
import android.os.Bundle;

public class MainActivity extends ActionBarActivity {
 
 private GestureDetectorCompat gestureDetectorCompat;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  gestureDetectorCompat = new GestureDetectorCompat(this, new MyGestureListener());
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  this.gestureDetectorCompat.onTouchEvent(event);
        return super.onTouchEvent(event);
 }

 class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
  //handle 'swipe left' action only

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, 
                float velocityX, float velocityY) {
            
         /*
         Toast.makeText(getBaseContext(), 
          event1.toString() + "\n\n" +event2.toString(), 
          Toast.LENGTH_SHORT).show();
         */
         
         if(event2.getX() < event1.getX()){
          Toast.makeText(getBaseContext(), 
           "Swipe left - startActivity()", 
           Toast.LENGTH_SHORT).show();
          
          //switch another activity
             Intent intent = new Intent(
               MainActivity.this, SecondActivity.class);
             startActivity(intent);
         }

            return true;
        }
    }
}

/res/layout/activity_main.xml, layout for MainActivity
<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:background="@color/background_material_dark"
    tools:context="com.example.androidswipeactivity.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" />
    
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/ic_launcher"/>

</LinearLayout>

SecondActivity.java, second activity, override onFling() to switch to finish() if Swipe right Gestures detected. It create ContentView using java code without xml.
package com.example.androidswipeactivity;

import android.os.Bundle;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.TextView;
import android.widget.Toast;

public class SecondActivity extends ActionBarActivity {
 
 private GestureDetectorCompat gestureDetectorCompat;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  TextView text2ndActivity = new TextView(this);
  text2ndActivity.setText("Second Activity");
  setContentView(text2ndActivity);
  
  gestureDetectorCompat = new GestureDetectorCompat(this, new My2ndGestureListener());
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  this.gestureDetectorCompat.onTouchEvent(event);
        return super.onTouchEvent(event);
 }

 class My2ndGestureListener extends GestureDetector.SimpleOnGestureListener {
  //handle 'swipe right' action only

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, 
                float velocityX, float velocityY) {
            
         /*
         Toast.makeText(getBaseContext(), 
          event1.toString() + "\n\n" +event2.toString(), 
          Toast.LENGTH_SHORT).show();
         */
         
         if(event2.getX() > event1.getX()){
          Toast.makeText(getBaseContext(), 
           "Swipe right - finish()", 
           Toast.LENGTH_SHORT).show();
          
          finish();
         }

            return true;
        }
    }

}

Make sure to modify AndroidManifest.xml to add <activity> of SecondActivity.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidswipeactivity"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SecondActivity"
            android:label="@string/app_name" >
        </activity>
    </application>

</manifest>


download filesDownload the files.

Next:
Swipe to Slide animated activity switching

Friday, November 29, 2013

Detect Gesture by implementing GestureDetector.SimpleOnGestureListener

This example show how to detect user gesture by implementing GestureDetector.SimpleOnGestureListener. It have the same result as last exercise of "GestureDetector".

Example of using GestureDetector.SimpleOnGestureListener

GestureDetector.SimpleOnGestureListener provides an implementation for all of the on<TouchEvent> methods by returning false for all of them. Thus we can override only the methods we care about. In our application, we have to detect onFling() only. So we can extend GestureDetector.SimpleOnGestureListener instead of implementing the GestureDetector.OnGestureListener interface.

MainActivity.java
package com.example.androidviewflipper;

import android.os.Bundle;
import android.app.Activity;
import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ViewFlipper;

public class MainActivity extends Activity{
 
 private GestureDetectorCompat mDetector;

 Button buttonPrev, buttonNext;
 ViewFlipper viewFlipper;

 Animation slide_in_left, slide_out_right;
 Animation slide_in_right, slide_out_left;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  mDetector = new GestureDetectorCompat(this, new MyGestureListener());

  buttonPrev = (Button) findViewById(R.id.prev);
  buttonNext = (Button) findViewById(R.id.next);
  viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);

  slide_in_left = AnimationUtils.loadAnimation(this,
    R.anim.slide_in_left);
  slide_out_right = AnimationUtils.loadAnimation(this,
    R.anim.slide_out_right);
  
  slide_in_right = AnimationUtils.loadAnimation(this,
    R.anim.slide_in_right);
  slide_out_left = AnimationUtils.loadAnimation(this,
    R.anim.slide_out_left);

  buttonPrev.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View arg0) {
    viewFlipper.setInAnimation(slide_in_right);
    viewFlipper.setOutAnimation(slide_out_left);
    viewFlipper.showPrevious();
   }
  });

  buttonNext.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View arg0) {
    viewFlipper.setInAnimation(slide_in_left);
    viewFlipper.setOutAnimation(slide_out_right);
    viewFlipper.showNext();
   }
  });
  ;
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  this.mDetector.onTouchEvent(event);
  return super.onTouchEvent(event);
 }

 class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
    float velocityY) {
   float sensitvity = 50;
   
   if((e1.getX() - e2.getX()) > sensitvity){
    viewFlipper.setInAnimation(slide_in_right);
    viewFlipper.setOutAnimation(slide_out_left);
    viewFlipper.showPrevious();
    Toast.makeText(MainActivity.this, 
      "Previous", Toast.LENGTH_SHORT).show();
   }else if((e2.getX() - e1.getX()) > sensitvity){
    viewFlipper.setInAnimation(slide_in_left);
    viewFlipper.setOutAnimation(slide_out_right);
    viewFlipper.showNext();
    Toast.makeText(MainActivity.this, 
      "Next", Toast.LENGTH_SHORT).show();
   }
   
   return true;
  }
    }
}


Keep using the layout and animation XML files in the exercise of "Bi-direction sliding ViewFlipper".

download filesDownload the files.

Wednesday, November 27, 2013

Using GestureDetector to detect user swipe, onFling()

Previous exercise demonstrate "Bi-direction sliding ViewFlipper" controlled by buttons. This exercise show how to implements GestureDetector.OnGestureListener to detect user swipe to update ViewFlipper.

Using GestureDetector to detect user swipe


package com.example.androidviewflipper;

import android.os.Bundle;
import android.app.Activity;
import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ViewFlipper;

public class MainActivity extends Activity implements 
 GestureDetector.OnGestureListener {
 
 private GestureDetectorCompat mDetector;

 Button buttonPrev, buttonNext;
 ViewFlipper viewFlipper;

 Animation slide_in_left, slide_out_right;
 Animation slide_in_right, slide_out_left;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  mDetector = new GestureDetectorCompat(this,this);

  buttonPrev = (Button) findViewById(R.id.prev);
  buttonNext = (Button) findViewById(R.id.next);
  viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);

  slide_in_left = AnimationUtils.loadAnimation(this,
    R.anim.slide_in_left);
  slide_out_right = AnimationUtils.loadAnimation(this,
    R.anim.slide_out_right);
  
  slide_in_right = AnimationUtils.loadAnimation(this,
    R.anim.slide_in_right);
  slide_out_left = AnimationUtils.loadAnimation(this,
    R.anim.slide_out_left);
  
  //viewFlipper.setInAnimation(slide_in_left);
  //viewFlipper.setOutAnimation(slide_out_right);

  buttonPrev.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View arg0) {
    viewFlipper.setInAnimation(slide_in_right);
    viewFlipper.setOutAnimation(slide_out_left);
    viewFlipper.showPrevious();
   }
  });

  buttonNext.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View arg0) {
    viewFlipper.setInAnimation(slide_in_left);
    viewFlipper.setOutAnimation(slide_out_right);
    viewFlipper.showNext();
   }
  });
  ;
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  this.mDetector.onTouchEvent(event);
  return super.onTouchEvent(event);
 }

 @Override
 public boolean onDown(MotionEvent arg0) {
  // TODO Auto-generated method stub
  return false;
 }

 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
   float velocityY) {
  float sensitvity = 50;
  
  if((e1.getX() - e2.getX()) > sensitvity){
   viewFlipper.setInAnimation(slide_in_right);
   viewFlipper.setOutAnimation(slide_out_left);
   viewFlipper.showPrevious();
   Toast.makeText(MainActivity.this, 
     "Previous", Toast.LENGTH_SHORT).show();
  }else if((e2.getX() - e1.getX()) > sensitvity){
   viewFlipper.setInAnimation(slide_in_left);
   viewFlipper.setOutAnimation(slide_out_right);
   viewFlipper.showNext();
   Toast.makeText(MainActivity.this, 
     "Next", Toast.LENGTH_SHORT).show();
  }
  
  return true;
 }

 @Override
 public void onLongPress(MotionEvent e) {
  // TODO Auto-generated method stub
  
 }

 @Override
 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
   float distanceY) {
  // TODO Auto-generated method stub
  return false;
 }

 @Override
 public void onShowPress(MotionEvent e) {
  // TODO Auto-generated method stub
  
 }

 @Override
 public boolean onSingleTapUp(MotionEvent e) {
  // TODO Auto-generated method stub
  return false;
 }

}


Keep using the layout and animation XML files in last exercise.

download filesDownload the files.


Next:
- Detect Gesture by implementing GestureDetector.SimpleOnGestureListener