5

기기 문제인지 코드에 문제가 있는지 잘 모르겠지만 상대 레이아웃과 이미지보기를 사용하여 간단한 드래그 가능한 정렬 가능 목록을 만들었습니다. 나는 이런 식으로하는 것에 대한 매우 구체적인 이유가있다. 그것은 내 질문이 아니다.가끔씩 Android/kindle 드래그가 동결 됨

내가 가지고있는 문제는 때때로 내 앱을 완전히 정지시키는 것입니다. 항목이 드래그 상태에서 멈추게됩니다. 손가락을 들어 올리면 그림자 (끌기) 개체가 화면에 계속 표시되며 화면을 터치하면 해당 지점으로 이동합니다. 이 작업은 약 1 분 동안 지속될 것입니다. 그런 다음 앱이 죽이거나 기다릴 수있는 옵션에 응답하지 않는다는 오류가 표시됩니다. 그런 다음

12-09 14:23:13.157: W/WindowManager(16415): Drag is in progress but there is no drag window handle. 

응용 프로그램의 시간이 초과 내가이 오류 메시지가 봤 유일한 정보는 더 가진 사람이었다

12-09 14:59:09.782: E/ActivityManager(16415): ANR in com.appname.appname (com.appname.appname/.MainActivity) 
12-09 14:59:09.782: E/ActivityManager(16415): Reason: keyDispatchingTimedOut 

오류로이 얻을 때 다음과 같이 로그 캣의 유일한 유용한 비트입니다 청취자를 끌고 다른 사람이 장치 터치 센서가 유지되지 않는다고 말했습니다.

이상적으로는이 오류를 수정하고 처음부터 이러한 오류가 발생하지 않도록하는 것이 가장 좋습니다. 빨리 드래그하면 주로 발생하는 것처럼 보이지만 사용자가 빠르게 드래그하지 않도록 할 수는 없습니다 ... 맞습니까?

또는 드래그로 인해 앱이 멈추고 드래그가 중단되는 것을 감지 할 수있는 방법이 있습니까? 터치 리스너에서 타이머를 설정하는 것과 마찬가지로 드래그 위치 메시지가 두 번째 또는 두 번째 인터럽트와 같은 경우 드래그 할 수 있습니까? 내가하는 일을 잘 알고있는 타이머 물건들, 그러나 그것이 얼어 붙은 동안 끌기를 멈추게하는 방법을 나는 모른다. 어떤 아이디어? 여기

코드입니다 :

설치 터치에

//happens once when the app loads 
RelativeLayout trackList = (RelativeLayout) findViewById(R.id.nsTrackList1);  
trackList.setOnDragListener(new MyTrackDragListener(this)); 

//happens in a loop for each "track" (image view) 
trackButton = new ImageView(this); 
trackButton.setImageDrawable(nsPackages[trackId].banner[bannerSizeSelector]); 
trackButton.setOnTouchListener(new MyTrackTouchListener()); 

드래그

public class MyTrackTouchListener implements OnTouchListener { 
    boolean isDragging=false; 
    float prevX, prevY; 
    public boolean onTouch(View view, MotionEvent motionEvent) { 
     if(motionEvent.getPointerCount() < 2 && !isDragging) return false; 
     if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 
      isDragging=false; 
      prevX=0; 
      prevY=0; 
      return true; 
     } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) { 
      if(isDragging) return true; 
      boolean wasFirst = (prevX == 0 || prevY == 0); 
      float theTotalDiff = Math.abs(prevX - motionEvent.getX()) + Math.abs(prevY - motionEvent.getY()); 
      prevX=motionEvent.getX(); 
      prevY=motionEvent.getY(); 
      if(wasFirst) return true; 
      if(theTotalDiff <3) return true; 
      ClipData data = ClipData.newPlainText("", ""); 
      DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view); 

      view.startDrag(data, shadowBuilder, view, 0); 
      int thisViewId = view.getId(); 
      //hide view 
      view.setVisibility(View.GONE); 

      isDragging=true;  
      return true; 
     } else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) { 
      isDragging=false; 
      return true; 
     }else { 

      Integer thisAction = motionEvent.getAction(); 
      Log.d("looper","Motion action: "+thisAction.toString()); 
      return false; 
     } 
    } 
} 

