Android 同一自定义视图的多个实例的事件
我是Android新手。 在我的项目中,我有一个自定义视图MyView,代码如下Android 同一自定义视图的多个实例的事件,android,Android,我是Android新手。 在我的项目中,我有一个自定义视图MyView,代码如下 public class MyView extends View { private final Bitmap baseBitmap = BitmapFactory.decodeResource( getResources(), R.drawable.myImage); private final Matrix matrix; private boolean act
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,然后将它们添加到主布局中。代码如下:
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;
}
}
}
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
的左上角。因此,只有最上面的(添加的最后一个)是可触摸的
我认为,如果您尝试将它们添加到线性布局
,作为测试,您将看到您的视图是有效的。以编程方式设置RelativeLayout
的LayoutParams
不是很舒服
编辑
我试过你的密码。事实上,您的视图只是一个接一个地绘制,否则整个图形将无法绘制,因此我的第一个猜测是正确的(最上面的视图覆盖了其他视图,即使在其透明部分中也是如此)(顺便说一句,请尝试Hierarchy Viewer,您自己也可以看到)。因此,您需要在单个视图中完成工作,或者像这样处理触摸:
@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中如何工作的说明,请参阅
这两种方法都需要ispetalTouched()
逻辑来检测是否/哪些图形必须移动,但第一种方法当然更有效
另外,忘了onMeasure()
这件事吧,我认为这有助于为视图提供一个环绕的大小,这样它就不会填充其父视图,而将视图放在一边是有意义的。但是,如果视图没有堆积起来,请确保触摸会起作用
(…allora
mPetali
stava proprio per petali!)使用LinearLayout我只得到第一个视图,所以我尝试使用RelativeLayout.LayoutParams,所以我尝试使用RelativeLayout.LayoutParams,如下所示RelativeLayout.LayoutParams=新的RelativeLayout.LayoutParams(LayoutParams.FILL\u PARENT,LayoutParams.WRAP\u CONTENT);如果(i>0){params.addRule(RelativeLayout.ALIGN_LEFT,i-1)}myView.setLayoutParams(params);mainLayout.addView(myView,i);但是它仍然不起作用。@vilandra:在params.addRule()
中,您需要传递视图的id(使用getId()
获得的id),而不是作为布局的子级传递其索引。LinearLayout可能不起作用,因为您忘记设置android:orientation=“vertical”
。但是,如果它仍然无法工作,您是否可以使用层次查看器检查视图是否占用了所有空间?然后,您可能需要在自定义视图中重写onMeasure()
。@bigstones:不能使用LinearLayout和垂直方向,不能重写onMeasure(),不能将Previous MyView对象保存在while中,也不能调用getId而不是使用索引(我想这是同一回事,因为我对setId使用索引)。我真的不知道会有什么问题。发布包含onMeasure方法的代码是否有用?@vilandra(这是一样的,因为我想我使用setId的索引)
哦,对不起,我没有看到。是的,请把代码也发出来,我希望我能帮上忙。@bigstones:好的,我很抱歉!现在的问题是要知道实际的触摸视图。我让我的视图实现View.OnTouchListener类,在视图构造函数settedcode
this.setOnTouchListener(this)code
和onTouch方法(code
onTouch(View v,MotionEvent事件)code
)中验证了获得的视图。视图总是当前的,也就是说,对于我的问题,传递给onTouch的视图总是最后一个,因此code
v.getId()code
和code
this.getId()code
之间的比较总是正确的。这样,问题就一直存在。然后,我使用了一个视图组,其中。。。
@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
}
//......