Search code examples
androidsurfaceviewandroid-custom-view

How to draw a custom view inside a SurfaceView?


I am having trouble putting all the pieces together. I have 3 classes: DefaultActivity that extends Activity, MyView that extends SurfaceView, and ResistorView that extends a View.

What I want to know is how draw a resistor every time I click the button bAddResistor from the DefaultActivity class? Here are some parts from the 3 classes:

DefaultActivity.java

public class DefaultActivity extends Activity {

    //MyView myView;
    TextView myText;
    ResistorView myResistor;

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

        //myView = (MyView) findViewById(R.id.my_view);
        //myView = new MyView(this, null);    
        //myResistor = new ResistorView(this);
        //myView.setBackgroundColor(Color.WHITE);
        //myView.setScrollContainer(true);
        setContentView(R.layout.main); 


        final Button bAddResistor = (Button) findViewById(R.id.bAdd);

        bAddResistor.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            // Perform action on click                 

            Global.numberOfResistors++;                
            Log.d("ButtonADD", "Button Add has been clicked");
            }
        });
    }
}

MyView.java

public class MyView extends SurfaceView implements SurfaceHolder.Callback { 
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);    
        getHolder().addCallback(this);    
    }        

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

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Canvas c = holder.lockCanvas();
        onDraw(c);
        holder.unlockCanvasAndPost(c);        
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub    
    }
}

ResistorView.java

public class ResistorView extends View {
    private Path mSymbol;
    private Paint mPaint;

    //...Override Constructors...
    public ResistorView(Context context) {
        super(context);
        init();
    }

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

    private void init() {
        mSymbol = new Path();
        mPaint = new Paint();

        mPaint.setAntiAlias(true);        
        mPaint.setStrokeWidth(2);
        mPaint.setColor(-7829368);
        mPaint.setStyle(Paint.Style.STROKE);

        //...Your code here to set up the path,
        //...allocate objects here, never in the drawing code.

        mSymbol.moveTo(0.0F, 0.0F);
        mSymbol.lineTo(0.0F, 50.0F);
        mSymbol.lineTo(16.666666F, 58.333332F);
        mSymbol.lineTo(-16.666666F, 75.0F);
        mSymbol.lineTo(16.666666F, 91.666664F);
        mSymbol.lineTo(-16.666666F, 108.33333F);
        mSymbol.lineTo(16.666666F, 124.99999F);
        mSymbol.lineTo(-16.666666F, 141.66666F);
        mSymbol.lineTo(0.0F, 150.0F);
        mSymbol.lineTo(0.0F, 200.0F);
        mSymbol.offset(100.0F, 20.0F);
    }

    //...Override onMeasure()...
    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //Use this method to tell Android how big your view is
        setMeasuredDimension(50, 50);
    }

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

        canvas.drawPath(mSymbol, mPaint);
    }        
}

and the main.xml layout

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

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/RightLayout"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentRight="true"
        android:background="#00000000"
        android:orientation="vertical" >

        <Button
            android:id="@+id/bAdd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Add RES" />

        <Button
            android:id="@+id/bDeleate"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Del RES" />

    </LinearLayout>

    <com.defaul.android.MyView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_toLeftOf="@id/RightLayout"
        android:background="#ff000000" />

</RelativeLayout>

If I put the drawing code in MyView.onDraw it works fine, the resistor is drawn. What I want is to click a button and draw the resistor on the surface, so every time I click I want a resistor to be added to the surface view.

Probably I'm approaching this problem in the opposite direction. If anyone can point me in the right direction I would really appreciated it.


Solution

  • Since I could not find a way to do what I wanted with SurfaceView I just created a class that extends View and then just add that view to my main layout.

    In case it might help someone, below is a simplified version of my code:

    public class CircuitSolverActivity extends Activity {
    /** Called when the activity is first created. */ 
    
    RelativeLayout mLayout; 
    MyView mView;
    
    
    @Override    
    public void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);        
    
        mLayout = (RelativeLayout)findViewById(R.id.elementContainer);                
    
    }
    
    public void bAddView(View view){
    
            mView = new MyView(context);            
            mView.setBackgroundColor(Color.TRANSPARENT);            
            mLayout.addView(mView); 
    }
    

    MyView class:

    public class ResistorView extends View {
    
    public ResistorView(Context context, AttributeSet attrs) {
        super(context, attrs);                
        init();        
    }
    
    public ResistorView(Context context){
        super(context);         
        init();
    }
    
    private void init() {
    
        mSymbol = new Path();
        mPaint = new Paint();        
    
        mPaint.setAntiAlias(true);      
        mPaint.setStrokeWidth(2);
        mPaint.setColor(-7829368);      
        mPaint.setStyle(Paint.Style.STROKE);       
    
    
        mSymbol.moveTo(0.0F, 0.0F);
        mSymbol.lineTo(0.0F, 50.0F);        
    
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mSymbol, mPaint);
    }