Можно ли перегрузить метод onDraw в Android? - PullRequest
0 голосов
/ 05 августа 2011

Я пытаюсь нарисовать объекты на холсте в Android.Например, для заполненного треугольника я определяю значения для треугольника в одном классе и, используя нажатие кнопки, я бы хотел вызвать холст из другого класса с отображенным на нем треугольником.

Моя проблема заключается вчто мне трудно передать значения из класса в метод onDraw (Canvas canvas).Я думаю о перегрузке метода.Кто-нибудь делал это раньше?

Спасибо.

"Отредактировано на основе ответов ниже !!"

Это код, который я вызываю, когда нажимаю кнопку из другого класса.Однако, несмотря на то, что значения треугольника вызываются, метод onDraw () не вызывается.Куда я иду не так?

public class MyView extends View{

Path path = new Path();
Paint paint = new Paint();

public MyView(Context context) {
    super(context);

}

public void setPath(Point a, Point b, Point c){

    path.setFillType(Path.FillType.EVEN_ODD);
    path.moveTo(a.x, b.y);
    Log.d("MYVIEW","pointA" +a.x);
    Log.d("MYVIEW","pointB" +b.y);
    path.lineTo(b.x, b.y);
    path.lineTo(c.x, c.y);
    path.lineTo(a.x, a.y);
    path.close();

    postInvalidate();
}

@Override
protected void onDraw(Canvas canvas) {

     super.onDraw(canvas);

    paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    paint.setStrokeWidth(2);
    paint.setColor(android.graphics.Color.RED);
    paint.setStyle(Paint.Style.FILL_AND_STROKE);
    paint.setAntiAlias(true);

    Log.d("ONDRAW","inside onDraw");
    canvas.drawPath(path, paint);       
}

}

"Как я вызываю класс MyView"

Point pointA = new Point();
        pointA.set(x, y);
        Point pointB = new Point();
        pointB.set(m, n);
        Point pointC = new Point();
        pointC.set(b, c);

        MyView view = new MyView(this.context);

        view.setPath(pointA, pointB, pointC);

Ответы [ 3 ]

1 голос
/ 05 августа 2011

Я думаю, что идея прямого вызова метода onDraw() сама по себе ошибочна, потому что onDraw() - это метод, который система вызывает , когда она хочет визуализировать ваше представление, передаваяэто Canvas, чтобы сделать это.Чтобы сообщить системе, что вы хотите, чтобы представление повторно отображалось, вызывайте invalidate() в этом представлении (или postInvalidate() из потока, не являющегося пользовательским интерфейсом), и затем система в конечном счете вызывает onDraw() этого представления.

То, что вы должны сделать, это либо предоставить вашему пользовательскому представлению ссылку на объект, который содержит данные, которые будут влиять на то, что отрисовано, либо, альтернативно, создать некоторые методы «установщика» в вашем пользовательском представлении, чтобы сам вид был представленэто объект, который содержит эти конкретные данные.Это действительно все зависит от вашего приложения.Тогда вы бы позвонили invalidate() в этом представлении.

Чрезвычайно упрощенные примеры из вышеперечисленного:

Triangle mTriangle = new Triangle( ... vertices here ... );
mCustomView.setTriangle(mTriangle);
mCustomView.invalidate();

Or:

mCustomView.setTriangle( ... vertices here ... );
mCustomView.invalidate();

Вы также можете выполнить invalidate() в методе сеттера, если хотите еще упростить его.Вероятно, именно так работает метод TextView setText(): он устанавливает текст в переменную и затем вызывает invalidate().

0 голосов
/ 05 августа 2011

Буфер пользовательского представления не является постоянным, вы должны рисовать все для каждого кадра, в то время как SurfaceView является постоянным, но у него есть два буфера, которые усложняют ситуацию.

Вы можете легко сделать то, что вы хотите, если бы вы нарисовали все свои объекты в растровом изображении, а затем нарисовали это растровое изображение на холсте представления. Затем вы можете создавать перегруженные методы для ваших объектов.

Другой способ сделать это, полезный для функции отмены, - сделать каждый объект классом, как предложил Тревор, и затем добавить эти объекты в ArrayList.

Когда onDraw просто перебирает ArrayList и рисует все объекты. Затем вы можете легко добавлять или удалять объекты.

Пример:

class Triangle{
 public PointF p1;
 public PointF p2;
 public PointF p3;
 public boolean filled; 
 public int tColor;
 public boolean remove;

  Triangle(PointF p1,PointF p2, PointF p3, boolean filled, int tColor){

   this.p1 = p1;
   this.p2 = p2;
   this.p3 = p3;
   this.filled = filled;
   this tColor = tColor;

  }

}

Создайте треугольник и добавьте его в массив:

ArrayList<Triangle> triangles = new ArrayList<Triangle>();

Triangle triangle = new Triangle(new PointF(1,1),new PointF(2.2f,2.2f),new PointF(3.3f,3.3f), true, Color.BLUE);

triangles.add(triangle);

в onDraw (Canvas canvas) для представления:

for (int i = triangles.size() - 1; i >= 0; i--) {

   Triangle triangle = triangles.get(i);
   if (trinagle.remove){
       triangles.remove(i); //remove object if condition met
   }else{
       drawTriangle(triangle, canvas);
   }
}

Затем вы в методе drawTriangle просто рисуете линии и т.д. на переданном холсте. Я надеюсь, что это дает вам некоторые идеи.

0 голосов
/ 05 августа 2011

Это способ сделать это:

public class yourDrawingView extends View{

//bla bla bla

int triangle_detail1;
int triangle_detail2; //and all you need to draw the triangle

public void setTriangle(int d1,int d1){ //etc give the function the parameters she needs
    triangle_detail1 = d1;
    triangle_detail2 = d2;
    //ETC

    //finally
    invalidate();
}

protected void onDraw(Canvas canvas){
    super.onDraw(canvas);
    //draw your triangle
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...