2014-04-09 3 views
1

서명 캡처 컨트롤이있는 ListView가 있습니다. 사용자가 서명 캡처 컨트롤을 터치하면 ListView가 스크롤되지 않도록해야합니다. 이제 캡처 컨트롤 작업의 가로 스트로크가 발생하지만 세로 스트로크는 작은 선을 그리고 ListView 스크롤을 시작합니다.Android : Turn ListView 스크롤 켜기 및 끄기

ListView 스크롤을 켜고 끌 수있는 쉬운 방법을 찾을 수 없습니다. StackOverflow에 대한 몇 가지 예가 있지만 답변을 수락 한 사용자는 거의 없었으며 성공하지 못한 것으로 보이는 많은 솔루션을 시도했습니다. 터치 이벤트를 가로 채고 더 이상 이벤트 체인을 통과시키지 않도록 시그니처 캡처 구성 요소에 알릴 수있는 방법이있는 것 같지만 그게 무엇인지 모릅니다. 기능적인 코드는 모두 동일 http://www.mysamplecode.com/2011/11/android-capture-signature-using-canvas.html

:

내 서명 캡처는 여기에있는 하나의 약간 수정 된 버전입니다.

문제의 SS에 대해서는 http://imgur.com/WbfgTkj을 참조하십시오. 녹색으로 강조 표시된 부분이 서명 캡처 영역입니다. 목록보기의 맨 아래에 있으며 스크롤하려면 스크롤해야합니다.

답변

1

글쎄, 알아 냈어. 나는이 질문에 비틀 거리는 다음 사람을 위해 대답을 남기는 것이 공평하다고 생각합니다. Java purists에게 미리 사과드립니다. C#처럼 Java를 작성합니다. 나는 또한 나가서이 안드로이드 것을 알아내는 종류입니다.

해결 방법은 사용자 지정 ListView를 만드는 것입니다. 그 안에는 터치 이벤트 발송 (특히 스크롤하는 ACTION_MOVE)을 켜고 끌 수있는 옵션이 있습니다. 코드는 다음과 같습니다.

public class UnScrollingListView extends ListView { 

public UnScrollingListView(Context context, AttributeSet attrs, int defStyle) {  super(context, attrs, defStyle); } 
public UnScrollingListView(Context context, AttributeSet attrs)     {  super(context, attrs);    } 
public UnScrollingListView(Context context)          {  super(context);      } 

public boolean DisableTouchEventScroll = false; 

protected boolean DispatchMoveEventInsteadOfConsumingIt = false; 
protected View DispatchTarget = null; 

public void ResetToNormalListViewBehavior() { 
    DisableTouchEventScroll = false; 
    DispatchMoveEventInsteadOfConsumingIt = false; 
    DispatchTarget = null; 
} 

public void SetUpDispatch(View v) { 
    DisableTouchEventScroll = true; 
    DispatchMoveEventInsteadOfConsumingIt = true; 
    DispatchTarget = v; 
} 

protected static float[] GetRelativeCoordinates(View innerView, MotionEvent e) { 
    int[] screenCoords = new int [2];  //not sure if I have to preallocate this or not. 
    innerView.getLocationOnScreen(screenCoords); 
    return new float[] { 
     e.getRawX() - screenCoords[0], 
     e.getRawY() - screenCoords[1]}; 
} 

@Override 
public boolean dispatchTouchEvent(MotionEvent ev){ 
    if(DispatchMoveEventInsteadOfConsumingIt && DispatchTarget != null) { 
     //convert coordinate systems 
     float[] newCoords = GetRelativeCoordinates(DispatchTarget, ev); 
     ev.setLocation(newCoords[0], newCoords[1]); 

     DispatchTarget.onTouchEvent(ev); 
     return true; 
    } 

    if(DisableTouchEventScroll && ev.getAction() == MotionEvent.ACTION_MOVE) { 
     return true; 
    } 

    return super.dispatchTouchEvent(ev); 
} 
} 

기본적으로 정상적인 목록보기처럼 동작합니다. SetUpDispatch (View)를 호출하여 목록보기 스크롤을 중지하고 모든 ACTION_MOVE 이벤트를 특정보기로 보내도록 지시 할 수 있습니다. 그런 다음 ResetToNormalListViewBehavior()를 호출하여 다시 스크롤을 시작할 수 있습니다. 내 원래의 게시물에 링크 된 서명 캡처 코드, 당신이해야 할 모든이 (가) onTouchEvent에서 다음과 같이 변경됩니다 :

switch (event.getAction()) 
{ 
    case MotionEvent.ACTION_DOWN: 
     ... 
     listView.SetUpDispatch(this); 
     return true; 

    case MotionEvent.ACTION_UP: 
     listView.ResetToNormalListViewBehavior(); 

    case MotionEvent.ACTION_MOVE: 
     ... 

하지 누구도이 문제가 발생합니다 확실하지만 몇 가지 일반적인 응용 프로그램을 갖고있는 것 같아요, 그래서 이것을 읽는다면 행운을 빈다.

0

당신의 ListView 캡처 서명 클래스에서이 작업을 시도해보십시오

public boolean onTouchEvent(MotionEvent e) { 
    super.onTouchEvent(e); 

    ViewParent v = this.getParent(); 
    while (v != null){ 
     if(v instanceof ScrollView || v instanceof HorizontalScrollView){ 
      FrameLayout f = (FrameLayout)v; 
      f.requestDisallowInterceptTouchEvent(true); 
     } 
     v = v.getParent(); 
    } 
    //... rest of the code 
}