2014-04-14 5 views
0

HorizontalScrollView 내에서 뷰를 정렬하고 각 뷰 (DrawView.java)에 사각형이 포함되어 있습니다. 액티비티에이 뷰만 포함되어있을 때 핀치 확대/축소 기능이 정상적으로 작동하지만 (코드 1 및 해당 이미지 1 참조) HorizontalScrollView에서 여러 뷰를 정렬 할 때이 뷰의 터치 이벤트가 터치로 엉망이므로 제대로 작동하지 않습니다. HorizontalScrollView의 이벤트 (코드 2 및 이미지 2)안드로이드의 HorizontalScrollView에서 핀치 줌이 제대로 작동하지 않습니다.

누군가가이 버그를 해결하는 데 도움을주십시오.

핀치 줌이 정상적으로 작동하는 코드입니다.

public class MainActivity extends Activity { 
    DrawView drawView; 


    public class DrawView extends View { 
     Paint paint = new Paint(); 
     public int recog=-1; // this variable will tell if onDraw is called for first time or is called by listener usinf invalidate() 
     boolean listener=false; 

     int data[] = new int[] {200,200,200,200,200,200,200,200,200,200,200,200}; 

     private float MIN_ZOOM = 0.1f; 
     private float MAX_ZOOM = 10f; 

     private float mPosX; 
     private float mPosY; 


     boolean zoom=false;  
     private ScaleGestureDetector detector; 
     float width=200; 

     private float mLastTouchX; 
     private float mLastTouchY; 


     private ScaleGestureDetector mScaleDetector; 
     private float mScaleFactor = 1.f; 


     private static final int INVALID_POINTER_ID = -1; 

    // The ‘active pointer’ is the one currently moving our object. 
    private int mActivePointerId = INVALID_POINTER_ID; 



     public DrawView(Context context) { 
      this(context, null);    
     } 

     public DrawView(Context context, AttributeSet attrs) { 
      this(context, attrs, 0); 
     } 

     public DrawView(Context context, AttributeSet attrs, int defStyle) { 
      super(context, attrs, defStyle); 
      mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 

     } 

     @Override 
     public void onDraw(Canvas canvas) { 

      paint.setColor(Color.GREEN); 
      canvas.save(); 
      if(listener ==true) 
       mScaleFactor+=0.4; 
      Log.e("Ronak","Listener"+listener); 

      Log.e("Ronak","ScaleFactor"+mScaleFactor); 
      canvas.scale(mScaleFactor, 1); 
      canvas.drawRect(0.0f, 0.0f, 300.0f, 100.0f, paint); 
      makeLinesinRange(0,100,300,100,200, 5, canvas,100); 
      width=mScaleFactor*300; 
      canvas.restore(); 
      requestLayout(); 

      } 

     public boolean onTouchEvent(MotionEvent ev) { 
      // Let the ScaleGestureDetector inspect all events. 
      mScaleDetector.onTouchEvent(ev); 

      final int action = ev.getAction(); 
      switch (action & MotionEvent.ACTION_MASK) { 
      case MotionEvent.ACTION_DOWN: { 
       final float x = ev.getX(); 
       final float y = ev.getY(); 

       mLastTouchX = x; 
       mLastTouchY = y; 
       mActivePointerId = ev.getPointerId(0); 
       break; 
      } 

      case MotionEvent.ACTION_MOVE: { 
       final int pointerIndex = ev.findPointerIndex(mActivePointerId); 
       final float x = ev.getX(pointerIndex); 
       final float y = ev.getY(pointerIndex); 

       // Only move if the ScaleGestureDetector isn't processing a gesture. 
       if (!mScaleDetector.isInProgress()) { 
        final float dx = x - mLastTouchX; 
        final float dy = y - mLastTouchY; 

        mPosX += dx; 
        mPosY += dy; 

        invalidate(); 
       } 

       mLastTouchX = x; 
       mLastTouchY = y; 

       break; 
      } 

      case MotionEvent.ACTION_UP: { 
       mActivePointerId = INVALID_POINTER_ID; 
       break; 
      } 

      case MotionEvent.ACTION_CANCEL: { 
       mActivePointerId = INVALID_POINTER_ID; 
       break; 
      } 

      case MotionEvent.ACTION_POINTER_UP: { 
       final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
         >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 
       final int pointerId = ev.getPointerId(pointerIndex); 
       if (pointerId == mActivePointerId) { 
        // This was our active pointer going up. Choose a new 
        // active pointer and adjust accordingly. 
        final int newPointerIndex = pointerIndex == 0 ? 1 : 0; 
        mLastTouchX = ev.getX(newPointerIndex); 
        mLastTouchY = ev.getY(newPointerIndex); 
        mActivePointerId = ev.getPointerId(newPointerIndex); 
       } 
       break; 
      } 
      } 

      return true; 
     } 

     @Override protected void onMeasure(int widthMeasureSpec, 
        int heightMeasureSpec) { 
       // int width = MeasureSpec.getSize(widthMeasureSpec); 
       //int height = (int)(width * 0.5f); 
       setMeasuredDimension((int)width, 350); 
       } 


