2014-02-09 104 views
0

我有以下XML:如何使用拖放保持布局内的图像拖放

<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@drawable/palette2" 
    android:id="@+id/fl" > 

    <ImageView 
     android:id="@+id/iv" 
     android:layout_width="10dp" 
     android:layout_height="10dp" 
     android:src="@drawable/esquare" /> 

</FrameLayout> 

这在我的Android手机提供了以下图像

enter image description here

我如何代码,以便该用户可以在布局中的任何位置拖动图像,并且ImageView将始终保持在布局内?

如果X<0这将是X =(X + imageview.width())

如果Y<0这将是Y =(Y + imageview.height())

X>layout.width()如果这将是X =(X-imageview.width())

如果Y>layout.height()它将是Y =(Y-imageview.height())?

事情与此类似:

enter image description here

因此,如果用户拖动视图外,广场上的图像将内FrameLayout

留在最后已知位置我转换布局背景到一个位图,所以我可以用它来获取X和Y坐标,并转换为我的应用程序的RGB值。

f = (FrameLayout) findViewById(R.id.fl); 
f.setOnTouchListener(flt); 
iv = (ImageView) findViewById(R.id.iv); 
f.setDrawingCacheEnabled(true); 
f.buildDrawingCache(); 
bm = f.getDrawingCache(); 

我有下面的代码工作,但在每隔一段时间,我得到一个错误的NPE或x must be <= layout.width()y must be <= layout.height();。有时候,应用程序允许我拖动到布局本身的右侧或底部,这不应该发生,因为我有一个不允许它的条件。

@Override 
    public boolean onTouch(View v, MotionEvent event) { 
     int x = (int)event.getX(); 
     int y = (int)event.getY(); 
     if (x<0) { 
      iv.setX(0); 
      iv.setY(y); 
      x=0; 
      Toast.makeText(getApplicationContext(), "x=0", 2000).show(); 
     } 
     if (y<0) { 
      iv.setY(0); 
      iv.setX(x); 
      y=0; 
      Toast.makeText(getApplicationContext(), "y=0", 2000).show(); 
     } 
     if (x>bm.getWidth()) { 
      x=bm.getWidth()-20; 
      iv.setX(x); 
      iv.setY(y); 
      Toast.makeText(getApplicationContext(), "x=bitmap.maxwidth(}", 2000).show(); 
     } 
     if (y>bm.getHeight()) { 
      y=bm.getHeight()-20; 
      iv.setY(y); 
      iv.setX(x); 
      Toast.makeText(getApplicationContext(), "y=bitmap.maxheight(}", 2000).show(); 
     } 
     if (x>0 || x<bm.getWidth() || y>0 || y<bm.getHeight()) { 
      int action = event.getAction(); 
      int pixel = bm.getPixel((int)x,(int) y); 

      switch (action & MotionEvent.ACTION_MASK) { 
       case MotionEvent.ACTION_DOWN: { 
        Log.i("COORDINATES","Touch coordinates : x" + String.valueOf(x) + "y" + String.valueOf(y)); 
        iv.setX(x); 
        iv.setY(y); 
        inRed = Color.red(pixel); 
        inBlue = Color.blue(pixel); 
        inGreen = Color.green(pixel); 
        Log.d("Colors","R:" +inRed +" G:" +inGreen+" B:" + inBlue); 
        break; 
       } 
       case MotionEvent.ACTION_MOVE:{ 
        Log.i("COORDINATES","Touch coordinates : x" + String.valueOf(x) + "y" + String.valueOf(y)); 
        iv.setX(x); 
        iv.setY(y); 
        inRed = Color.red(pixel); 
        inBlue = Color.blue(pixel); 
        inGreen = Color.green(pixel); 
        Log.d("Colors","R:" +inRed +" G:" +inGreen+" B:" + inBlue); 
        break; 
       } 
      } 
     } 
     return true; 
    } 

用下面的代码,X = 0和Y = 0的工作很好! imageview保持在里面,但是当我拖动X或Y越过位图的宽度和高度时,问题就会发生。

这是我的logcat如果我拖累了太多的权利:

02-09 12:34:32.791: E/AndroidRuntime(12607): FATAL EXCEPTION: main 
02-09 12:34:32.791: E/AndroidRuntime(12607): java.lang.IllegalArgumentException: x must be < bitmap.width() 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.graphics.Bitmap.checkPixelAccess(Bitmap.java:1155) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.graphics.Bitmap.getPixel(Bitmap.java:1107) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at com.example.dragdrop.MainActivity$1.onTouch(MainActivity.java:116) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.View.dispatchTouchEvent(View.java:7241) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2168) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1903) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1953) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1405) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.app.Activity.dispatchTouchEvent(Activity.java:2410) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1901) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.View.dispatchPointerEvent(View.java:7426) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:171) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4342) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4382) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.Choreographer.doCallbacks(Choreographer.java:562) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.Choreographer.doFrame(Choreographer.java:530) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.os.Handler.handleCallback(Handler.java:725) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.os.Handler.dispatchMessage(Handler.java:92) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.os.Looper.loop(Looper.java:137) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at android.app.ActivityThread.main(ActivityThread.java:5195) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at java.lang.reflect.Method.invokeNative(Native Method) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at java.lang.reflect.Method.invoke(Method.java:511) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) 
02-09 12:34:32.791: E/AndroidRuntime(12607): at dalvik.system.NativeStart.main(Native Method) 

回答

1

看起来你有引起你的问题使发错别字。

变化

if (x>0 || x<bm.getWidth() || y>0 || y<bm.getHeight()) 

这个

if (x>0 && x<bm.getWidth() && y>0 && y<bm.getHeight()) 

也许这会解决您的问题。

+0

要添加到您发布的内容中,我应该分别包围X和Y我在想...会放弃它。谢谢。顺便说一句,你认为我的条件检查是正确的,因为我正在进行移动和下降事件之前进行评估?或者我应该在移动和移动事件内单独进行条件处理? – Si8

+0

随着你的建议,我做了一些调整和(手指交叉)它按预期工作!!!!!!!!!!!!!!!!!我非常开心!哈哈谢谢! – Si8

+1

很高兴听到它现在所有的工作:) –