android: swipe left or right to slide views

25,485

Solution 1

I thought a new answer would be a good idea since the old one is so different.

I'll start with a bit of background: The idea here is to use a horizontal scroll view to move to the next set of controls in a pretty way. So when the user stop scrolling the scroll view to the left or right, we want to change the pictures and text, and then move the scroll back to the middle in preparation for the next swipe. Someone has already answered how to listen for when a scroll view stops I've included an almost working example of how you might use this to get the effect you are looking for.

I hope this helps out and feel free to ask if you have anymore problems.

 @Override
 protected void onScrollChanged(int x, int y, int oldX, int oldY) {
     if (Math.abs(y - oldY) > SlowDownThreshold) {
         currentlyScrolling = true;
     } else {
         currentlyScrolling = false;
         if (!currentlyTouching) {
             //scrolling stopped...handle here
             //Check if it was a left or right swipe by comparing the new and old scroll locations
             if (y > oldY) {
                 //Scroll moved Right
                 //So we would do something like 
                 setContents(Index + 1);
                 //We find out where the middle of the scroll is
                 int middleHScroll = (Hscrollview.getMeasuredWidth() / 2) - (Hscrollview.getMeasuredWidth() / 2)
                 //We then return the scroll view to the middle
                 HScroll.scrollTo(middleHScroll);
             } else {
                 //Scroll moved Left
                 //We get set the pictures and text to the previous Index of the contents
                 setContents(Index - 1);
                 //We find out where the middle of the scroll is
                 int middleHScroll = (Hscrollview.getMeasuredWidth() / 2) - (Hscrollview.getMeasuredWidth() / 2)
                 //We then return the scroll view to the middle
                 HScroll.scrollTo(middleHScroll);
             }
             super.onScrollChanged(x, y, oldX, oldY);
         }
     }
 }

The xml should be something along these lines. There is still plenty of work to do to get this working but I hope this puts you in the right direction.

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textview1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/title_bar"
            android:gravity="center_horizontal"
            android:text="PRODUCTS >> PRODUCT DETAILS" />

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >

            <RelativeLayout
                android:id="@+id/RelativeLayout1"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical"
                android:weightSum="2" >

                <HorizontalScrollView
                    xmlns:android="http://schemas.android.com/apk/res/android"
                    android:id="@+id/HorizontalScrollView1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
                    android:layout_alignParentTop="true" >


                    <LinearLayout
                        xmlns:android="http://schemas.android.com/apk/res/android"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginRight="70dp"
                        android:orientation="horizontal" >



                        <ImageView
                            android:id="@+id/productimage3"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginLeft="70dp"
                            android:layout_marginRight="20dp"
                            android:layout_weight="1"
                            android:background="@drawable/product_detail_gradient"
                            android:minHeight="100dp"
                            android:minWidth="100dp" />

                        <ImageView
                            android:id="@+id/productimage2"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginLeft="70dp"
                            android:layout_marginRight="70dp"
                            android:layout_weight="1"
                            android:background="@drawable/product_detail_gradient"
                            android:minHeight="100dp"
                            android:minWidth="100dp" />

                        <ImageView
                            android:id="@+id/productimage1"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginLeft="70dp"
                            android:layout_marginRight="70dp"
                            android:layout_weight="1"
                            android:background="@drawable/product_detail_gradient"
                            android:minHeight="100dp"
                            android:minWidth="100dp" />

                    </LinearLayout>
                </HorizontalScrollView>

                <RelativeLayout
                    android:id="@+id/description"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_alignParentBottom="true"
                    android:layout_alignParentLeft="true"
                    android:layout_below="@+id/HorizontalScrollView1"
                    android:layout_weight="1"
                    android:background="@drawable/black_img_bg" >

                    <TextView
                        android:id="@+id/title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="15dip"
                        android:textStyle="bold" >
                    </TextView>

                    <TextView
                        android:id="@+id/desc"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_below="@+id/title" >
                    </TextView>

                    <Button
                        android:id="@+id/addtocart"
                        android:layout_width="80dip"
                        android:layout_height="wrap_content"
                        android:layout_alignParentBottom="true"
                        android:layout_alignParentLeft="true"
                        android:background="@drawable/button_green_lhs"
                        android:gravity="left|center_vertical"
                        android:onClick="addToCartOrBuy"
                        android:text="Add To Cart"
                        android:textSize="10dip" />

                    <Button
                        android:id="@+id/buy"
                        android:layout_width="150dip"
                        android:layout_height="wrap_content"
                        android:layout_alignParentBottom="true"
                        android:layout_toRightOf="@+id/addtocart"
                        android:background="@drawable/button_orange_mid"
                        android:onClick="addToCartOrBuy"
                        android:text="Buy"
                        android:textSize="10dip" />

                    <Button
                        android:id="@+id/tellafriend"
                        android:layout_width="80dip"
                        android:layout_height="wrap_content"
                        android:layout_alignParentBottom="true"
                        android:layout_alignParentRight="true"
                        android:layout_toRightOf="@+id/buy"
                        android:background="@drawable/button_green_rhs"
                        android:gravity="right|center_vertical"
                        android:onClick="tellAFriend"
                        android:text="Tell A Friend"
                        android:textSize="10dip" />
                </RelativeLayout>
            </RelativeLayout>
        </RelativeLayout>

    </LinearLayout>

