我正在尝试将我的Windows Phone应用程序移植到Android,并且在将相同的onclicklistener与更多视图相关联时遇到了一些问题。 我的自定义视图代码是:
public class Cerchio extends View{
private float x;
private float y;
private Paint paint;
public Cerchio(Context c, float x, float y, Paint paint) {
super(c);
this.x = x;
this.y = y;
this.paint = paint;
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(x, y, 30, this.paint);
}
}
在这里我用听众创建视图:
RelativeLayout gridLayout = (RelativeLayout) findViewById(R.id.grid_layout);
for (Punto p : gr.getPunti()){ //creating visible grid
float x = (dpToPx(300) / (gr.getX()-1) * (p.getX()-1)) + dpToPx(15);
float y = (dpToPx(300) / (gr.getY()-1) * (p.getY()-1)) + dpToPx(15);
Cerchio cerchio = new Cerchio(this, x, y, paintbianca);
cerchio.setTag(p);
cerchio.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
move(v);
}
});
gridLayout.addView(cerchio);
}
最后,我的移动功能的开始:
public void move(View v) {
Cerchio cerchio = (Cerchio) v;
Punto p = (Punto) v.getTag();
RelativeLayout gridLayout = (RelativeLayout) findViewById(R.id.grid_layout);
无论我点击哪个视图,Android都会一直认为我点击始终是相同的视图(在for语句中添加的最后一个视图)。 所以,基本上,我需要的是理解捕获点击视图的正确方法。
提前感谢所有帮助我的人:)
编辑:以下是移动方法的完整代码:
public void move(View v) {
Cerchio cerchio = (Cerchio) v;
Punto p = (Punto) v.getTag();
RelativeLayout gridLayout = (RelativeLayout) findViewById(R.id.grid_layout);
if (p.Equals(selezionato)) //sto ricliccando il punto
{
selezionato = null;
cerchio.setLayerPaint(paintbianca);//deseleziono l'ellisse visivamente
for(Linea l : linee){ //rimuovo le linee
gridLayout.removeView(l);
}
linee.clear();
}
else if (selezionato != null) //sto collegando 2 punti
{
if (gr.ControllaMossa(p, selezionato)) //se la mossa è consentita collego i 2 punti e continuo
{
for (Linea l : linee) //rimuovo le linee
{
gridLayout.removeView(l);
}
cerchiosel.setLayerPaint(paintbianca); //deseleziono l'ellisse visivamente
linee.clear();
int x1 = dpToPx((int) (cerchio.getX() + 15));
int y1 = dpToPx((int) (cerchio.getY() + 15));
int x2 = dpToPx((0 + (300 / (gr.getX() - 1) * (selezionato.getX() - 1))) + 15);
int y2 = dpToPx((int)((300 - (310.0 / (gr.getY() - 1) * (selezionato.getY() - 1))) + 15));
Linea linea = new Linea(this,x1,y1,x2,y2,paintbianca); //disegno la linea che collega i 2 punti
gridLayout.addView(linea);
ArrayList<Punto> ls = gr.TrovaTriangolo(p,selezionato);
for (Punto q : ls)
{
float X1 = dpToPx((int)cerchio.getX());
float Y1 = dpToPx((int)cerchio.getY());
float X2 = dpToPx(0 + (300 / (gr.getX() - 1) * (selezionato.getX() - 1)) + 15);
float Y2 = dpToPx(310 - (300 / (gr.getY() - 1) * (selezionato.getY() - 1)) + 15);
float X3 = dpToPx(0 + (300 / (gr.getX() - 1) * (q.getX() - 1)) + 15);
float Y3 = dpToPx(310 - (300 / (gr.getY() - 1) * (q.getY() - 1)) + 15);
if (turno == 0) //coloro il triangolo a seconda del giocatore e assegno l'area
{
Triangolo triangolo = new Triangolo(this,X1,Y1,X2,Y2,X3,Y3,paintazzurra); //creo il triangolo
g1.AumentaArea(gr.AreaTriangolo(p,selezionato,q));
triangolig1++;
TextView textg1 = (TextView) findViewById(R.id.textG1);
textg1.setText(g1.getNome() + "\n Score: " + triangolig1);
gridLayout.addView(triangolo);
}
else
{
Triangolo triangolo = new Triangolo(this,X1,Y1,X2,Y2,X3,Y3,paintviola); //creo il triangolo
g2.AumentaArea(gr.AreaTriangolo(p, selezionato, q));
triangolig2++;
TextView textg2 = (TextView) findViewById(R.id.textG2);
textg2.setText(g2.getNome() + "\n Score: " + triangolig2);
gridLayout.addView(triangolo);
}
}
if (ls.size() == 0) //cambio di turno
{
turno = (turno + 1) % 2;
}
/*if (turno == 0) //gestisco il turno visivamente
{
EP1.Visibility = System.Windows.Visibility.Visible;
EP2.Visibility = System.Windows.Visibility.Collapsed;
}
else
{
EP1.Visibility = System.Windows.Visibility.Collapsed;
EP2.Visibility = System.Windows.Visibility.Visible;
}*/
gr.Linka(selezionato, p);
gr.AggiornaADJ(selezionato, p);
selezionato = null;
//gestisco la fine della partita
double area = (gr.getX()-1) * (gr.getY()-1);
double a = g1.getArea() + g2.getArea();
double range =Math.abs(a - area);
if (range>=0 && range<=0.1)
{
int vincitore = CalcolaVincitore();
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
dlgAlert.setTitle("Finish");
dlgAlert.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
finish();
}
});
dlgAlert.setCancelable(true);
switch (vincitore)
{
case 0:
dlgAlert.setMessage("Draw");
dlgAlert.create().show();
break;
case 1:
dlgAlert.setMessage(g1.getNome() + " won");
dlgAlert.create().show();
break;
case 2:
dlgAlert.setMessage(g2.getNome() + " won");
dlgAlert.create().show();
break;
}
}
}
else //se la mossa non è consentita tocca ancora a quel giocatore
{
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
dlgAlert.setTitle("Attention");
dlgAlert.setMessage("Move not allowed");
dlgAlert.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
finish();
}
});
dlgAlert.setCancelable(true);
dlgAlert.create().show();
}
}
else //sto selezionando il primo punto
{
selezionato = p;
cerchiosel = cerchio;
cerchiosel.setLayerPaint(paintgialla); //deseleziono l'ellisse visivamente
for (Tupla t : gr.getLista()) //illumino i possibili collegamenti
{
if (p.Equals(t.getPuntoA()) && t.getLinked() == false)
{
int x1 = dpToPx((int) (cerchio.getX() + 15));
int y1 = dpToPx((int) (cerchio.getY() + 15));
int x2 = dpToPx(((0 + (300 / (gr.getX() - 1) * (t.getPuntoB().getX() - 1))) + 15));
int y2 = dpToPx((310 - (300 / (gr.getY() - 1) * (t.getPuntoB().getY() - 1))) + 15);
Linea linea = new Linea(this,x1,y1,x2,y2,painttratteggiata);
gridLayout.addView(linea);
}
}
}
}
编辑2:我通过用按钮替换我的自定义视图(Cerchio)解决了我的问题。再次感谢所有试图帮助我的人!