0

クラスParticleの画面オブジェクトを描画するCustomViewVisual1という名前のカスタムビューを作成しました。このカスタムビューは、Activityを拡張するLayoutCanvasという名前のクラスで使用します。LayoutCanvasのonTouch()イベントもonProgressChanged()イベントも、invalidateを呼び出して、postInvalidate()も試したにもかかわらず、ビューが再描画されないようです。オブジェクトの値は変更されますが、再描画できません。正直なところ、私はAndroidを初めて使用し、クラスの設計方法と実装場所に関する優れたプラクティスを認識していません。そのため、私が達成しようとしていることに対してより良い解決策がある場合は、お知らせください。前もって感謝します!

これはParticleクラスです:

    public class Particle {
    Rect rect = new Rect();
    float similarity;
    Point p = new Point();
    float x;
    float y;

    float tx = 240;
    float ty = 320;

    Matrix transform = new Matrix();

    float r;
    Paint _paint = new Paint();
    Paint tempp = new Paint();

    Particle(){}

    Particle(int width, float similarity){
        this.similarity = similarity;
        x = MyMath.map(similarity, 0, 1, 0, width/2);
        //y = MyMath.myRandom(-20, 20);
        y = 0;
        //p.set((int) MyMath.map(similarity, 0, 1, 0, width/2), (int)MyMath.myRandom(0, 360));
        p.set((int)x, (int)y);
        r = MyMath.myRandom(0, 360);
        //recalculateCoordinates();
        _paint.setColor(Color.WHITE);
        tempp.setColor(Color.GREEN);
        //rotate(r);

    }


    public void display(Canvas canvas, Paint paint, float scale){
        //canvas.drawLine(canvas.getWidth()/2, 0, canvas.getWidth()/2, canvas.getHeight(), _paint);
        //canvas.drawLine(0, canvas.getHeight()/2, canvas.getWidth(), canvas.getHeight()/2, _paint);
        canvas.save();
        canvas.translate(canvas.getWidth()/2, canvas.getHeight()/2);
        //canvas.translate(tx, ty);
        canvas.rotate(r);
        //canvas.scale(scale, scale);
        paint.setColor(colorize());
        canvas.drawRect(-p.x, p.y, -p.x+10, p.y+10, paint);
        canvas.restore();

        canvas.save();
        canvas.translate(canvas.getWidth()/2, canvas.getHeight()/2);
        canvas.drawLine(0, 0, 200, 0, tempp);
        canvas.drawText("0'", 100, 8, tempp);
        canvas.restore();

        canvas.save();
        canvas.translate(canvas.getWidth()/2, canvas.getHeight()/2);
        canvas.rotate(45);
        canvas.drawLine(0, 0, 200, 0, tempp);
        canvas.drawText("45''", 100, 8, tempp);
        canvas.restore();

        canvas.save();
        canvas.translate(canvas.getWidth()/2, canvas.getHeight()/2);
        canvas.rotate(90);
        canvas.drawLine(0, 0, 200, 0, tempp);
        canvas.drawText("90'", 100, 8, tempp);
        canvas.restore();

        canvas.save();
        canvas.translate(canvas.getWidth()/2, canvas.getHeight()/2);
        canvas.rotate(180);
        canvas.drawLine(0, 0, 200, 0, tempp);
        canvas.drawText("180'", 100, 8, tempp);
        canvas.restore();
    }

    public int colorize(){
        return Color.argb(100, Math.round(255-MyMath.map(similarity, 0, 1, 0, 255)), 0, Math.round(MyMath.map(similarity, 0, 1, 0, 255)));
    }

    public void rotate(float degrees){
        transform.setTranslate(120, 160);
        transform.setRotate(degrees, 0, 0);

        // Create new float[] to hold the rotated coordinates
        float[] pts = new float[2];

        // Initialize the array with our Coordinate
        pts[0] = p.x;
        pts[1] = p.y;

        // Use the Matrix to map the points
        transform.mapPoints(pts);

        p.set((int)pts[0], (int)pts[1]);
        // NOTE: pts will be changed by transform.mapPoints call
        // after the call, pts will hold the new cooridnates

        // Now, create a new Point from our new coordinates
        //Point newPoint = new Point((int)pts[0], (int)pts[1]);

        // Return the new point
        //p.set(newPoint.x, newPoint.y);
        //return newPoint;
    }

    public void translate(int x, int y){
        tx = x;
        ty = y;
    }

    public void recalculateCoordinates(){
        x = (float) ( (x * android.util.FloatMath.cos(r) ) - (y * android.util.FloatMath.sin(r) ) );
        y = (float) ( (x * android.util.FloatMath.sin(r) ) - (y * android.util.FloatMath.cos(r) ) );
    }
    /**
     * @return the similarity
     */
    public float getSimilarity() {
        return similarity;
    }

    /**
     * @param similarity the similarity to set
     */
    public void setSimilarity(float similarity) {
        this.similarity = similarity;
    }

    /**
     * @return the x
     */
    public float getX() {
        return x;
    }

    /**
     * @param x the x to set
     */
    public void setX(float x) {
        this.x = x;
    }

    /**
     * @return the y
     */
    public float getY() {
        return y;
    }

    /**
     * @param y the y to set
     */
    public void setY(float y) {
        this.y = y;
    }

    /**
     * @return the r
     */
    public float getR() {
        return r;
    }

    /**
     * @param r the r to set
     */
    public void setR(float r) {
        this.r = r;
    }

    public Point getP() {
        return p;
    }

    public void setP(Point p) {
        this.p = p;
    }
    }

