Insert Android view at the top of the view hierarchy - java

I would like to know if it is possible to add a view to the top of the view hierarchy for my Android App. Currently, I have a class that receives information from an external service. I would like to display information received as a custom alert to the user. Is it possible to insert this custom view at the top of the global view hierarchy, so that it shows above all other views. I would prefer not to start a new activity, just add the view on top of what is currently being shown.

Yes. Accessing the root View is as easy as finding it.
In the Activity:
FrameLayout root = (FrameLayout) findViewById(android.R.id.content);
Since the root is a FrameLayout, you just have to add a View to it in order for it to be on top. However, note that the Z-order will change if you add other Views after this one is added. In which case, you'll have to use ViewGroup#bringChildToFront(View view) to bring it back to the top.
EDIT:
It is also possible to get the root view from another View by using View#getRootView(). This is not always reliable as the View may not be attached to the hierarchy (in which case the View itself is the root). Or it's parent may not be in the hierarchy (in which case the Parent itself will be the root).

Related

Is there any event to know if a view is moved below some other view?

I have a stack of views shown on top of each other. So at a time only 1 view is shown and others are below the active view. I want to know whether a particular view is active or moved below some other view inside the ViewPart code. Is there any listener which can tell me that the composites of any view are now moved below some other composites of another view?
Also it would be great if can I know through listeners that a particular view is now made invisible.
I have only access to my view code and that is why I have to implement it in that view only.
Stack of views is shown under one Window so the parent shell is same of all the views.
You can use an org.eclipse.ui.IPartListener to listen for events about parts.
In a ViewPart you can use:
getSite().getPage().addPartListener(partListener);
to add a listener. The listener has method for parts being opened, closed, activated and deactivated and brought to the top of stack.
You can also use IPartListener2 which has some additional methods.

Is there a generic way to display progress bar over Views in Android?

I have seen numerous posts on how to display progress bar while the data loads in the background. All suggestions requires we manually place a ProgressBar in the layout xml and then use an AsyncTask to show and hide the ProgressBar and the View in question.
However, I would like to make a generic class which creates the ProgressBar programmatically at runtime and place it exactly over the view in question and maybe also slightly shade or blur the view while the ProgressBar is displayed. Had this been a Swing application I would have painted my progress bar on the "glass pane" of the view after slightly shading it with gray. In that case since the progress bar is the child of the same pseudo parent hence I could easily position that as centred.
In Android UI toolkit I am not aware of any such "glass panes". How do I achieve this effect?
Make a BaseActivity that you derive all your Activities from (same goes for Fragments).
Give it something like
protected void showLoading(){
ViewGroup content = findViewById(...);
content.setVisibility(Visibility.GONE);
ViewGroup root = findViewById(...);
root.addView(new ProgressBar());
}
Gotta make sure all your layouts have a ViewGroup for root and one for content, which otherwise might not be necessary and bloat layouts, but thats how I do it and it works fine.
Above is pseudocode of course, but you get the idea.
There's also this libary: http://www.androidviews.net/2013/04/progressfragment/, but I don't think it's necessary to import a library for that task.
Unfortunately you have to create this functionality. I always do this by creating a class from a framelayout and then place my imageview inside with my progressbar ontop. I then create an interface I use as a callback so that when said process is complete and the data is finished being processed I get my callback and I hide the progressbar. I use a framelayout because its the easiest view to use to "stack" views ontop of one another by simply placing them inside the FrameLayout. You may also need to place views inside the frame inside of a relativelayout with the width and height set to match parent so you can set the layout_centerInParent to true on your progressbar so it sits nicely inside your compound view.
Well, I'm not sure I get the question right, because it seems easier to me than it might be. But anyway:
To instantiate programmatically a progress bar, you need to do the following in your activity:
ProgressBar pb = new ProgressBar(this);
((ViewGroup) this.findViewById(R.id.view_that_will_contain_progressbar)).addView(pb);
This will add the view to the ViewGroup view_that_will_contain_progressbar. This ViewGroup should be a FrameLayout if you want to overlay over other information.
Tip: if you want to customize your ProgressBar, you can declare it in a layout file, and do the following to instantiate and attach the PB (still in your activity/fragment) :
this.getLayoutInflater().inflate(R.layout.progressbar,parent);
with parent refering to the parent you want to attach it to.