Solution 2

If I understand you correctly you simply need to use a gesture listener and then call the method you use to populate all the text views and imageviews you have with the next instance of information.

I found this example to be very useful when I was learning about gesture recognition.

First add the gesture listener to your public class myClass

import android.widget.Toast;
public class myClass extends Activity implements OnGestureListener {

Then the following goes right afterwards so that we can listen for each touch event.

    private static final int SWIPE_MIN_DISTANCE = 6; //120;
    private static final int SWIPE_MAX_OFF_PATH = 125; //250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 100; //200;
    private GestureDetector gestureScanner;@
    Override
    public boolean onTouchEvent(MotionEvent me) {
        return gestureScanner.onTouchEvent(me);
    }
    //@Override
    public boolean onDown(MotionEvent e) {
        //viewA.setText("-" + "DOWN" + "-");
        return true;
    }
    //@Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;
            // right to left swipe
            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Toast.makeText(getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show();

            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Toast.makeText(getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show();

            } else if (e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Toast.makeText(getApplicationContext(), "Swipe up", Toast.LENGTH_SHORT).show();

            } else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Toast.makeText(getApplicationContext(), "Swipe down", Toast.LENGTH_SHORT).show();

            }
        } catch (Exception e) {
            // nothing
        }

        return true;
    }@
    Override
    public void onLongPress(MotionEvent e) {
        Toast mToast = Toast.makeText(getApplicationContext(), "Long Press", Toast.LENGTH_SHORT);
        mToast.show();
    }
    //@Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        //viewA.setText("-" + "SCROLL" + "-");
        return true;
    }
    //@Override
    public void onShowPress(MotionEvent e) {
        //viewA.setText("-" + "SHOW PRESS" + "-");
    } //@Override
    public boolean onSingleTapUp(MotionEvent e) {
        Toast mToast = Toast.makeText(getApplicationContext(), "Single Tap", Toast.LENGTH_SHORT);
        mToast.show();
        return true;
    }

You can put the methods you use to call the previous or next instance inside the relevant listener where the toast is.

You can adjust the sensotivity of the swipes by changing these variables

 private static final int SWIPE_MIN_DISTANCE = 6; //120;
 private static final int SWIPE_MAX_OFF_PATH = 125; //250;
 private static final int SWIPE_THRESHOLD_VELOCITY = 100; //200;

I hope this helps out.

Edit:

Sorry for the mix up, your onCreate should include gestureScanner = new GestureDetector(this);

@Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.product_details);
     setContent();
     gestureScanner = new GestureDetector(this);
 }

That should get it working except for the visual effect. You can experiment with using a ScrollView to help with the slide.

Share:
25,485
png
Author by

png

Updated on July 18, 2022

