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:
holder.lockCanvas()
and holder.unlockCanvasAndPost(bufferCanvas)
methods.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!