How to use ActionBar features from a fragment? - android-fragments

In a fragment code I'd like to make ActionBar API calls such as
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
Is it a good idea to hold a reference to the activity in the fragment's code or is there a better way to approach this?
I'm using SherlockFragment for compatibility.

I just realized SherlockFragment has getActivity() and getSherlockActivity() methods, so I can write:
this.getActivity().requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
this.getSherlockActivity().setProgressBarIndeterminateVisibility(true);

Related

How to implement transition between two PageRow in leanback BrowseFragment?

I'm using a leanback BrowseFragment to implement a simple android tv app. I have two PageRows which are backed by custom fragments. When I switch between the two in the browse navigation area, the content side of the screen goes blank briefly before the new fragment's views appear. How can I fade from one view to the other without a delay in between?
I see some references to "entrance transition" in the docs which I think is what I need, but I can't find any examples of what to do in those callbacks.
https://developer.android.com/reference/android/support/v17/leanback/app/BrowseFragment.MainFragmentAdapter.html#setEntranceTransitionState(boolean)
I tried to implement setEntranceTransitionState on my PageRow Fragment's MainFragmentAdapter, but it is never invoked:
class GuideFragment: Fragment(), BrowseFragment.MainFragmentAdapterProvider {
val fragmentAdapter = object: BrowseFragment.MainFragmentAdapter<GuideFragment>(this) {
override fun setEntranceTransitionState(state: Boolean) {
Log.v("TEST", "setEntrance($state)")
fragment.setEntranceTransitionState(state)
}
}
override fun getMainFragmentAdapter() = fragmentAdapter
}
There is no way to do this when using BrowseSupportFragment.
If you look at the implementation of swapToMainFragment(), you'll see that while scrolling the content is set to an empty fragment. When SCROLL_STATE_IDLE is reached, a regular fragment transaction is used to replace the child fragment with the new content.
leanback has a lot of limitations, It is better to fork the official code and create your own repo and modify it; we did the same in our app.

Sometimes willHideViewController from UISplitViewControllerDelegate is not called

I have a problem.
My app is a tab bar controller and its first view controller is a split view controller.
This seems to be not ok for Apple because documents say a split voew controller must be the root, so perhaps that is the reason of my problems.
The problem is that sometimes, willHideViewController from UISplitViewControllerDelegate is not called, so, for this reason, the upper/left button sometimes is not created, which is anoying.
I realised, to reproduce this error, try several times this:
-Landscape mode.
-Select a tab different to split view controller tap.
-Move the iPad to portrait in that tab.
-Go to the split view controller tab, and sometimes, willHideViewController is not called so you will not see the upper button. However if I rotate my iPad to landscape and after that to portrait, it's fixed.
I tried to force manually several rotations to work around this problem, but no luck.
I still have to try any split view controller clone class from github or similar.
Do you have idea what's going on or any work around?
Here I show you two examples working properly.
Thanks a lot for your help.
Where do you set the splitViewControllers delegate? Perhaps you can set the delegate when you load the tab. It sounds like you set it only when you have rotated once?
Otherwise, see this example
Here they have the TableViewController be the delegate of the splitviewcontroller. Perhaps you could do the same with the TabBarController?
I've concluded that this can't be done in any way that I consider 'sufficiently' legitimate. It's possible to get frustratingly close, but the issue of having the willShow..., willHide disseminated to the split view controllers under each tab remains.
The solution that seems most likely to work is,
https://github.com/grgcombs/IntelligentSplitViewController/blob/master/IntelligentSplitViewController.m
Though this code is undoubtedly clever, it's a bit too 'side door' for me. I suspect (but don't know) that just invoking the delegate methods is not sufficient. Surely the UISplitViewController itself needs to change it's internal state as well as calling the delegate methods? This method 'just' invokes the delegate methods when there's an orientation change.
So... I've decided on a more legitimate solution, which is to use the new method introduced in iOS 5.
- (BOOL) splitViewController:(UISplitViewController *)svc
shouldHideViewController:(UIViewController *)vc
inOrientation:(UIInterfaceOrientation)orientation
{
return NO;
}
So, the master menu is never hidden, and therefore the problem of managing the popover doesn't arise.
Of course, this is still not totally 'legit' as it still includes UISplitViewControllers that are not at the top level (the UITabViewController is at the top level, and the split views are on each tab)
Good luck with whichever solution you choose.
I'll update this reply when I've confirmed Apple will approve an app using this solution.

