android onclick为几个自定义视图问题

时间:2015-04-10 12:08:37

标签: android onclicklistener android-custom-view

早上好,我在一个ralativeLayout中绘制了9个customView。

我希望为每个视图分配点击监听器。

问题在于,当我点击其中一个视图时,即使我实际点击了第一个视图,也会获得对最后一个绘制视图的引用。

这是我的代码:

public class MainActivity extends Activity {

MySurfaceView view;
RelativeLayout layout;
List<CustomCircles> circlesArr;

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

    setContentView(R.layout.activity_main);

    layout = (RelativeLayout) findViewById(R.id.relativeLayout);

    ViewTreeObserver vto = layout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);

            int width = layout.getMeasuredWidth();
            int height = layout.getMeasuredHeight();

            int radius = calculateCircleRadius(height);
            calculateCirclesPosition(radius);
        }
    });
}

int circlesPerRow = 3;
int rows = 3;

 private void calculateCirclesPosition(int radius) {

    int index = 0;
    circlesArr = new ArrayList<CustomCircles>();

    for (int i = 0; i < rows; ++i) {
        int y = radius + ((radius * 2) * i);
        RelativeLayout.LayoutParams params = null;
        if(i == 0) {
            params = new RelativeLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        } else if(i == 1) {
            params = new RelativeLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.BELOW, circlesArr.get(0).id);
        } else if(i == 2) {
            params = new RelativeLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.BELOW, circlesArr.get(3).id);
        }


        for (int j = 0; j < circlesPerRow; ++j) {

            int x = radius + ((radius * 2) * j);
            Punto centro = new Punto(x, y);
            Cerchio cerchio = new Cerchio(centro, radius);
            cerchio.indexInArray = index;

            CirclesHandler.get().getCircleList().add(cerchio);

            CustomCircles circle = new CustomCircles(this, centro,
                    radius, index++);
            circle.setTag("circle" + index);

            Log.v("jajaja", "setted index is "+ index);

            circlesArr.add(circle);

            if(j == 0) {
                params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            } else {
                params = new RelativeLayout.LayoutParams(
                        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                params.addRule(RelativeLayout.RIGHT_OF, circlesArr.get(j-1).getId());
            }

            layout.addView(circle, params); 
        }
    }
}

private int calculateCircleRadius(int height) {
    return (height / 3) / 2;
}
}

CustomCircleView Class

public class CustomCircles extends View implements View.OnClickListener {

Punto centro;
Paint paint;
int radius;
int id;

public CustomCircles(Context context, Punto centro, int radius, int id) {
    this(context);
    this.centro = centro;
    this.radius = radius;
    this.id = id;
    //setId(id);
}

public CustomCircles(Context context) {
    super(context);
    init();
}

public CustomCircles(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public CustomCircles(Context context, AttributeSet attrs) {
    super(context, attrs);
}

private void init() {

    this.setOnClickListener(this);
    paint = new Paint();
    paint.setColor(Color.parseColor("#000000"));
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.drawCircle(centro.x, centro.y, radius, paint);
}

@Override
public void onClick(View v) {
    Log.v("jajaja", "Clicked " + this.getTag());
}
}

enter image description here

感谢您的时间

2 个答案:

答案 0 :(得分:1)

您将圈子放在RelativeLayout中,没有关于地点的选项,这就是为什么他们都可以拥有getLeft()==0getTop()==0

对于所有圈子,请致电View方法setId(index),而LayoutParams需要添加规则:

params.addRule(RelativeLayout.RIGHT_OF, prevCircle.getId());
params.addRule(RelativeLayout.ALIGN_TOP, prevCircle.getId());

params.addRule(RelativeLayout.BELOW, circleAbove.getId());
params.addRule(RelativeLayout.ALIGN_LEFT, circleAbove.getId());

对于新的圆圈。

答案 1 :(得分:0)

几天后,我尝试使用onMeasure()和onLayout()来改变我的方法。 最后我知道了!

我想分享我的代码:

Custum相对布局类:

public class CustomRelativeLayout extends RelativeLayout {

public CustomRelativeLayout(Context context) {
    super(context);
}

public CustomRelativeLayout(Context context, AttributeSet attrs,
        int defStyle) {
    super(context, attrs, defStyle);
}

public CustomRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    for (int i = 0; i < getChildCount(); ++i) {

        View v = getChildAt(i);
        Punto center = ((CustomCircles) v).centro;
        int radius = ((CustomCircles) v).radius;
        v.layout(center.x - radius, center.y - radius, center.x + radius,
                center.y + radius);
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    for (int i = 0; i < getChildCount(); ++i) {

        View v = getChildAt(i);
        Punto center = ((CustomCircles)v).centro;
        v.measure(center.x * 2, center.y *2);
    }

      int desiredWidth = 100;
        int desiredHeight = 100;

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int width;
        int height;

        //Measure Width
        if (widthMode == MeasureSpec.EXACTLY) {
            //Must be this size
            width = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            //Can't be bigger than...
            width = Math.min(desiredWidth, widthSize);
        } else {
            //Be whatever you want
            width = desiredWidth;
        }

        //Measure Height
        if (heightMode == MeasureSpec.EXACTLY) {
            //Must be this size
            height = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            //Can't be bigger than...
            height = Math.min(desiredHeight, heightSize);
        } else {
            //Be whatever you want
            height = desiredHeight;
        }

        setMeasuredDimension(width, height);
}
}

自定义圈子类:

public class CustomCircles extends View implements View.OnClickListener {

Punto centro;
Paint paint;
int radius;
int id;

public CustomCircles(Context context, Punto centro, int radius, int id) {
    this(context);
    this.centro = centro;
    this.radius = radius;
    this.id = id;
}

public CustomCircles(Context context) {
    super(context);
    init();
}

public CustomCircles(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public CustomCircles(Context context, AttributeSet attrs) {
    super(context, attrs);
}

private void init() {

    this.setOnClickListener(this);
    paint = new Paint();
    paint.setColor(Color.parseColor("#000000"));
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.drawCircle(radius, radius, radius, paint);
}

private void changeColor() {
    this.paint.setColor(Color.parseColor("#0000FF"));
    invalidate();

}

@Override
public void onClick(View v) {
    changeColor();
}
}

主要活动类:

 public class MainActivity extends Activity {

MySurfaceView view;
CustomRelativeLayout layout;
List<CustomCircles> circlesArr;

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

    setContentView(R.layout.activity_main);

    layout = (CustomRelativeLayout) findViewById(R.id.customRelativeLayout);

    ViewTreeObserver vto = layout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);

            int width = layout.getMeasuredWidth();
            int height = layout.getMeasuredHeight();

            int radius = calculateCircleRadius(height);
            calculateCirclesPosition(radius);
        }
    });
}

int circlesPerRow = 3;
int rows = 3;

private void calculateCirclesPosition(int radius){

    int index = 0;
    circlesArr = new ArrayList<CustomCircles>();

    for (int i = 0; i < rows; ++i) {
        int y = radius + ((radius * 2) * i);

        for (int j = 0; j < circlesPerRow; ++j) {

            int x = radius + ((radius * 2) * j);
            Punto centro = new Punto(x, y);
            Cerchio cerchio = new Cerchio(centro, radius);
            cerchio.indexInArray = index;

            CirclesHandler.get().getCircleList().add(cerchio);

            CustomCircles circle = new CustomCircles(this, centro,
                    radius, index++);

            circlesArr.add(circle);

            layout.addView(circle); 
        }
    }
}

private int calculateCircleRadius(int height) {
    return (height / 3) / 2;
}
}

enter image description here