     private void makeLinesinRange(int x1, int y1, int x2, int y2, int size, int divisions, Canvas canvas,int width) 
     { 
      paint.setStrokeWidth(6); 
      paint.setColor(Color.DKGRAY); 
      float kk=(x2-x1)/(divisions-1); 
      for(int i=0;i<divisions;i++) 
      { 
       canvas.drawLine(x1+i*kk, y1, x1+i*kk, y2+size, paint); 
      } 
     } 

     private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
      @Override 
      public boolean onScale(ScaleGestureDetector detector) { 
       mScaleFactor *= detector.getScaleFactor(); 

       Log.e("Ronak","scale "+mScaleFactor); 
       // Don't let the object get too small or too large. 
       mScaleFactor = Math.max(0.3f, Math.min(mScaleFactor, 5.0f)); 


       invalidate(); 
       return true; 
      } 
     } 



    } 



    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     drawView = new DrawView(this); 
     drawView.setBackgroundColor(Color.WHITE); 
     setContentView(drawView); 




    } 
} 

DrawView.java. 이것은 단일보기의 코드입니다. I는 I는 HorizontalScrollView 연장되는 수평 스크롤링 이러한 관점 여러 끼우는 상기 클래스 (DrawView.java)를 호출하는 클래스가 HorizontalScrollView

public class DrawView extends View { 
    Paint paint = new Paint(); 
    public int recog=-1; // this variable will tell if onDraw is called for first time or is called by listener usinf invalidate() 
    boolean listener=false; 
    int view_number=0; 

    int data[] = new int[] {200,200,200,200,200,200,200,200,200,200,200,200}; 
    int lines[] = new int[] {4,5,7,8,2,6,6,3,2,1,1,6}; 
    String[] type=new String[]{"Song","Music","Magazine","Audible","Videos","Apps","Other"}; 


    private static float MIN_ZOOM = 0.1f; 
    private static float MAX_ZOOM = 10f; 

    private float mPosX; 
    private float mPosY; 


    boolean zoom=false;  
    private ScaleGestureDetector detector; 
    float width=700; 
    float height=500; 

    private float mLastTouchX; 
    private float mLastTouchY; 


    private ScaleGestureDetector mScaleDetector; 
    private float mScaleFactor = 1.f; 


    private static final int INVALID_POINTER_ID = -1; 

// The ‘active pointer’ is the one currently moving our object. 
private int mActivePointerId = INVALID_POINTER_ID; 



    public DrawView(Context context) { 
     this(context, null);    
    } 

