同一个自定义的更多实例的事件查看
我是Android新手。 在项目中,我与后续的代码同一个自定义的更多实例的事件查看
public class MyView extends View {
private final Bitmap baseBitmap = BitmapFactory.decodeResource(
getResources(), R.drawable.myImage);
private final Matrix matrix;
private boolean active = true;
public MyView(Context context, Matrix matrix) {
super(context);
this.matrix = matrix;
this.setFocusable(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (active) {
System.out.println("draw "+this.getId());
canvas.drawBitmap(baseBitmap, matrix, null);
} else {
...
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
System.out.println("--------->"+this.getId());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
this.matrix.setTranslate(event.getX()-(baseBitmap.getWidth()/2), event.getY()-(baseBitmap.getHeight()/2));
this.invalidate();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
this.active = false;
}
return true;
}
在我的活动自定义视图MyView的,我实例MyView的很多次,然后将它们添加到主布局。这是它的代码:
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();
float cx = display.getWidth()/2, cy = display.getHeight()/2;
int radius = 80;
double distance = 0, distancePoint = 0;
final int flags = PathMeasure.POSITION_MATRIX_FLAG
| PathMeasure.TANGENT_MATRIX_FLAG;
float length = 0;
setContentView(R.layout.main);
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_view);
Path pathCircle = new Path();
pathCircle.addCircle(cx, cy, radius, Direction.CW);
PathMeasure meas = new PathMeasure(pathCircle, false);
int nObject = 10;
length = meas.getLength();
distance = length/nObject;
int i = 0;
while(i<nObject){
Matrix m = new Matrix();
meas.getMatrix((float)distancePoint, m, flags);
MyView myView = new MyView(this, m);
System.out.println(myView.toString());
myView.setId(i);
mainLayout.addView(myView,i);
i++;
distancePoint = distance*i;
}
}
}
在运行时,当我触摸任何MyView元素时,我总是得到最后一个。使用“”,我可以看到被触摸的元素的ID始终是最后一个,即使我将第一个或任何其他元素分开。实际上,我只能移动最后一个元素。
有谁知道为什么我无法获得MyView碰到的正确事件?
(我希望我的问题是清楚的)
感谢
我改变了代码添加onMeasure方法。我使用了教程的代码,尺寸不是特定于我的图像。意见是绘制和结果是相同的,不幸的是有同样的问题。我也发布了布局xml,可能会很有用。
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();
float cx = display.getWidth()/2, cy = display.getHeight()/2;
int radius = 80;
double distance = 0, distancePoint = 0;
final int flags = PathMeasure.POSITION_MATRIX_FLAG
| PathMeasure.TANGENT_MATRIX_FLAG;
float length = 0;
setContentView(R.layout.main);
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_view);
Path pathCircle = new Path();
pathCircle.addCircle(cx, cy, radius, Direction.CW);
PathMeasure meas = new PathMeasure(pathCircle, false);
int nObject = 10;
length = meas.getLength();
distance = length/nObject;
int i = 0;
while(i<nObject){
Matrix m = new Matrix();
meas.getMatrix((float)distancePoint, m, flags);
MyView myView = new MyView(this, m);
System.out.println(myView.toString());
myView.setId(i);
nt spec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
myView.measure(spec, spec);
mainLayout.addView(myView,i);
i++;
distancePoint = distance*i;
}
}
}
public class MyView extends View {
private final Bitmap baseBitmap = BitmapFactory.decodeResource(
getResources(), R.drawable.myImage);
private final Matrix matrix;
private boolean active = true;
public MyView(Context context, Matrix matrix) {
super(context);
this.matrix = matrix;
this.setFocusable(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (active) {
System.out.println("draw "+this.getId());
canvas.drawBitmap(baseBitmap, matrix, null);
} else {
...
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
System.out.println("--------->"+this.getId());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
this.matrix.setTranslate(event.getX()-(baseBitmap.getWidth()/2), event.getY()-(baseBitmap.getHeight()/2));
this.invalidate();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
this.active = false;
}
return true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int chosenWidth = chooseDimension(widthMode, widthSize);
int chosenHeight = chooseDimension(heightMode, heightSize);
int chosenDimension = Math.min(chosenWidth, chosenHeight);
setMeasuredDimension(chosenDimension, chosenDimension);
}
private int chooseDimension(int mode, int size) {
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else { // (mode == MeasureSpec.UNSPECIFIED)
return getPreferredSize();
}
}
// in case there is no size specified
private int getPreferredSize() {
return 300;
}
}
main.xml中:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/main_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF66FF33">
</RelativeLayout>
我敢肯定那是因为你基本上是在你RelativeLayout
的左上角堆积如山的意见。所以,只有最上面的(最后一个)是可触摸的。
我认为,如果你试图将其添加到LinearLayout
,作为一个测试,你会看到你的观点的作品。以编程方式为RelativeLayout
设置LayoutParams
不是很舒服的恕我直言。
编辑
我想你的代码。事实是,你的意见只是提出要绘制一个比其他,否则整体绘图不会来,所以我的第一个猜测是正确的(最上层覆盖了别人 - 即使在其透明部分)(顺便说一句尝试层次浏览器,你可以看到你自己)。所以,你需要做你的工作在一个单一的视图,或者处理触摸这样的:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if(!isPetaloTouched()) {// check if the actual drawing was touched
return false; // discard the event so that it reaches
// the underlying view
}
//......
的事件在Android中如何工作的说明,请参见this post。
这两种方法都需要一个isPetaloTouched()
逻辑以检测是否/哪些绘图必须移动,但第一个将是更有效的,当然。
另外,忘记onMeasure()
的事情,我认为这可以帮助给视图大小包装,以便它不会填充它的父母,并将意见调整到一边是合理的。但是,如果视图没有堆积起来,请确保触摸可以工作。
(...每petali allora mPetali
Stava的PROPRIO!)
使用的LinearLayout我得到的只是第一种观点,所以我试图用RelativeLayout.LayoutParams,所以我试图用RelativeLayout.LayoutParams如下 RelativeLayout的。LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);如果(i> 0){ params.addRule(RelativeLayout.ALIGN_LEFT,i-1); } myView.setLayoutParams(params); mainLayout.addView(myView,i); 但它仍然无法正常工作。 – vilandra 2011-04-06 16:04:44
@vilandra:在'params.addRule()'你需要传递视图的id(你用'getId()'得到的),而不是它的索引作为布局的子元素。 LinearLayout可能没有工作,因为你忘了设置android:orientation =“vertical”。但是,如果它仍然不起作用,您是否可以使用Hierarchy Viewer来检查您的视图是否占用了所有空间?您可能需要在自定义视图中重写'onMeasure()'。 – bigstones 2011-04-06 20:03:26
@bigstones:没有办法与LinearLayout和垂直方向,没有办法重写onMeasure(),没有办法保存在while内部的previuos MyView对象,并调用getId insted使用索引(这是相同的事情因为我使用索引setId , 我想)。 我真的不知道这可能是什么问题。 发布包含onMeasure方法的代码可能有用吗? – vilandra 2011-04-07 21:21:53