0

I'm currently developing an Android App, using a personal SurfaceView and double buffering. However I'm facing a little problem with my code.
In one hand I have an xml view, based on LinearLayout hierarchy. When I instantiate my activity, I set my contentView on this xml. The problem is then that my double buffering don't works anymore. Thread is running but nothing is displayed.
In the other hand, I set my contentView with a new personal SurfaveView element and display works fine. But of course, I cannot access anymore to the other elements of my LinearLayout.

Actually, I would like to set my contentView on my xml view AND keep my display working.

I hope I was clear enough, thank you for your answers!

Here is my activity:

public class MainController extends Activity {
    @Override
    protected void onCreate(final Bundle p_savedInstanceState) {
        super.onCreate(p_savedInstanceState);
        setContentView(R.layout.main_controller_activity);

        this.drawableView = (MCustomDrawableView) findViewById(R.id.drawingBox);

        ...
    }
    ...
}

My surface view:

public class MCustomDrawableView extends SurfaceView {
    public MCustomDrawableView(Context p_context, AttributeSet p_attributes) {
        super(p_context, p_attributes);

        this.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(final SurfaceHolder p_holder) {
                try {
                    // Instantiating a new thread
                    thread = new MBufferingThread(getInstance());

                    thread.start();

                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            }

            @Override
            public void surfaceChanged(final SurfaceHolder p_holder, int p_format, int p_width, int p_height) {...}

            @Override
            public void surfaceDestroyed(final SurfaceHolder p_holder) {...}
        });

        // Setup drawing options
        setupDrawing();
    }
    ...
}

And my xml view:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:background="@color/app_background"
    tools:context=".MainController">

    <com.iskn.calligraphy.models.draw.MCustomDrawableView
        android:id="@+id/drawingBox"
        style="@style/DrawingBox" />

    <SeekBar
        android:id="@+id/brushSize"
        style="@style/SizeSeekBar" />

    <SeekBar
        android:id="@+id/brushOpacity"
        style="@style/OpacitySeekBar" />

</LinearLayout>

EDIT:
After further researches and analyses, it appears clearly that:

  • setContentView(R.layout.main_controller_activity): in this case I get all the elements from my activity, but the MCustomDrawableView display nothing.
  • setContentView(new MCustomDrawableView(getApplicationContext())): on that case, MCustomDrawableView is working well (it displays what I want), but I don't have the others View from my main_controller_activity

In both cases:

  • my thread is running and works well.
  • my drawing function is called as well, with the holder.lockCanvas() and holder.unlockCanvasAndPost(bufferCanvas) methods.
Sierra
  • 591
  • 9
  • 28
  • What is a "personal" SurfaceView? SurfaceView is already double- or triple-buffered, why are you adding more buffering? If the problem is with the buffering or the drawing, you should show that code. – fadden Jan 05 '15 at 16:59
  • Thank you for your answer. What I called "personal" SurfaceView is just my MCustomDrawableView class, which extends SurfaceView. In my case, double buffering allows me to perform drawing action on buffered canvas. Then, I post this canvas on displayed one (main). Actually this part works well, my only problem is the link between my main activity, and this class which extends SurfaceView. – Sierra Jan 05 '15 at 18:13

1 Answers1

0

Well, I found a functionnal solution :

I think the problem was coming from the MCustomDrawableView initialization . I created a new instance of that class from the onCreate method , and not from the xml file . Then, I set it to the contentView:

   protected void onCreate(Bundle p_savedInstanceState) {
        super.onCreate(p_savedInstanceState);
        setContentView(R.layout.main_controller_activity);

        // Instantiate drawable object & set style properties
        this.drawableView = new MCustomDrawableView(getApplicationContext());
        FrameLayout.LayoutParams style = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT);

        // Add the drawable view to the main_activity
        addContentView(this.drawableView, style);
    } 

But this way raises a new problem. The added view is on the top, which means that all the others View are hided. I solved this with bringToBack(this.drawableView) below method:

private void bringToBack(View p_view) {
    // Get parent from the current view
    ViewGroup viewGroup = ((ViewGroup) p_view.getParent());

    int childrenCount = viewGroup.indexOfChild(p_view);
    for(int cpt = 0; cpt < childrenCount; cpt++) {
        // Move the child to the top
        viewGroup.bringChildToFront(viewGroup.getChildAt(cpt));
    }
}

It brings back the provided view to the background position. I also had to set the LinearLayout's alpha to 0.

I'm still open to other solutions!

Sierra
  • 591
  • 9
  • 28