Justin
Justin

Reputation: 800

Add a gradient color to swipe gesture

Right now I can handle swipe gestures fine with the posted code. But I want to add a background color for the transition as the user swipes from one direction to another. Very similar to the way the stock contacts app does it. I know I will have to use a GestureOverlay but I can't figure out how to link that with my current code. Is it possible, or is there an easier way to do this?

    // inside my onCreate method
    View view = getLayoutInflater().inflate(R.layout.gesture_overlay, null);
    GestureOverlayView gestureOverlayView = new GestureOverlayView(this);
    gestureOverlayView.addView(view);


    mGestureDetector = new GestureDetector(new MyGestureDetector());
    mGestureListener = new View.OnTouchListener() {
        public boolean onTouch(View view, MotionEvent event) {
            mLongPress = false;
            return mGestureDetector.onTouchEvent(event);
        }
    };

    // mListView.setOnItemClickListener(this);
    mListView.setOnTouchListener(mGestureListener);
}


class MyGestureDetector extends SimpleOnGestureListener {
    private static final int SWIPE_MIN_DISTANCE       = 120;
    private static final int SWIPE_MAX_OFF_PATH       = 200;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    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) {
        return true;
    } else
        if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
            return true;
        }

    return false;
}

}

enter image description here

Upvotes: 1

Views: 1883

Answers (2)

Crimson
Crimson

Reputation: 311

I have created a solution that worked for me so far...

create for the list item a flipperview like this:

list_item.xml

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

<!-- ViewFlipper Child 1 -->
<RelativeLayout 
android:id="@+id/listItem"
android:layout_width="match_parent"
android:layout_height="80dip"    
android:padding="4dip"    
android:background="@drawable/list_item_background"
>

<TextView 
    android:id="@+id/productName"        
    android:singleLine="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:textSize="20sp"
    android:gravity="left|center_vertical"
    android:text="" 
    android:textColor="#FFFFFF"/>
<TextView
    android:id="@+id/short_description"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"        
    android:text="short description"
    android:gravity="left"
    android:layout_below="@id/productName"
    />      
<EditText
    android:id="@+id/editValue"     
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"                    
    android:hint="@string/value"
    android:layout_alignParentRight="true"
    android:layout_alignBaseline="@id/productName"
    android:textColorHint="#FFFFFF"
    android:text=""
    android:singleLine="true"
    android:inputType="number"  
    android:textColor="#FFFFFF"
    android:maxLength="2"       
    />  
        <TextView 
    android:id="@+id/productPrice"      
    android:layout_height="wrap_content"    
    android:layout_width="wrap_content"
    android:paddingRight="8dip"     
    android:layout_toLeftOf="@id/editValue"                
    android:text="€3,40"
    android:textSize="20sp" 
    android:textColor="#FFFFFF"
    />

</RelativeLayout>

<!-- Transition views -->
<!-- ViewFlipper Child 2 -->
<LinearLayout 
    android:id="@+id/transitionViewAdd"
    android:layout_width="match_parent"
    android:layout_height="80dip"   
    android:padding="4dip"    
    android:background="@drawable/list_item_swipe"              
    android:orientation="horizontal"
>
    <TextView
        android:id="@+id/swipe_transition_textview_add"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"                       
        android:gravity="center"
        android:textSize="25sp"     
        android:textColor="#FFFFFF" 
        android:text="@string/swipe_transition_text_add"            
    />
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_gravity="center"
        android:src="@drawable/content_new"
    />

</LinearLayout>  
<!-- ViewFlipper Child 3 -->
<LinearLayout 
    android:id="@+id/transitionViewRemove"
    android:layout_width="match_parent"
    android:layout_height="80dip"           
    android:background="#ff7978"        
    android:orientation="horizontal"
>  
<ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_gravity="center"
        android:src="@drawable/ic_action_remove"            
/>
<TextView
        android:id="@+id/swipe_transition_textview_remove"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:textSize="25sp"     
        android:textColor="#FFFFFF" 
        android:text="@string/swipe_transition_text_remove"                 
    />
</LinearLayout>
</ViewFlipper>

Set for the background of the flipperview a gradient like below:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:startColor="#FF0000"
              android:endColor="@android:color/transparent"
              android:angle="0"/>           
    <corners android:radius="3dp"/>        
</shape>

now in the GestureDetector when swiping change the FlipperView to the View you want. (I assume you use the MotionEvent to handle the different states of the swipe)

 case MotionEvent.ACTION_MOVE:{         
        float deltaX = motionEvent.getRawX() - mDownX;
        int deltaXRound = Math.round(deltaX);
        float deltaY = motionEvent.getRawY() - mDownY;
        if(mVelocityTracker == null || mPaused){
            break;
        }

        if(Math.abs(deltaY) > Math.abs(deltaX)){                
            return false;
        }

        mVelocityTracker.addMovement(motionEvent);          
        if (Math.abs(deltaX) > mSlop) {
            mSwiping = true;                                    
            mListView.requestDisallowInterceptTouchEvent(true); 
        }

     // Cancel ListView's touch (un-highlighting the item)
        MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
        cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
                (motionEvent.getActionIndex()
                        << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
        mListView.onTouchEvent(cancelEvent);
        cancelEvent.recycle();           

        if(deltaX > 0 && mSwiping){                             
                  mViewFlipper.setDisplayedChild(mViewFlipper.indexOfChild(mViewFlipper.findViewById(R.id.transitionViewAdd)));
            mCurrentFlipperView = mViewFlipper.getCurrentView();

            Drawable background = mCurrentFlipperView.getBackground();
            background.setBounds(0, 0, deltaXRound, mCurrentFlipperView.getHeight());   
            background.invalidateSelf();

now.. the thing that does the trick is to use the setBounds method to set the bounds of the background of your listitem

Drawable background = mCurrentFlipperView.getBackground();
background.setBounds(0, 0, deltaXRound, mCurrentFlipperView.getHeight());   
background.invalidateSelf();

this works for me.. it creates a gradient that follows the touch while swiping.. it needs some editing to let it work better.. but i've looked for a solution very long and I know a lot of people are looking for it so I wanted to show it as fast as possible. But i think you'll figure it out to make it the way you want.

Upvotes: 3

Frank Cheng
Frank Cheng

Reputation: 6186

Does the screenshot comes from Samsung phone? I have implemented this effect before. This swipe bar isn't a gradient color but just composed with three pictures .

You can get these pictures by decompile the APK file with apktool

Upvotes: 0

Related Questions