class MyTrackDragListener implements OnDragListener { 
    public static boolean isDragging=false; 
private MainActivity parent; 

public MyTrackDragListener(MainActivity myAct){ 
    parent=myAct; 
}  
    @Override 
    public boolean onDrag(View v, DragEvent event) { 
     int action = event.getAction(); 
     switch (event.getAction()) { 
     case DragEvent.ACTION_DRAG_STARTED: 
      isDragging=true; 
      // do nothing 
      return true; 
     case DragEvent.ACTION_DROP: 
      View view = (View) event.getLocalState(); 
      parent.doDropSort(view,(int) event.getY()); 
      return true; 
     case DragEvent.ACTION_DRAG_ENDED: 
      if(isDragging && event.getResult()==false){ 
       View view2 = (View) event.getLocalState(); 
       parent.doDropSort(view2,(int) event.getY(),true); 
       return true; 
      } 
      isDragging=false; 
      break; 
     case DragEvent.ACTION_DRAG_LOCATION: 
      parent.doDragHover((int) event.getY()); 
      return true; 
     default: 
      Log.d("looper","drag other... "+String.valueOf(event.getAction())); 
     } 
     return false; 
    } 
} 

몇 가지 이미

  • 항상 참/드래그 거짓 기본적으로
  • onDrag
  • 의 반환의 모든 조합을 false를 돌려 완전히
  • 항상 onDrag
  • 에서 true를 반환 드래그 리스너를 제거
    • 시도 터치 및 터치
    • 2 손가락 및 Action_Move 부분 제거 및 Action_down에서 끌기 실행

    같은 결과가 있습니다. 끌어서 놓기가 완벽하게 시간의 약 70 %를 작동 한 다음 갑자기 위에서 설명한 고정 동작을 수행합니다. 때로는 첫 번째 드래그에 때로는 때로는 여러 번 있습니다. 나는 끌기 속도를 제외하고 일관된 본에주의했다. 일반적으로 드래그 할 때 일반적으로 발생하는 것으로 보이지만 방향을 드래그하거나 드래그하면 문제가되지 않습니다.

    +0

    , 당신이 경우 볼 것 ... ID + 1 항목을 발견하고이 같은 제로로 아래 설정하여 상단 품절 될 만들고 있었다 작은 테스트 앱으로 꾸준히 다시 작성한 다음 버그 보고서를 제출할 수 있습니다. –

    +0

    @CarlAnderson 감사합니다. 저는 며칠 동안 수작업 테스트를 해본 결과 패턴이 보이지 않습니다. 이러한 종류의 동작을위한 테스트 응용 프로그램을 작성하는 방법에 대한 조언이 있습니까? 터치/드래그 앤 드롭 입력을 시뮬레이트 할 수있는 방법이 있습니까? – Lenny

    +0

    내가 아는 누구도, 그리고 불행히도 당신이 일관되게 repro에 그것을 얻을 수 없다면 아마 그것을 보지 않을 것입니다. –

    답변

    2

    예! 나는 그것을 알아.미래의 누군가를 도울 수있는 해답입니다.

    나는 마지막으로 (내가 놓친 방법을 모른다) 만 상위 목록 항목에 좁혀 후이 라인을 좁혀하는 휴식하지 않았다까지 라인을 주석 시작 :

    view.setVisibility(View.GONE); 
    

    내 목록이 설정된 방식으로 각 항목은 상대적 레이아웃 (아래 항목 제외)에서 레이아웃 속성 BELOW를 사용했습니다. 보기에서 맨 위 항목을 제거하면 두 번째 항목부터 상위 항목까지 가시성이 GONE 인 항목 아래에 있으므로 수행 할 작업을 알 수 없습니다. 해결책은보기에서 다음 항목의 매개 변수를 설정하는 것이 었습니다. 다행히도 필자는 내 트랙 버튼의 뷰 ID를 수동으로 설정합니다 (스크롤하는 다른보기도 있습니다. 라벨 등). 그래서 순차적입니다. 그래서 내 수정은 단순히

    전 아마존 직원 및 킨 개발자로
    // the top item in my list is ALWAYS view id 1 
    if(thisViewId == 1){ 
        ImageView nextTrackButton = (ImageView) trackList.findViewById(thisViewId+1); 
        LayoutParams ntLP = (LayoutParams) nextTrackButton.getLayoutParams(); 
        ntLP.addRule(RelativeLayout.BELOW,0); 
        nextTrackButton.setLayoutParams(ntLP); 
    }   
    
    //hide view 
    view.setVisibility(View.GONE);