    public DrawView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public DrawView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 

    } 

    @Override 
    public void onDraw(Canvas canvas) { 

     paint.setColor(Color.BLUE); 
     canvas.save(); 
     if(listener ==true) 
      mScaleFactor+=0.4; 
     Log.e("Ronak","Listener"+listener); 

     Log.e("Ronak","ScaleFactor"+mScaleFactor); 
     canvas.scale(mScaleFactor, 1); 
     canvas.drawRect(0.0f, 0.0f, 300.0f, 70.0f, paint); 
     makeLinesinRange(0,70,300,70,200, lines[view_number], canvas,100); 


     width=mScaleFactor*300; 
     height=mScaleFactor*100; 
     /*int start=0; 
     int temp=(int)width/lines[view_number]; 
     for(int i=0;i<lines[view_number];i++) 
     { 
      canvas.drawText(type[i], 50, 100, paint); 
      start=temp; 
      temp+=temp; 
     }*/ 
     canvas.restore(); 
     requestLayout(); 

     } 

    public boolean onTouchEvent(MotionEvent ev) { 
     // Let the ScaleGestureDetector inspect all events. 
     mScaleDetector.onTouchEvent(ev); 

     final int action = ev.getAction(); 
     switch (action & MotionEvent.ACTION_MASK) { 
     case MotionEvent.ACTION_DOWN: { 
      final float x = ev.getX(); 
      final float y = ev.getY(); 

      mLastTouchX = x; 
      mLastTouchY = y; 
      mActivePointerId = ev.getPointerId(0); 
      break; 
     } 

     case MotionEvent.ACTION_MOVE: { 
      final int pointerIndex = ev.findPointerIndex(mActivePointerId); 
      final float x = ev.getX(pointerIndex); 
      final float y = ev.getY(pointerIndex); 

      // Only move if the ScaleGestureDetector isn't processing a gesture. 
      if (!mScaleDetector.isInProgress()) { 
       final float dx = x - mLastTouchX; 
       final float dy = y - mLastTouchY; 

       mPosX += dx; 
       mPosY += dy; 

       // invalidate(); 
      } 

      mLastTouchX = x; 
      mLastTouchY = y; 

      break; 
     } 

     case MotionEvent.ACTION_UP: { 
      mActivePointerId = INVALID_POINTER_ID; 
      break; 
     } 

     case MotionEvent.ACTION_CANCEL: { 
      mActivePointerId = INVALID_POINTER_ID; 
      break; 
     } 

     case MotionEvent.ACTION_POINTER_UP: { 
      final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 
      final int pointerId = ev.getPointerId(pointerIndex); 
      if (pointerId == mActivePointerId) { 
       // This was our active pointer going up. Choose a new 
       // active pointer and adjust accordingly. 
       final int newPointerIndex = pointerIndex == 0 ? 1 : 0; 
       mLastTouchX = ev.getX(newPointerIndex); 
       mLastTouchY = ev.getY(newPointerIndex); 
       mActivePointerId = ev.getPointerId(newPointerIndex); 
      } 
      break; 
     } 
     } 

     return true; 
    } 

    public boolean onInterceptTouchEvent(MotionEvent event) { 
     /* switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       break; 
      case MotionEvent.ACTION_CANCEL: 
      case MotionEvent.ACTION_UP: 
       mIsBeingDragged = false; 
       break; 
      case MotionEvent.ACTION_MOVE: 
       float x = event.getX(); 
       float y = event.getY(); 
       float xDelta = Math.abs(x - mLastX); 
       float yDelta = Math.abs(y - mLastY); 

       float yDeltaTotal = y - mStartY; 
       if (yDelta > xDelta && Math.abs(yDeltaTotal) > mTouchSlop) { 
        mIsBeingDragged = true; 
        mStartY = y; 
        return true; 
       } 
       break; 
     }*/ 
     Log.e("Ronak","Here"); 
     return false; 
    } 



    @Override protected void onMeasure(int widthMeasureSpec, 
       int heightMeasureSpec) { 
      // int width = MeasureSpec.getSize(widthMeasureSpec); 
      //int height = (int)(width * 0.5f); 
      setMeasuredDimension((int)width, 350); 
      } 


    private void makeLinesinRange(int x1, int y1, int x2, int y2, int size, int total_events, Canvas canvas,int width) 
    { 
     paint.setStrokeWidth(6); 
     paint.setColor(Color.MAGENTA); 

     if(total_events<1) 
     { 
      return; 
     } 
     if(total_events==1) 
     { 
      canvas.drawLine(((x1+x2)/2), y1, (x1+x2)/2, y2+size, paint); 

     } 
     else if(total_events==2) 
     { 
      canvas.drawLine(((x1+x2)/3), y1, (x1+x2)/3, y2+size, paint); 
      canvas.drawLine((2*(x1+x2)/3), y1, 2*(x1+x2)/3, y2+size, paint); 


     } 
     else 
     { 
     paint.setStrokeWidth(6); 
     paint.setColor(Color.MAGENTA); 
     float kk=(x2-x1)/(total_events-1); 
     for(int i=0;i<total_events;i++) 
     { 
      canvas.drawLine(x1+i*kk, y1, x1+i*kk, y2+size, paint); 
     } 
     } 
    } 

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      mScaleFactor *= detector.getScaleFactor(); 

      Log.e("Ronak","scale "+mScaleFactor); 
      // Don't let the object get too small or too large. 
      mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); 


      invalidate(); 
      return true; 
     } 
    } 



} 

이러한 견해 복수 배치하고있다. 이 클래스의 onTouch 함수를 재정의 할 필요가 있습니까?

enter image description here enter image description here

+0

을 처리하는 방법에 대한 몇 가지 통찰력을 가지고 : [화면을 캡처하는 방법 (http://www.digitaltrends.com/mobile/ 스크린 샷 - 어떤 종류의 불이라도)/ –

+0

고맙습니다. 다음에이 사실을 기억해 두겠습니다. 내 문제를 해결하는 데 나를 도울 수 있습니까? – user3265443

+0

@Ivan Bartsov 이 문제를 해결하는 데 도움을 줄 수 있습니까? 입력 내용이 매우 유용합니다. http://stackoverflow.com/questions/32054181/listview-animation-on-item-addition-not-working-properly – user3265443

답변

1

첫째 : 이궁! onDraw()에서 requestLayout()을 호출하지 마십시오. 그렇지 않으면 100 %로드가 발생합니다. 이제까지 할 일은 다시 레이아웃하고 다시 그립니다.

두 번째 : onInterceptTouchEvent()DrawView에서 제거하십시오. View - 및 View까지 확장되므로이 메소드는 터치 디스패치 프로세스의 일부로 호출되지 않습니다.

셋째 : 어느 쪽이 작동하지 않습니까? 스크롤링 또는 스케일링?

가 이

읽기 this thread, 그것은 내가 여기를 떠날거야 여러 제스처 소요되는 구성 요소

+0

스케일링이 작동하지 않습니다. 그러나, 내가 꼬집어 때, 때로는 자사의 스케일 업하지만 때마다 그것 때문에 혼란스러워 이벤트 ScrollView의 혼란. 또한 유사한 이유로 scaling down이 작동하지 않습니다. HorizontalScrollView의 onTouch 메서드를 재정의 할 필요가 있습니까? – user3265443

+0

부모 레이아웃보기가 wrap_content 인 경우 requestLayout()을 onDraw()에서 호출 할 때의 문제점은 무엇입니까? 그렇다면 레이아웃 크기를 어떻게 변경합니까? – user3265443

관련 문제