Getting Currently Set Content View

We are creating an app with two main views: sView and sViewSettings. If the Android Back button is pressed we want an if statment to check if the current view is set to sView settings, if it is then call the sView.
Already have a listener setup for the back button just need it to call the if statement to check the current view.
Have already tried
if (this.findViewById(android.R.id.content) == sViewSettings)
Any ideas on this?
Thank you for Reading,
Travis
The view with id android.R.id.content is a FrameLayout holding your content view. Try this:
ViewGroup contentFrame = (ViewGroup) findViewById(android.R.id.content);
if (contentFrame.getChild(0) == sViewSettings) { ... }
However, I suggest a slightly different approach: use a ViewSwitcher (or any kind of ViewAnimator) to flip between the two main views and keep track in your code of which one is on display.
EDIT: If you want to keep your layouts loaded separately, you can assign an id (the same one) to the root view of each layout and then retrieve the content view directly using findViewById.

View created from Java code is wrapped in another view. Why?

1) Why, when I create my custom compound view from Java code it is wrapped in another view which creates another level of view hierarchy? If I use the <include> tag in the XML to create the view, this does not happened. (see the attached image from hierarchy manager). Any reason for that?
2) The image shows (the part where the view is created by <include> tag) another interesting behavior – that it is easily possible to have the views with the same android:id on the same hierarchy level. When the findByViewId() method is used then, the first view reference is returned.
Any reason for that?
Because that's the way you wrote the code If you do not want that behavior, fix your code.
that it is easily possible to have the views with the same android:id on the same hierarchy level
Of course. You see this all the time with subclasses of AdapterView, such as ListView.

Android ViewGroup Remove Views?

I have a tabhost. One of the tab's activity is a ViewGroup. This viewgroup manages two different activities. I do this so I can navigate between activities within a tab. I add the activities like so:
if (videoViewLive == null)
videoViewLive = getLocalActivityManager().startActivity("VideoPlayerLive", new Intent(this,VideoPlayerLive.class).
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
videoViewLive.setVisibility(View.VISIBLE);
this.addContentView(videoViewLive, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT));
Each of my content view activities receives asynchronous notifications. What I would like to do is somehow remove the activity/content view that is not being used. So in essence, I load content view A, B dies, becomes null, or whatever, and vice versa. I want to do this because the way I am managing these views seems problematic. (errors when loading a view, loading the other view, then loading the first again, etc.)
Have you tried ViewGroup.removeAllViews()?
This is kind of tangential to the issue here, but why are you doing this with separate Activities?
This is exactly the kind of thing Fragments were designed for. There is actually a class called ViewPager included in the android support library (see also FragmentStatePagerAdapter) which allows the same kind of behavior via tabs (potentially in the ActionBar) or swiping. The adapter automagically handles the lifecycles of the Fragments as you navigate between them, all within the context of a single Activity, such that you can use the top-level Activity for routing events and maintaining overarching state if necessary.
I would try following approach:
//Add OnGlobalLayout Listener using ViewTreeObserver
View rootView = (android.R.id.content);
//Assuming you are managing these two activities inside the ViewGroup
Activity activityA = <someRef Value>;
Activity activityB = <someRef Value>;
rootView.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
//try couple of things here
// 1. determine which activity has focus
// 2. you could also check position of View on screen to determine which one is active or on the top
if (activityA.hasWindowFocus())
{
//do some action --remove other content from ViewGroup
}
});

Categories

Resources