Comments

  • png
    png almost 2 years

    I have a list view. On click of an item a detailed view for the item is open. This layout has many widgets like text view, ImageView Buttons etc. Now I want to slide this detail view of the items to show the detail view of next item in the list. Similarly previous item for left to right.

    I am not able to implement the view sliding I have done how to get the prev / next items in the list. But the actual sliding is the issue

    I tried gesturedetector like in Android: Swipe left to right and right to left

    and some other examples. But when I try to slide, there is no effect. I don't see any visual sliding at all.

    How to fix this?

    Tried this code but still no slide happening

     public class ProductActivity extends Activity implements OnGestureListener {
    
    
         @
         Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.product_details);
             setContent();
         }
    
         private void setContent() {
             Bundle extras = getIntent().getExtras();
             TextView title = (TextView) findViewById(R.id.title);
             title.setText(extras.getString("Title"));
             TextView desc = (TextView) findViewById(R.id.desc);
             desc.setText(extras.getString("Desc"));
             Button buy = (Button) findViewById(R.id.buy);
             String priceTag = ("$" + String.format("%.2g", extras.getDouble("Price")) + "  Buy Now >>");
             buy.setText(priceTag);
             ImageView image = (ImageView) findViewById(R.id.productimage);
             Utils.imageLoader.DisplayImage(extras.getString("Image"), image);
    
         }
    
    
    
    
         private static final int SWIPE_MIN_DISTANCE = 6; // 120;
         private static final int SWIPE_MAX_OFF_PATH = 125; // 250;
         private static final int SWIPE_THRESHOLD_VELOCITY = 100; // 200;
         private GestureDetector gestureScanner;
    
         @
         Override
         public boolean onTouchEvent(MotionEvent me) {
             return gestureScanner.onTouchEvent(me);
         }
    
         // @Override
         public boolean onDown(MotionEvent e) {
             // viewA.setText("-" + "DOWN" + "-");
             return true;
         }
    
         // @Override
         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
             float velocityY) {
             try {
                 if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                     return false;
                 // right to left swipe
                 if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                     Toast.makeText(getApplicationContext(), "Left Swipe",
                         Toast.LENGTH_SHORT).show();
    
                 } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                     Toast.makeText(getApplicationContext(), "Right Swipe",
                         Toast.LENGTH_SHORT).show();
    
                 } else if (e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                     Toast.makeText(getApplicationContext(), "Swipe up",
                         Toast.LENGTH_SHORT).show();
    
                 } else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                     Toast.makeText(getApplicationContext(), "Swipe down",
                         Toast.LENGTH_SHORT).show();
    
                 }
             } catch (Exception e) {
                 // nothing
             }
    
             return true;
         }
    
         @
         Override
         public void onLongPress(MotionEvent e) {
             Toast mToast = Toast.makeText(getApplicationContext(), "Long Press",
                 Toast.LENGTH_SHORT);
             mToast.show();
         }
    
         // @Override
         public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
             float distanceY) {
             // viewA.setText("-" + "SCROLL" + "-");
             return true;
         }
    
         // @Override
         public void onShowPress(MotionEvent e) {
             // viewA.setText("-" + "SHOW PRESS" + "-");
         } // @Override
    
         public boolean onSingleTapUp(MotionEvent e) {
             Toast mToast = Toast.makeText(getApplicationContext(), "Single Tap",
                 Toast.LENGTH_SHORT);
             mToast.show();
             return true;
         }
    
     }
    
  • Reefa
    Reefa over 11 years
    I suggest using a scroll view. Setup 3 sets of the image and text controls. Then when the user scrolls to the top of the scroll view, set the new elements and scroll them to the middle. Letting the scroll view do the hard work and allowing a, hopefully seamless redraw of the image and text views.
  • png
    png over 11 years
    i tried this. Pls see my que updated. but i dont see nay sliding effect and no toast comes. i think i am missing something basic.
  • Reefa
    Reefa over 11 years
    I edited my answer which should get your listener working to start.
  • png
    png over 11 years
    yes, i could get the toast with the fix. But i tried making it as scrollable , then even toast disappeared. Instead what happens is swipe is becoming scroll . views scroll from top to bottom
  • Reefa
    Reefa over 11 years
    I'm putting an example of how to get the visual scroll affect together for you, but I'll need you to post your layout xml please.
  • png
    png over 11 years
    i am not able to add the layout due to size restriction. Can u give me any id i can send the file. Thanks a lot
  • png
    png over 11 years
  • png
    png over 11 years
    i have put the file in chat window
  • png
    png over 11 years
    Thanks a lot for the help. Few questions : whats is SlowDownThreshold, Hscrollview etc. thanks
  • Reefa
    Reefa over 11 years
    When the user stops scrolling they don't always take their finger off the screen. This means that the scroll is actually still moving, just very slowly. SlowDownThreshold is how slow the scroll has to be moving before the app will consider the scroll complete. HScroll is the horizontal scroll layout. HorizontalScrollview Hscroll=(HorizontalScrollview) findViewById(R.id.HorizontalScrollView1). That way we don't have to use findViewById each time we want to interact with the horizontal scrollview. ps sorry for the 2 day late answer.
  • png
    png over 11 years
    thanks a lot. This onscrollchanged is which class method. I dont see it for activity. Should implement any interface
  • png
    png over 11 years
    Thanks a lot for ur effort to solve the issue. Unfortunately it didnt work for me. What worked is here misha.beshkin.lv/android-swipe-gesture-implementation . I followed this tutorial and it was very easy and staright forward.