Adding View to Relative Layout behind an existing view causes screen flicker - android

I'm trying to insert a View behind another view that is taking up the full screen and then later removing the view in the front to reveal the only remaining view. Functionally, everything is working as expected but the problem is that when I call View.addView() to add the second view, specifying to add it at index 0 so it is behind the first view, the screen flickers. It's almost as if the view is actually getting added in front of the first view for a fraction of a second and then it is hidden again as it is moved behind it.
Here's what I'm doing:
When the Activity is created I add an ImageView to a RelativeLayout and make the RelativeLayout instance the Activity's content view:
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
m_layout = new RelativeLayout(this);
m_layout.setBackgroundColor(Color.BLACK);
m_splashImage = new ImageView(this);
m_splashImage.setImageResource(R.drawable.splash);
m_splashImage.setScaleType(ScaleType.FIT_XY);
m_layout.addView(m_splashImage,
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
setContentView(m_layout);
}
When the Activity is started, I created and add the GLSurfaceView to the RelativeLayout at index 0, so it is behind the ImageView:
protected void onStart() {
super.onStart();
m_layout.addView(new MyGLSurfaceView(), 0,
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT));
}
Later, after all of the loading is done and the GLSurfaceView is ready to continuously render,
the splash ImageView is removed and cleaned up.
public void hideSplashScreen() {
if (m_splashImage != null) {
m_layout.removeView(m_splashImage);
m_splashImage = null;
}
}
Is there a better way to do this that doesn't require creating the GLSurfaceView before the onStart() is called?

Have you tried using view.setVisibility(View.GONE) on of the view that you adding behind? Of course before you are adding it.

Related

TransitionManager.beginDelayedTransition blinks

I'm trying to provide a fullscreen button for my camera view which is in my app. Unfortunately, during the transition, the app is showing newly calculated params before the actual animation. I mean, the new dimensions of camera view are seen for a while (blinks), then the screen is becoming black and in the end, the animation of expanding is done. This is how I do it:
fullScreenBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isFullScreen){
TransitionManager.beginDelayedTransition(transitionsContainer);
fragmentContener.setVisibility(View.VISIBLE);
hudView.setVisibility(View.VISIBLE);
mCameraContent.setLayoutParams(params);
isFullScreen = false;
} else {
TransitionManager.beginDelayedTransition(transitionsContainer);
fragmentContener.setVisibility(View.GONE);
hudView.setVisibility(View.GONE);
mCameraContent.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
isFullScreen = true;
}
}
The fullScreenBtn is in the mCameraContent layout on the camera preview in the corner. transitionContainer is the whole activity layout. I think it is worth noting that my activity layout is divided into two equal views: baseContener and fragmentContener, the hudView is inside the baseContener below mCameraContent. They are fading out properly, the only problem is with camera preview. I was trying to add Slide() or ChangeBounds() into beginDelayedTransition method but that doesn't solve the problem. What should I do to avoid that view blinking?

Animating a TextView appearing on activity creation

I want to show an animation of a TextView appearing when an activity is created. What I want is to show the activity without the TextView and then the TextView appearing (ideally, flying from outside) in its final position without user interaction.
I've tried to use the transition framework from API level 19 by having the TextView with visibility gone in the XML layout and setting it to visible in onCreate() with this code:
ViewGroup layout = (ViewGroup) findViewById(R.id.main_layout);
TransitionManager.beginDelayedTransition(layout, new ChangeBounds());
textView.setVisibility(View.VISIBLE);
This doesn't work. However, if I don't do this in onCreate() but as a response to a button click, it works. I think that the problem is that the layout is not created yet, so when I set the visibility to visible in the onCreate(), the layout is created with the final state and there aren't two scenes for the TransitionManager to work.
I've tried putting the code in onPause() but the result was the same. Any ideas how this should be done?
Try onWindowFocusChanged() like this
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if(hasFocus){
// start your animation here
}
}
You should do this in onResume() after the layout has been created. Initially the visibility would be Invisible and then the view will animate.
try like this:
ViewGroup layout = (ViewGroup) findViewById(R.id.main_layout);
layout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
TransitionManager.beginDelayedTransition(layout, new ChangeBounds());
textView.setVisibility(View.VISIBLE);
}
});
because your view should be able to animate only after it's creation

How to destroy a Layout?

