I have a TextView in my application that works fine until I pause the application (by pressing home) and launch it again. It should just resume the activity, but for some reason the TextView doesn't display the text properly after it resumes the activity. The text is showing up as black squares, like this:
http://i.stack.imgur.com/5mtvy.png
Does anyone know how to fix this?
EDIT: Here's my code:
The TextView is created in a layout xml that has a GLSurfaceView (called GameView) and on top of that a TextView. Here's the xml code:
<RelativeLayout 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"
tools:context="MainActivity" >
<GameView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/gv"
/>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:textColor="#android:color/black"
android:id="#+id/tv" />
</RelativeLayout>
And here is the code in the MainActivity class onCreate method:
setContentView(R.layout.activity_main);
GameView gameView = (GameView) findViewById(R.id.gv);
TextView textView = (TextView) findViewById(R.id.tv);
The onPause, onResume, onStart, onStop methods have nothing related to the TextView.
The TextView is saved into an instance variable for MainActivity and later, TextView.setText() is called to set the text of the TextView.
EDIT: I was able to fix this problem by commenting out one line: GLES20.glDeleteTextures(...) that was being called onPause() I have NO idea how this is even related or why calling this function caused that issue, but when I comment it out the problem goes away and when I bring this line back the problem comes back with it. If anyone can explain how one relates to the other, it would be greatly appreciated.
Check what u have in on start and on stop methods, it is for sure painting what u have typed earlier.
Try putting
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
TextView textView = (TextView) findViewById(R.id.tv);
textView.forceLayout();
}
Let me know if this solves your problem or not?
I encountered the same situation.
Just make sure your deleting view(which uses opengl) texture action in the thread you created it.
In your case, GameView is the key.
Related
I really didn't want to post it here because this problem sounds really stupid and is difficult to describe, but after hiting my head 2 hours for a stupid layout problem i decided to try
I've one activity with several layout components...
During on create all components are set to be invisible just one keeps visible.
When user presses the button, all components turn visible
when presses button again, all components SHOULD turn invisible again
ALL COMPONENTS VISIBILITY IS ADJUST IN ONLY ONE METHOD
so the activity looks like:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_giveaway, R.id.mainView);
/*lots of stuff*/
//last thing
makeVisible(View.INVISIBLE);
}
private void makeVisible(int visi) {
findViewById(R.id.cardView).setVisibility(visi);
((ViewGroup) findViewById(R.id.influencerLayout)).setVisibility(visi);
this.recyclerView.setVisibility(visi);
}
the problem: is on second click all components get invisible but one keeps on screen
the component which stays on is a cardview
Mainlayout:
<RelativeLayout 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"
tools:context="com.tomatedigital.giveawaymaster.activity.NewGiveawayActivity">
//lots of stuff//
<include layout="#layout/giveaway" />
layout/giveaway is:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="#dimen/giveawayCardHeight"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true">
//lots of other stuf
</cardview>
It's the first thing i set visible on controller method but the only which doesn't go back invisible
REPEATING: there is no other calls to setVisibility other than these, all visibitilities are controled just under that method
I didn't post the whole activity code here because is way long
==========UPDATE==========
Just to clarify:
1- the cardview is one separated layout file re-used several places
2- there is only one cardview in the mainlayout
3
if i remove makeVisible(View.INVISIBLE)from onCreate(), all stuff stays visible,
if i call makeVisible(View.INVISIBLE) and never call makeVisible(View.VISIBLE) all stuff stays invisible
but if I invisble->visible->invisible everything goes invisible but cardview keeps visible
When you want to set the whole layout to Invisibility state, you need to do it in your include #layout/giveaway.xml. Becouse it is a view too.
Like we talk in comments...
Background
I have a rather complex layout being shown to the user in an activity.
One of the views is an EditText.
Since I had to make one of the views stay behind the soft-keyboard, yet the rest above it, I had to listen to view-layout changes (written about it here).
The problem
I've noticed that whenever the EditText has focus and shows its caret, the entire view-hierarchy gets re-layout.
You can see it by either looking at the log of the listener I've created, or by enabling "show surface updates" via the developers settings.
This causes bad performance on some devices, especially if the layout of the activity is complex or have fragments that have complex layouts.
The code
I'm not going to show the original code, but there is a simple way to reproduce the issue:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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"
tools:context="com.example.user.myapplication.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="just some text"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone"
android:text="write here"
android:textSize="18dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="just some text 2"/>
</LinearLayout>
</FrameLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(android.R.id.content).getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
#Override
public boolean onPreDraw() {
Log.d("AppLog", "onPreDraw");
return true;
}
});
}
}
What I've tried
When disabling the caret (using "cursorVisible", which for some reason is called a "cursor" instead) , I can see that the problem doesn't exist.
I've tried to find an alternative to the built-in caret behavior, but I can't find. Only thing I've found is this post, but it seems to make it static and I'm not sure as to how well it performs (performance and compatibility vs normal caret).
I've tried to set the size of the EditText forcefully, so that it won't need to cause invalidation of the layout that contains it. It didn't work.
I've also noticed that on the original app, the logs can (for some reason) continue being written even when the app goes to the background.
I've reported about this issue (including sample and video) here, hoping that Google will show what's wrong or a fix for this.
The question
Is there a way to avoid the re-layout of the entire view hierarchy ? A way that will still let the EditText have the same look&feel of normal EditText?
Maybe a way to customize how the EditText behaves with the caret?
I've noticed that whenever the EditText has focus and shows its caret,
the entire view-hierarchy gets re-layout.
This is not true. Size and position of EditText is constant - there is no re-layouting. You can check it by using code below.
findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Log.d("AppLog", "Layout phase");
}
});
Because of blinking caret - EditText constatly calls invalidate(). This forces the GPU to draw EditText again.
On my nexus 5 (marshmallow) I see that only EditText beeing redrawn (Show GPU view updates - enabled).
How about overriding dispatchOnPreDraw() all the vies you use in activity and having flag to check whether that specific view needs to redraw ?
As you need to disable redraw of all other views only when a text view is on focus. So when a text view is on focus have a flag to disable the redrawing of other views.
if dispatchOnPreDraw() method returns false then refreshing of view will be continues else not. I don't know how complex is your layout and how many views are used, but here a separate class should extent a view used and override that method, and also need a mechanism/variable to distinguish the object in current focus.
Hope this method helps!
In Xamarin, I have a simple Activity that loads up with a five second wait before another Activity is loaded.
The first Activity has an image as part of the Layout, yet this image is not being displayed.
Here is my Activity code:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.SplashActivity);
Thread.Sleep(5000);
var testActivity = new Intent (this, typeof(TestStartup));
StartActivity (testActivity);
}
Here is my SplashActivity layout code:
<?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"
android:background="#color/background_color">
<ImageView
android:src="#drawable/Splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/SplashImage"
android:layout_gravity="center_vertical" />
</LinearLayout>
The application waits five seconds, and then the TestStartup Activity loads, however, the image is not displayed during the five second wait. How can I display this image while the Activity waits five seconds?
Can I please have some help with this code?
Thanks in advance
It is not shown because you are blocking the UI Thread with
Thread.Sleep(5000);
You should get rid of this kind of logic. Relying on x secs it is always wrong. The computation you are waiting for could be ready before, making the remaining waiting period a wast, or could require more the x secs. To "fix" your issue you can use Handler.postDelayed(Runnable, 5000), and put the logic you need to be executed inside the run method. This way, at least, the UI Thread will not be blocked
You might want to take a look at Xamarin's tutorial for creating splash screens in Android:
http://developer.xamarin.com/guides/android/user_interface/creating_a_splash_screen/
It looks like you were on the right track, but they use a theme rather than setting the content view. As previously mentioned, your layout isn't being displayed because your sleep method is blocking the UI Thread. Using a theme is a good way to get around this, and you can reuse a lot of what you already have.
Im having a few issues with a game that Im making
First of, im making a Tower Defence game and, has you probably know, in a Tower Defence game, the "Monsters" in the game changing their routes every time you block them with a Turret.
Now, the main idea is that when you build a turret the monsters will recalculate their route. The route is calculated like this: before the monster is created it gets a Trail object that gets a direction, a starting point and an ending.
The Trail has an X and Y that increases every call and checks if a turret is located in that coordinates. If a turret is located, the Trail creates 2 new Trail objects, gets the correct one and adds it to himself, that creates a recursive object.
Now I dont know how to write all of this in Java, and if I go with this method, that it will take alot of resources (I think).
The second problem that I have is about drawing a layout over a SurfaceView.
I made a pause button, and when im clicking it the main Thread (the one that draws the game) is supposed to be stopped. Now when the thread is stopped the pause screen should be visible, but the problem is, that if the thread stops, any touch on the screen wouldn't be detected. So I tried to create a RelativeLayout, add to it the Surface and inflate the pause.xml file that containes a FrameLayout with 2 buttons: Resume and Quit, and when the pause button is clicked the FrameLayout should be visible but thats not working.
(I tried again with RelativeLayour instead, but that didn't work either)
Thanks, and if you didn't understanded something please tell me and I will try to be more understandable.
EDIT - THE CODE
pause.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pauseContent"
android:background="#AA000000"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:visibility="invisible">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<Button
android:id="#+id/resume"
android:layout_width="100px"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Resume" />
<Button
android:id="#+id/quit"
android:layout_width="100px"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#id/resume"
android:text="Quit" />
</RelativeLayout>
</RelativeLayout>
GameActivity.java
public class GameActivity extends Activity {
private RelativeLayout mainLayout;
private GameView gameView;
private RelativeLayout pauseContent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainLayout=new RelativeLayout(this);
LayoutInflater inflater=(LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View v=inflater.inflate(R.layout.pause, null);
pauseContent=(RelativeLayout) v.findViewById(R.id.pauseContent);
gameView=new GameView(GameActivity.this, getWindowManager().getDefaultDisplay().getWidth(), getWindowManager().getDefaultDisplay().getHeight());
mainLayout.addView(gameView);
mainLayout.addView(pauseContent, new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
setContentView(mainLayout);
}
}
(I deleted some of the code that wasn't needed to be shown)
In my game I created a Button object that works like the android UI Button (with the click listener...), now, I created the pause button that when he will be clicked, the pause layout should be visible - that doesn't works.
I have an xml layout for a Fragment (android.support.v4.app.Fragment). When this Fragment is added for the first time, the background drawable displays fine. But when this Fragment is replaced with another Fragment, then later replaced back in again (by creating a new instance and using FragmentTransaction.replace()), the background drawable disappears (but not in all cases, see below). Here is the layout xml for the Fragment:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include layout="#layout/footer_photos" />
<RelativeLayout
android:id="#+id/pageLayout"
android:background="#drawable/body_background2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#id/footer">
<ImageView
android:id="#+id/page"
android:layout_height="500dp"
android:layout_width="400dp"
android:layout_centerInParent="true"
android:background="#FFF" />
</RelativeLayout>
</RelativeLayout>
The background drawable in question is in the RelativeLayout with the id "pageLayout".
Possible clues:
When I remove the ImageView in there, the background drawable shows up fine.
The other Fragments have similar layout xmls (with the same background drawable), but without ImageViews inside of them, and they work fine.
One of these Fragments has a WebView and buttons inside of it, and this one's background shows up fine.
After replacing the "WebView Fragment" with the Fragment in question, the background shows up fine (!?).
EDIT: The same issue consistently occurs if an image is loaded into the ImageView then a dialog-themed activity is launched on top of it, then finished. My solution below fixes both cases.
Found a better solution than my last one. In onResume() for the Fragment, just need to do:
getView().post(new Runnable() {
#Override
public void run() {
View v = getView();
if (v != null)
v.invalidate();
}
});
It causes a flicker, but at least it seems to work consistently.
i had a similar problem. With a relativelayout, there was an imageView and a textView.
I resolved with a call to bringToFront method:
myImageView.bringToFront();
Hope this helped.
Okay, I fixed this issue while trying to fix another issue. The issue was solved by calling setLayoutParams() on the page ImageView (with whatever layout params). This caused the background of the pageLayout RelativeLayout to show up again. The cause of the issue remains unknown...
The fragments are replaced , along with their background, which means that
when a fragment A is replaced by fragment B, the background changes to the background of fragment B.
If you don't give any background to fragment B, then you can see fragment B over fragment A.