How can I use Caliburn.Micro conventions to set a button's text and its action?

If I have a button in my View named, say, Save, then I can add a Save property to my ViewModel, and Caliburn.Micro will automatically bind it to my button's Content. For example:
public string Save { get { return StringResources.Save; } }
Or I can add a Save method to my ViewModel, and Caliburn.Micro will execute that method when the button is clicked. For example:
public void Save() {
Document.Save();
}
But what if I want to do both? C# doesn't let me declare a method and a property with the same name. Can I use conventions to both set the button's Content and the action to perform when it's clicked?
(I know I can manually bind one or the other, but I'd rather use conventions if it's practical.)
This is a common need, so you'd think it would be built into Caliburn.Micro, but it doesn't seem to be. I've seen some code that extends the conventions to support this (and I'll post it as an answer if nothing better comes along), but it's a workaround with some bizarre quirks -- so I'd like to hear if anyone else has made this work more cleanly.
Note: I did see this similar question, but it seems to be about whether this is a good idea or not; I'm asking about the mechanics. (I'll reserve judgment on whether it's a good idea until I've seen the mechanics. (grin))
Quick and dirty
<Button x:Name="Save"><TextBlock x:Name="SaveText"></TextBlock></Button>

Removing all event listeners in Flex

How can I remove all event listeners on all components at once, especially when it is not known what listeners are attached to each component?
You can override mx.core.FlexSprite, which UIComponent inherets from, and generate an array of listeners created. Doug Mc Cune put up source code here.
His blog says: removeAllEventListeners() – removes all event listeners of all types. This completely wipes out all event listeners for the component all at once.
Let us know if this does the job!
No!
You might be able to mock something up with hasEventListener and willTrigger. But, there doesn't appear to be an obvious way to remove the event listeners without actually knowing the method name.
What do you want to do this for?
There is an issue in Adobe JIRA for this task, please vote if you feel that it important for you
https://bugs.adobe.com/jira/browse/SDK-14127
Elad Elrom has a post on his implementation to store event listener references, and be able to remove them all at once:
http://elromdesign.com/blog/2010/07/16/easy-way-to-store-event-listeners-reference-prevent-memory-leaks/

call flex initComplete at a specific time

Below is the overriden on complete function for a preloader in Flex.
private function initComplete(e:Event):void
{
//dispatchEvent(new Event(Event.COMPLETE));
cp.status.text="Configuring... Please Wait";
}
What I want to do is when the app has finsihed loading I want to change the preloaders text to "configuring".
Then I want to go and do a bunch of setup stuff in my code.
Once I've done all the setup I wanted how can I get the Preloader to dispatch its Event.complete from else where in my code?
I tried Application.application.preloader but it comes up null.
So I guess my question really is how to access a preloader from anywhere in my application.
Would a better approach be to have all setup classes as members of my preloader class?
One thing that might help is a Model-View-Controller pattern. Are you using a framework for your application like Mate, Swiz, or Cairngorm?
If you were using Mate, for example, you could do something like this:
Create an AppStateManager class with a property (e.g. applicationState)
Create an EventMap with an EventHandler for the FlexEvent.INITIALIZE event. In this handler, set the AppStateManager.applicationState to something like "CONFIGURING"
Your EventMap has an injector that injects the applicationState property into a view. The injector listens for changes to this property and updates the view. In this case it might just be injected into your main view.
In the main view, you have a public bindable property also called applicationState that gets injected by Mate.
In the setter for this property, you can have an if/then or a switch that does different tasks depending on the state. For example, if applicationState == "COMPLETE", then this.preloader.dispatchEvent(Event.COMPLETE) or something like that.
The details are pseudo-sketched out but the idea is to use Flex's bindings to notify view components when changes have been made, and to have shared objects that maintain state. Not sure if that's what you're looking for...
The component LifeCycle does specific stuff in a specific order, and the near final element is to make the component visible.
It sounds to me like you want to defer this setting of visible to true to do other stuff. But, I imaging if you were making use of the component LifeCycle this would be a non-issue.
What sort of app init stuff do you need to do?

Resources