I'm developing an Android app in which I use LayoutInflator to generate new layout. What the app does basically is - Its has one imageview. When I click on a button, I change the layout to display multiple ImageViews (like 2x2 or 4x4). I am successful in displaying these layouts using the LayoutInflator. However, the previous Layout stays intact and the new Layout is displayed over the old Layout which, kind of, messes the whole layout. My question is - is there anyway to destroy the old layout before displaying the new one?
Edit:
Here is the code (on the onClick event that I'm using)
public void oneby1onClick(View view){
RelativeLayout main = (RelativeLayout)findViewById(R.id.main_layout);
view = getLayoutInflater().inflate(R.layout.activity_main, main,false);
main.removeView(main);
main.addView(view);
}
public void twoby2onClick(View view){
RelativeLayout main = (RelativeLayout)findViewById(R.id.main_layout);
view = getLayoutInflater().inflate(R.layout.twoby2, main,false);
main.removeView(main);
main.addView(view);
}
public void fourby4onClick(View view){
RelativeLayout main = (RelativeLayout)findViewById(R.id.main_layout);
view = getLayoutInflater().inflate(R.layout.fourby4, main,false);
main.removeView(main);
main.addView(view);
}
Maybe you could just make your layout invisible if that is the case.
This can be done quite easily programmaticaly:
layout.setVisibility(View.GONE);
According to #ookami.kb's suggestion I should use main.removeAllViews(); instead of main.removeView(main);, that helped me.

Getting window size before adding controls

I have a custom view with a public function that adds a control as a child of the view, and I want to call it from my activity. The problem is that I need to know the size of the view in the function in order to place the control. I can't override onMeasure to get the measures because my view inherits from another custom view in which this function is final. I tried overriding measureChildren, but it gets called too late (even after onResume on the activity in which the view is placed in). What can I do in order to have the size before the activity calls the function in the view?
One possibility is to measure your view back in the activity then set properties of the view for it's internal methods to use.
Using a global layout listener has always worked well for me. It has the advantage of being able to remeasure things if the layout is changed, e.g. if something is set to View.GONE or child views are added/removed.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null);
// set a global layout listener which will be called when the layout pass is completed and the view is drawn
mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
// at this point, the UI is fully displayed
}
}
);
setContentView(mainLayout);
http://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.html
If you want the the display dimensions in pixels you can use getSize:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

How to add view components dynamically from activity

I am attempting to create a user interface dynamically. I have successfully create a view and loaded my background image. I have created two additional small view items to display on the background. My problem is that I have not been able to find any advice/instruction that tells me how to draw the small views. It seems that it should be a trivial exercise and I am guessing it is just finding the correct referencing. Hope someone out there can point me in the right direction.
Here is my Activity:
public class GhostActivity extends Activity implements OnTouchListener
{
private DrawView ghostView;
public Card mCard1, mCard2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
// ToDo add your GUI initialization code here
super.onCreate(savedInstanceState);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
ghostView = new DrawView(this);
setContentView(ghostView);
//get the window size
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Context context = getApplicationContext();
//create view items with initial positions
Point startPoint;
startPoint = new Point();
startPoint.x = 5;
startPoint.y = 3;
mCard1 = new Card(context, 1, R.drawable.bol_geel, startPoint);
startPoint.x = 5;
startPoint.y = 43;
mCard2 = new Card(context, 2, R.drawable.bol_rood, startPoint);
//now display them on the ghostView *****************HOW?
// set the callbacks
ghostView.setOnTouchListener(this);
mCard1.setOnTouchListener(this);
mCard2.setOnTouchListener(this);
}
and here is the View;
public class DrawView extends View
{
Drawable bg ;
public DrawView(Context context) {
super(context);
//setFocusable(true);
Drawable bg = this.getResources().getDrawable(R.drawable.bubbleblue480x800);
setBackgroundDrawable(bg);
}
#Override protected void onDraw(Canvas canvas) {
// canvas.drawColor(0x0000000); //if you want another background color
//draw on the canvas
}
}
edit: I believe my problem is needing to pass a pointer to the ghostView canvas. what makes me think that is if I create the children within ghostView then call their .draw method they appear exactly as I would expect.
#Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0x0000000); //if you want another background color
//draw the cards on the canvas
mCard1.draw(canvas);
mCard2.draw(canvas);
}
so at this point I am wondering how to get a reference pointer to the ghostView canvas.
To be honest I am finding the whole Activity - View relationship confusing.
Edit: I have taken a different approach based on detail in this tutorial
http://www.kellbot.com/2009/06/android-hello-circle/
It uses a FrameLayout and it seems I can achieve my objective.
To add view dynamically to view your class must extends from ViewGroup or LinearLayout class then you will able to call method addView.
Inside your ghost view first add a layout e.g Linear or Relative. Then only you could able to add views inside that layout you cant simply add a view to a xml file.
Or you can create a dynamic layout then only u can add view inside that layout.
RelativeLayout relative= new RelativeLayout(findViewById(R.id.your relativeLayoutID));
relative.addView(child);
child could be anything button textview and widget.

Categories

Resources