IT_Programming/Android_Java

[펌] ViewFlipper와 ScrollView, ListView 를 함께 사용할때 생기는 문제 해결책

JJun ™ 2011. 7. 22. 07:21



 * 출처

 : https://revolutionbl.tistory.com/entry/ViewFlipper와-ScrollView-ListView-를-함께-사용할때-생기는-문제-해결책





스크롤 뷰와, 리스트 뷰같은 특정 컴포넌트들은 상하 스크롤을 스크린 터치 이벤트를 받아서 사용하므로,
ViewFlipper 내부에 위치할 경우 한가지만 동작하는 문제가 생긴다.
ex ) 리스트 뷰 위를 터치하면 좌, 우로 움직여도 'ViewFlipper' 가 동작하지 않음 

때문에  OnGestureListener 를 달고 여러가지 작업을 해주었으나... 매번 중복되는 코드에 피곤해 지던중 매우 귀중한 포스팅을 발견

 http://android-journey.blogspot.com/2010/01/android-gestures.html

정리하자면 필터를 사용하여 이벤트를 가공해 주는것

편의를 위해 예제 소스를 뽑아냈다.

  * 액티비티 부분 -


public class SimpleActivity extends Activity implements SimpleGestureListener {


private SimpleGestureFilter detector;


/** Called when the activity is first created. */

@Override

    public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

detector = new SimpleGestureFilter(this,this);

}


@Override

public boolean dispatchTouchEvent(MotionEvent me) {

this.detector.onTouchEvent(me);

return super.dispatchTouchEvent(me);

}


@Override

public void onSwipe(int direction) {

String str = "";

switch (direction) {

case SimpleGestureFilter.SWIPE_RIGHT : str = "Swipe Right";

break;

case SimpleGestureFilter.SWIPE_LEFT :  str = "Swipe Left";

break;

case SimpleGestureFilter.SWIPE_DOWN :  str = "Swipe Down";

break;

case SimpleGestureFilter.SWIPE_UP :    str = "Swipe Up";

break;

}

Toast.makeText(this, str, Toast.LENGTH_SHORT).show();

}


@Override

public void onDoubleTap() {

Toast.makeText(this, "Double Tap", Toast.LENGTH_SHORT).show();

}


}




* 제스쳐 필터 부분



import android.app.Activity;

import android.view.GestureDetector;

import android.view.GestureDetector.SimpleOnGestureListener;

import android.view.MotionEvent;


public class SimpleGestureFilter extends SimpleOnGestureListener {


public final static int SWIPE_UP = 1;

public final static int SWIPE_DOWN = 2;

public final static int SWIPE_LEFT = 3;

public final static int SWIPE_RIGHT = 4;

public final static int MODE_TRANSPARENT = 0;

public final static int MODE_SOLID = 1;

public final static int MODE_DYNAMIC = 2;

private final static int ACTION_FAKE = -13;


// just an unlikely number

private int swipe_Min_Distance = 100;

private int swipe_Max_Distance = 350;

private int swipe_Min_Velocity = 100;

private int mode = MODE_DYNAMIC;


private boolean running = true;

private boolean tapIndicator = false;


private Activity context;

private GestureDetector detector;

private SimpleGestureListener listener;


public SimpleGestureFilter(Activity context, SimpleGestureListener sgl) {

this.context = context;

this.detector = new GestureDetector(context, this);

this.listener = sgl;

}


public void onTouchEvent(MotionEvent event) {

if (!this.running)

      return;


boolean result = this.detector.onTouchEvent(event);

if (this.mode == MODE_SOLID) {

        event.setAction(MotionEvent.ACTION_CANCEL); 

                } else if (this.mode == MODE_DYNAMIC) {

if (event.getAction() == ACTION_FAKE) {

        event.setAction(MotionEvent.ACTION_UP); 

                        } else if (result) {

        event.setAction(MotionEvent.ACTION_CANCEL); 

                        } else if (this.tapIndicator) {

event.setAction(MotionEvent.ACTION_DOWN);

this.tapIndicator = false;

}

}

// else just do nothing, it's Transparent

}


public void setMode(int m) {

this.mode = m;

}


public int getMode() {

return this.mode;

}


public void setEnabled(boolean status) {

this.running = status;

}


public void setSwipeMaxDistance(int distance) {

this.swipe_Max_Distance = distance;

}


public void setSwipeMinDistance(int distance) {

this.swipe_Min_Distance = distance;

}


public void setSwipeMinVelocity(int distance) {

this.swipe_Min_Velocity = distance;

}


public int getSwipeMaxDistance() {

return this.swipe_Max_Distance;

}


public int getSwipeMinDistance() {

return this.swipe_Min_Distance;

}


public int getSwipeMinVelocity() {

return this.swipe_Min_Velocity;

}


@Override

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

final float xDistance = Math.abs(e1.getX() - e2.getX());

final float yDistance = Math.abs(e1.getY() - e2.getY());

if (xDistance > this.swipe_Max_Distance || yDistance > this.swipe_Max_Distance)

            return false;


velocityX = Math.abs(velocityX);

velocityY = Math.abs(velocityY);

boolean result = false;

if (velocityX > this.swipe_Min_Velocity && xDistance > this.swipe_Min_Distance) {

if (e1.getX() > e2.getX()) { 

                                 // right to left

      this.listener.onSwipe(SWIPE_LEFT); 

                        } else {

         this.listener.onSwipe(SWIPE_RIGHT);

                        }

result = true;

} else if (velocityY > this.swipe_Min_Velocity && yDistance > this.swipe_Min_Distance) {

if (e1.getY() > e2.getY()) { 

                                 // bottom to up

      this.listener.onSwipe(SWIPE_UP); 

                        } else {

        this.listener.onSwipe(SWIPE_DOWN);

                        }

result = true;

}

return result;

}


@Override

public boolean onSingleTapUp(MotionEvent e) {

this.tapIndicator = true;

return false;

}

        @Override

public boolean onDoubleTap(MotionEvent arg0) {

this.listener.onDoubleTap();

return true;

}


@Override

public boolean onDoubleTapEvent(MotionEvent arg0) {

return true;

}

        @Override

public boolean onSingleTapConfirmed(MotionEvent arg0) {

if (this.mode == MODE_DYNAMIC) {

// we owe an ACTION_UP, so we fake an

arg0.setAction(ACTION_FAKE);

// action which will be converted to an

// ACTION_UP later.

this.context.dispatchTouchEvent(arg0);

}

return false;

}


}




* Simple 인터페이스



public interface SimpleGestureListener {

    void onSwipe(int direction);

    void onDoubleTap();

}