I created my own SurfaceView, which works fine on its own, but when I try to put two on separate tabs in a TabWidget, only one of them is displayed no matter which tab is selected, and it is always a SurfaceView that first appears when the application starts.
To illustrate the problem, I created a code sample that can be compiled to display the problem.
The SurfaceView below, called SurfaceViewCircle, simply creates a bitmap, draws a blue circle by default, and then displays it. There is a public changeColour () method that will change the color of a circle in a bitmap.
Secondly, I am creating an XML layout that simply contains one instance of SurfaceViewCircle.
In the Activity class, I create a TabWidget and host, etc. Then I inflate the above XML twice, but in one case, I change the color of the SurfaceViewCircle to red. After launching the application no matter which tab I select, the red circle ALWAYS displays EXCEPT for a brief instance when the application exits and the blue circle is displayed.
Can someone please indicate if I skipped a step when using SurfaceView?
This is the operation code:
public class TestActivity extends Activity { private TabHost mTabHost; private Context mTabHostContext; private View surfaceView1, surfaceView2; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.maintabs); setupTabHost();
This is my custom SurfaceView:
public class SurfaceViewCircle extends SurfaceView implements SurfaceHolder.Callback{ private Paint paint, circlePaint; private Bitmap bitmap = null; private int w; private int h; private int colour = 0; private Resources r = null; private _Thread t = null; private boolean surfaceIsCreated; public SurfaceViewCircle(Context context) { super(context); initialise(); } public SurfaceViewCircle(Context context, AttributeSet attrs) { super(context, attrs); initialise(); } public SurfaceViewCircle(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initialise(); } private void initialise(){ r = getResources(); getHolder().addCallback(this); paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setFilterBitmap(true); colour = R.color.blue_square; circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG); circlePaint.setColor(r.getColor(colour)); circlePaint.setStyle(Style.FILL); circlePaint.setStrokeWidth(0.02f); t = new _Thread(getHolder()); } public void changeColour(int colour){ circlePaint.setColor(colour); if (surfaceIsCreated){ createBitmap(); } synchronized (t){ t.notify(); } } private Bitmap createBitmap(){ Bitmap b = null; b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); c.scale((float)w, (float)w);
Maintabs.xml file:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="0dip" android:layout_marginRight="0dip" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> </TabHost> </LinearLayout>
And surfaceviewindependent.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <uk.co.androidcontrols.gauges.SurfaceViewCircle android:id="@+id/circle1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="0.5" android:layout_margin="1dip"> </uk.co.androidcontrols.gauges.SurfaceViewCircle> </LinearLayout>
I also noted that someone had a similar problem here.
Apologies for the poor formatting, but the code editor is almost impossible to use for large code quotes!
Additional Information
I tried to use setVisibility()'
in onvisibilityChanged()
, but this ultimately onvisibilityChanged()
exception:
protected void onVisibilityChanged(View changedView, int visibility){ super.onVisibilityChanged(changedView, visibility); changedView.setVisibility(visibility); Log.i("SurfaceViewCircle", "onVisibilityChanged() called."); } java.lang.IllegalThreadStateException: Thread already started.
It seems that calling changedView.setvisibility()
destroys the surface every time.