これはCustomViewVisual1クラスです。

    public class CustomViewVisual1 extends View implements Runnable{
    int width;
    int height;
    int x = 0; 
    int y = 0;
    int canvasScale = 1;
    int countDraw = 0;

    Thread t = null;
    boolean isItOK = false;

    Paint paint;
    Particle[] p = new Particle[500];

    public CustomViewVisual1(Context context){
        super(context);
        initView();
    }


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

    private void initView() {
        // TODO Auto-generated method stub
        paint = new Paint();

        Random r = new Random();
        for (int i = 0; i < p.length; i++) {
            p[i] = new Particle(width, r.nextFloat());
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        x = width/2;
        y = height/2;
        initView();
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //canvas.translate(width/2, height/2);
        canvas.drawARGB(255, 0, 0, 0);
        canvas.scale(canvasScale, canvasScale);
        for (int i = 0; i < p.length; i++) {
            p[i].display(canvas, paint, canvasScale);
        }

        paint.setColor(Color.WHITE);
        canvas.drawCircle(x, y, 20, paint);
        /*
        paint.setColor(Color.CYAN);
        canvas.drawRect(0, 0, width, 10, paint);
        paint.setColor(Color.GREEN);
        canvas.drawRect(0, height-10, width, height, paint);
        paint.setColor(Color.YELLOW);
        canvas.drawRect(0, 0, 10, height, paint);
        paint.setColor(Color.MAGENTA);
        canvas.drawRect(width-10, 0, width, height, paint);
        */
        countDraw++;
        Log.d("How many draw = ", ""+countDraw);
    }


    public float getCanvasScale() {
        return canvasScale;
    }


    public void setCanvasScale(int canvasScale) {
        this.canvasScale = canvasScale;
    }

    public void pause() {
        isItOK = false;
        while (true) {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        t = null;
    }

    public void resume() {
        isItOK = true;
        t = new Thread(this);
        t.start();
    }


    @Override
    public void run() {
        // TODO Auto-generated method stub
    }
    }

これはLayoutCanvasクラスです。

    public class LayoutCanvas extends Activity implements OnTouchListener{

    RelativeLayout rl;
    SeekBar sb;
    CustomViewVisual1 cView;

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_layout_canvas);

        cView = new CustomViewVisual1(this);
        cView.setOnTouchListener(this);

        rl = (RelativeLayout) findViewById(R.id.lay_canvas);
        rl.setOnTouchListener(this);
        rl.setOnLongClickListener(new OnLongClickListener(){
            @Override
            public boolean onLongClick(View v) {
                // TODO Auto-generated method stub
                Log.d("on long touch", "keep touching");
                return false;
            }});

        sb = (SeekBar) findViewById(R.id.sb_activity_layout_canvas);
        sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                Log.d("in progress changed", "before if() "+progress);
                if(progress > 0 && progress <=10){ 
                    Log.d("in progress changed", "in if() " + progress);
                    cView.setCanvasScale(progress);
                    cView.invalidate();
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }});

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        Log.d("on touch", "Just touched");
        cView.x = (int) event.getX();
        cView.y = (int) event.getY();
        Log.d("cView x = ", ""+cView.x);
        Log.d("cView y = ", ""+cView.y);
        cView.invalidate();
        return false;
    }



    }

そしてこれはレイアウト.xmlファイルです:

  <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" 
        android:id="@+id/lay_canvas">

        <SeekBar
            android:id="@+id/sb_activity_layout_canvas"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@+id/button1"
            android:layout_alignParentLeft="true"
            android:max="10" />

         <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@+id/button2"
            android:text="Button" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:text="Button" />

        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_toRightOf="@+id/button2"
            android:text="Button" />

        <com.anvil.thesis.CustomViewVisual1
            android:id="@+id/myView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/sb_activity_layout_canvas"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true" />

    </RelativeLayout>
4

1 に答える 1

2

問題は、カスタムビューのインスタンスが2つあることです。setContentView(R.layout.activity_layout_canvas);1つ目は、呼び出してレイアウトファイルが膨らんだときに作成されます。このインスタンスはビュー階層に追加されます。明示的に作成する2番目のもの

cView = new CustomViewVisual1(this);
cView.setOnTouchListener(this);

ただし、これはビュー階層に追加されることはありません。つまり、実際には画面に表示されていないため、onTouch呼び出し時にcView.invalidate();描画されません。cView

これを行うために必要なことはcView、次のようなレイアウトで拡張されたカスタムビューを参照することです。

cView = (CustomViewVisual1)findViewById(R.id.myView1);
于 2012-09-20T15:56:16.143 に答える