I'm developing an app with SupportMapFragment and custom view switching mechanism. Right now i styles app, to make its window to be transparent using styles.xml, but with that change i see a strange problem when using maps. When user switches it current view from one that uses map fragment to another, part of screen that was used by map on previous view becames transparent, for about 1 second.
In image below i present some description, on right i marked using yellow color situation than im talking about:
on left side is view that i present map using SupportMapFragment, on the right is one i have switched next, with 2 diffrent views(ImageView and TextView),but yellow part of TextView is transparent like my application window, su user can notice eg. apps menu. This is not what im trying to achive so Im looking way to get rid of this effect.
My code for switching views is like follows:
public void switchAppView(View view){
mMainView.removeViewAt(0);
mMainView.addView(view,0);
}
the mMainView is initialized in onCreate Method, by code:
#Override
public void onCreate(Bundle icicle){
super.onCreate(icicle);
setContentView(R.layout.activity_main);
mMainView = (RelativeLayout) findViewById(R.id.mymain_layout);
}
my activity_main.xml layout presents similar to:
<RelativeLayout
android:id="#+id/mymain_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:id="#+id/replacable"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="visible"
></FrameLayout>
<FrameLayout
android:id="#+id/extra"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="invisible"
></FrameLayout>
</RelativeLayout>
I tried to search clues and situations like that but I didnt find any, so if anyone can help i would be grateful, Thanks for help.
becames transparent, for about 1 second.
I'm guessing you are using black background and you really mean it becomes black.
In that case what you see is a known issue.
You may read more about it here:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=4659
and here:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=4639
Related
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!
I am trying to call a new activity from a fragment. I have a button at the toolbar, and when it is pressed the following code is being called (this event is inside the fragment):
Intent secondactitvity = new Intent(this.Activity,typeof(Activity_SecondActivity));
StartActivity(secondactitvity );
Now the new activity is being called and here is my code inside OnCreate of the new activity:
RequestWindowFeature(WindowFeatures.ActionBar);
ActionBar.SetIcon(Resource.Drawable.icon_toolbar_back_new);
ActionBar.SetCustomView(Resource.Layout.ActionBar_Custom_Layout);
ActionBar.SetDisplayShowCustomEnabled(true);
base.OnCreate(bundle);
SetContentView(Resource.Layout.SecondActivity_Layout);
Here is the SecondActivity_Layout:
<?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">
<TextView
android:text="Text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView1" />
<fragment
class="frag.Fragment_Second"
android:id="#+id/fragment_secondActivity"
android:paddingTop="10dip"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
Here is the layout for the fragment:
<?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:minWidth="25px"
android:minHeight="25px">
<TextView
android:text="#string/secondFragment_name"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView1" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText1"
android:paddingLeft="10dp" />
</LinearLayout>
And here is the fragment code:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.Inflate(Resource.Layout.Fragment_ProjectDetails, container); //view;// base.OnCreateView(inflater, container, savedInstanceState);
}
public override void OnActivityCreated(Bundle savedInstanceState)
{
Toast.MakeText(this.Activity, "activity for second fragment created",ToastLength.Short).Show();
base.OnActivityCreated(savedInstanceState);
}
Now the problem is. The second activity remains empty, it is not being filled with the fragment (but there is not an error message). I would understand it if the fragment cannot be found or something like that, but in this case all the functions from the fragment (onCreateView, onActivityCreated) are being called, and the Toast is also being displayed, but the activity is empty. Then I tried to insert a text view at the top of the fragment inside the second activity layout file, and its being shown but, the controls from the fragment remain un-visible. Then I tried to change the fragment associated to the second activity, I changed it to the fragment which is calling the activity, and this one is being properly loaded (I changed it inside the .axml file).
What am I missing here, for me it seems like the second one is not being created property and thus the controls cannot be displayed (but, I may also be wrong)?
Thank You
well after spending far too much hours on this i got the solution. First thing i have noticed is that i cannot acces Views from the second fragment layout (when trying to read them in code i could not compile). Then i created a new axml file, assigned it as the layout for the second fragment, and the controls are being displayed.
So for me it seems like a bug in Xamarin, somehow the first axml has not been registered accordingly (but funny thing is that i could access the axml per se, but not the controls).
I am somebody who is migrating from Java (Android development) to Xamarin, and i have put a lot of hope on it. But I must admit that after few weeks lots of the first enthusiasm is gone. There is a lot missing in Xamarin and as time is passing by I am more thinking about moving back to Java and start learning Objective C for iOS. This project which i am doing now in Xamarin, i would have done it already if I were using Java, but for now I am still in the early phase (of course it cannot be as fast as in Java because i have to google for everything, but ...). Thers is also the issue with the Resource file, sometimes when my project breaks I cannot stop it from executing and i have to kill Visual Studio via Taskbar. In most cases when I do this the Resource file gets "destroyed" and when I open the project again i cannot start it anymore (in most cases I didnt bother because I was practising and I created a new one, but what if it is a bigger project ?)
The next thing is the missing IntelliSense inside the .axml when the designer is open (when I open it with the xml viewer i get the IntelliSense). Do i have to switch always between these views ?
And now this thing with the fragment, how i am supposed to trust the system if such cruical things dont work right.
Since I am still in the trial period I will give this whole thing a chance, but as I sad, the "fun" working with it is decreasing ...
Sorry for the long post, but just had the need to say :)
I had the same problem and nothing I had done solved it, including removing the layout and adding it again even with different name.
I figured out that I had messed up the method and forgot the override keyword. After this fix, it worked just fine.
As I am actually not very confident with programatically changing Views, I have following problem:
At the first start of my app, I want to have an overlay for the main screen, that tells the user to have a look at the settings, as there are two critical options the user has to configure.
I don't want to use an AlertDialog and rather not use a wizard. So, I decided to take an approach similar to Go SMS and create an overlay at the first start. The mockup I created looks like this:
Normal menu:
First start:
So these are the problems I have:
Like I said, I don't want to use a screenshot overlaying on first start, as this would take too much space and would not be language and screen independent.
I would have the circle as an png, but I don't know how exactly put it over the image
The same problem with the text
And finally I want to put a semi-transparent white over the app. It does not necessarily need the hole for the icon, though it would be nice.
In case you need the Layout Source, you can get it at pastebin
So, I just need to get a start here, if it is better to use LayoutInflater or ViewStub and how to realize it, as I have absolutely no experience with it...
Thanks!
/edit: I uploaded a new, more well-arranged layout.
I have faced a similar problem, I client wanted a walkthrough of the application, where the entire screen had to become whiter (as they said: "transparent"), except for the button being explained by an overlay speech-bubble.
Fortunately for you, your layout is not nearly as complicated as the one I had to work with :)
Now, you can get the transparency-effect in two ways, either have a white background and call all the views setAlpha() methods, or you can create a half-transparent white overlay.
If you go with the overlay, you'll have to find a way to display the opaque buttons through the overlay. This can get a bit complicated.
If you go with the first option, you can just setAlpha(1) on the opaque view to get it to show up.
The setAlpha() method is only available from api version 11+, so if you target an earlier version, you might have to do it in a slightly more complicated way.
Example of setting alpha on views pre-honeycomb:
Layout for your buttons (make them however you want, just make them similar so you can loop through them):
<LinearLayout
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:tag="image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/tile"/>
<TextView
android:tag="text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF000000"
android:text="button1"/>
</LinearLayout>
In your program, when you are want to make the buttons transparent:
LinearLayout l = (LinearLayout) findViewById(R.id.button1);
((ImageView)l.findViewWithTag("image")).setAlpha(0x7F);
((TextView)l.findViewWithTag("text")).setTextColor(0x7F000000);
When you have decided on how you want to create the transparency effect, you will have to decide on how to display the overlay-text/bubble. You'll most likely want to put this in a separate layer on top of your entire layout, to make sure that it is not affected by your new view.
One way to achieve this is by changing your root layout element to a FrameLayout, and then creating/displaying in this. e.g:
<FrameLayout background="#FFFF"> <!-- white background, just in case -->
<LinearLayout>
<!-- the rest of your layout -->
</LinearLayout>
<LinearLayout visibility="gone"> <!-- this will be your overlay view -->
<ImageView /> <!-- the arrow/ring -->
<TextView /> <!-- the description -->
</LinearLayout>
</FrameLayout>
When the introduction is displayed, you set the position of the hidden overlay-view to the position of the table item to be explained, change the text to an appropriate string/resource and display the view.
When the introduction is over, you reset the alpha values of all buttons, and set the visibility of the overlay to gone again.
Since I don't have much experience with ViewStub, I would do it with LayoutInflater.
First of all, you need to have a second layout loaded on top of your current layout. The easiest is to have a FrameLayout, which has as one child your current view, and the dynamically you load the second child on the first start. When you load a content view in an Activity, it will be attached to some already created views (some DecorView, a FrameLayout, etc). So you can either re-use the existing FrameLayout, or you can create a new one.
I would vote for the second solution, since it's more stable (I just mentioned the other possibility in case you want to minimize the number of layers).
So, as a first step, wrap your current layout inside a FrameLayout, and give it an id, let's say "#id/root".
Then, in the onCreate method, you can have something like this:
setContentView(R.layout.main);
if (isFirstRun()) {
ViewGroup parent = (ViewGroup)findViewById(R.id.root); // locate the FrameLayout
LayoutInflater li = LayoutInflater.from(this); // get an instance of LayoutInflater
li.inflate(R.layout.overlay, parent);
}
So far you will have the overlay loaded. Now it's up to you to define the overlay.
To make the whitening effect, just set the following attribute on the root view in your overlay.xml layout:
android:background="#40ffffff"
To position the circle, first you need to find it's location. You can use the View.getLocationOnScreen to get the absolute coordinate of the icon (below the circle) on the screen. Then you can have two options:
either create a custom view (for the overlay) and manually draw the circle at the given location
or add the circle using an ImageView and adjust the left and top margins based on the coordinates
This is my first Android project, so bear with me. I created a custom view ("GameBoard" extends View) for drawing my game board and pieces by overriding the OnDraw. It all works fine. However, I'd like to add a tween-animated "You win" graphic at the end of the game. However, I can't figure out how to add an ImageView to my GameBoard view.
I read that I could use an XML file and add my custom view to it, but it didn't work. Here's my XML code:
<?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"
android:background="#001133" >
<view Class = "com.myname.firstgame.GameBoard"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</view>
</RelativeLayout>
I also tried it without the "view Class =" in the view tag. I also tried it without the ".GameBoard" in the view tag and specifying it in the "android:id=" tag. (All these attempts came from Google searches.)
If I can get it to work, I figure I can add an ImageView with my bitmap as the background, place it in the right spot, and animate it. I do a similar thing for my title screen and it works fine, but it uses an XML natively, without a custom view. (In hindsight, I'm wondering if I should have used XML rather than a custom view for the game board, but that's another matter.)
Can anyone help, please?
This seems to answer your question.
http://sankarganesh-info-exchange.blogspot.com/2011/04/performing-animation-in-android.html
just call the target.startAnimation() method when your user wins / loses / whatevers your game
I recently updated my phone to gingerbread and to my horror one of my apps stopped working!
The app consists of a SurfaceView and a layout (view) that shows up as an overlay over this SurfaceView.
THe xml looks like this:
<?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"
>
<com.mycompany.MySurfaceView
android:id="#+id/myview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<include layout="#layout/settings"
android:layout_alignTop="#id/myview"
android:visibility="invisible"
android:id="#+id/settings"
/>
</RelativeLayout>
When the user press the menu button I use this code to show the view:
View settings = (View)findViewById(R.id.settings);
settings.setVisibility(View.VISIBLE);
This worked flawlessy on versions earlier than 2.3 but now the behaviour is very random.
Observations
Very rarely everything works.
Sometimes the view shows up after hiding / unhiding it.
Sometimes you can press the buttons on the view (even though it's invisible) this makes the view show up for the rest of the application lifetime.
The getVisibility method always report the correct value.
What I've tried
Rebuilding draw cache
Using BringToFront method
Post invalidate
Setting the initial value of the view to "visible", this makes everything work, but I really want it to be initially invisible!
If anyone wants to check the problem you can try it for yourself in my app (it's on market, search for "chainparticles").
Thanks!
Solved it by changing the views initial state to "gone". WTF?!