cómo hacer que la vista personalizada se invalide de la actividad

I've an app where i'm wanting to place 2 circles on a bitmap. i've got 2 buttons, one for increasing the radius and one for decreasing the radius. The buttons are inflated from xml in the activity. the activity's view is a custom view. i can get the buttons to show on the view and the both alter the radius variable accordingly. so far so good. i can't get the view to invalidate when either button is clicked. what should happen, is when the button is clicked the radius is changed then the canvas redrawn to show the radius changes. How can i call invalidate from the onclick()? I'm not sure if this is the best way of doing this. thanks. .

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Jjilapp extends Activity {




    private static final String TAG = "*********jjil";


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

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.touchview);
        final TouchView touchView = (TouchView)findViewById(R.id.touchview); 
        final HorizontalSlider slider = (HorizontalSlider)findViewById(R.id.slider); 
        touchView.initSlider(slider);

        Button plus = (Button)findViewById(R.id.plus);
        plus.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Log.e(TAG, "onClickplus");
                TouchView.setRadius(TouchView.getRadius() + 5);
                Log.e(TAG, "radius = "+TouchView.getRadius());
            }}) ;





         Button minus = (Button)findViewById(R.id.minus);
         minus.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub

                TouchView.setRadius(TouchView.getRadius() - 5);
                Log.e(TAG, "radius = "+TouchView.getRadius());

                TouchView.invalidate();// DOESN'T WORK***************

            }}) ;







    }//end of oncreate




}//end of jjilapp

.

public class TouchView extends View{



    private static int radius = 50;




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

    }




    public TouchView(Context context, AttributeSet attr) {
        super(context,attr);
        Log.e(TAG, "++++++++++ inside touchview constructor");





    pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);         
    pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT)); 
    pTouch.setColor(Color.TRANSPARENT);
    pTouch.setStyle(Paint.Style.STROKE);


    }// end of touchView constructor






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

        Log.e(TAG, "******about to draw bgr ");
        canvas.drawBitmap(bgr, 0, 0, null);



       canvas.drawCircle(centreX, centreY, radius,pTouch);
       canvas.drawCircle(centreA, centreB, radius,pTouch);
        }

    }//end of onDraw



    public static int getRadius() {
        return radius;
    }




    public static void setRadius(int r) {
        radius = r;
    }




}

preguntado el 27 de agosto de 11 a las 18:08

I'm confused. What's wrong with touchView.invalidate();? -

2 Respuestas

Por qué son radius and the associated get/set methods static? That means that even if you had several TouchViews in your app at once, all of them would always have the same radius.

Start by removing static from those three things so that each TouchView has its own radius. Next, instead of invoking your TouchView métodos del TouchView class itself, invoke them from your actual TouchView instance which you named touchView above. (e.g. touchView.setRadius(...) en lugar de TouchView.setRadius(...).)

invalidate is not a static method of a View so you cannot invoke it as one. Views should invalidate themselves when their properties change that would require them to redraw. Since radius is one such property for your TouchView debería llamar invalidate() on itself at the end of the setRadius method. This will let you remove any direct invalidate calls from your Activity where they don't belong.

Respondido 27 ago 11, 22:08

thanks for that info. the way you described is the way views ought to update themselves. i'll change the setter to refect this.:) - chico tortuga

You are using the class's function and not the object, meaning you use :

TouchView.function()

en lugar de

touchView.function()

invalidate is not a static function, so you need to call it directly on the object itself. Don't forget to use postInvalidate() in case you are updating the view from a non-UI thread.

Respondido 27 ago 11, 22:08

OnClickListeners will always be invoked from the UI thread and any correct Android code will never update views from a thread other than the UI thread. (That's why it's called the UI thread. :) ) - adamp

well, this is why id didn't say "change your code to...". I only thought it's worth mentioning, that in a case of a call from a non-ui thread, postInvalidate is in order. - Raanan W

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.