So I modified the Mediarouter source to be dependent on ActionBarSherlock rather than AppCompat. However, now the callback from MediaRouteAdapter onDeviceAvailable(...) is not being called.
Any ideas on how to get this to work?
I don't want to leave the cast button always visible. Rather, I want to use onDeviceAvailable(..) to only make it visible when a device is available.
I found a hack on how to fix this.
If you use appcompat, the cast icon will only be visible when you have a chromecast device in your network, based upon your implementation of onDeviceAvailable(...).
However, if you use ABS, the onDeviceAvailable(...) method is not called when a chromecast device is available on the network. So in order to see the cast icon, we must set it as always visible.
So the issue is that the cast icon is always visible (when you set visibility to visible or when you add it to your actionbar).
HOWEVER:
The MediaRouter has different view states. One for when a cast device is available and one for when there isn't one available.
The Mediarouter library consists of drawable pngs that are the icons for when a device is available or not.
Just replace the one for which 'no route is available' with a blank resource, or anything that suits the app.
When a device is available, the correct cast icon will show, and when not available your custom resource will show (blank if the resource is a blank view).
Here are full details on how to obtain the mediarouter source code, and how to fix this: http://www.droidorbit.com/2013/10/mediarouter-and-actionbarsherlock.html
Related
I've run into a very peculiar problem with Toolbars. The way my team currently uses the Toolbar is via a wrapper class, let's call it WrapToolbar.
So WrapToolbar will internally setup a Toolbar, and exposes some common Toolbar functions. Things like setTitle, getTitle, etc are available.
This WrapToolbar also sets up a default icon. This way all usages of the WrapToolbar will have this icon available for the screens that need it.
The problem with this approach is that for screens that require additional icons, have to add them via a Menu XML and the onCreateOptionsMenu function.
When we do that, the default icon setup with WrapToolbar gets pushed to the left, and the new icons from the Menu XML get added at the end.
This has worked fine for us until recently when requirements changed, and now are asking for the default icon to be at the end all the time.
I'm currently wrestling with the idea of doing a custom wrapper around Toolbar that exposes the ability to add icons, get the title, set the title, etc. This way we can put the icons in any order, and have ultimate flexibility in how our Toolbar looks.
I'm looking for some guidance on what that might look like. I also want to get some feedback on whether my initial idea to solve for this is flawed in some way I haven't foreseen.
Menus have a built in ordering based on the android:menuCategory attribute - you can use android:menuCategory="secondary" to push a menu item (like your default icon) to the end of the list - all MenuItems without a menuCategory will appear to the left of it.
I'm a new to Android development and I've been giving Android Studio a spin. I've followed Google's tutorial and I still haven't been able to get the ActionBar up and running either on the emulator or on the real device. I've specified the min version in the manifest file and I've also edited the menu and activity xml files accordingly.
Confusingly, the UIs shown in the activity_foo.xml and menu_foo.xml are different:
activity_foo.xml:
menu_foo.xml:
Even more confusingly, the final app when built shows both the Search and Settings in the hamburger menu though I do not recall seeing it in the GUI previews:
How can I fix this?
Confusingly, the UIs shown in the activity_foo.xml and menu_foo.xml are different
They are supposed to be different. One is showing you a layout file. The other is showing you a menu resource. Their previews are not supposed to necessarily match. After all, an Android app that is bigger than a breadbox will have many layout resources, few of which will be defining the contents of an activity.
For those layouts that do define the contents of an activity, IIRC, you can have the same tools:context=".FooActivity" in the root element of your layout file, and the preview may take that into account.
Even more confusingly, the final app when built shows both the Search and Settings in the hamburger menu though I do not recall seeing it in the GUI previews:
In the preview, the search item is represented by a toolbar-style button (icon is a magnifying glass).
In your menu resource, you have one <item> that has android:showAsAction and one <item> that has app:showAsAction. Either you are using the appcompat-v7 action bar backport, or you are not. That would be determined by things like:
what Java class your activity inherits from (ActionBarActivity or AppCompatActivity for appcompat-v7)
what theme you are using for the activity in your manifest (if it is based on Theme.AppCompat.*, you are using appcompat-v7)
If you are using appcompat-v7, you need to change the android:showAsAction to app:showAsAction. Given the results of your run of the project in the emulator, my guess is that you are using appcompat-v7. If you make the change to the menu resource and run the project again, you may see the search item show up as the magnifying glass icon, as you see in the preview. I say "may" because there may or may not be room to show that toolbar-style icon, depending on screen size and orientation of the device that runs your app — action bar items with ifRoom will show as toolbar-style buttons if there is room or will fall into the overflow menu if not.
Background
I know there are already logo and icon (difference is explained here).
The problem
Starting with API 20 ("L"? or maybe Android wear?) , there is now a new one, called "banner". Here's what the documentation says about it:
A drawable resource identifier (in the package's resources) of this
component's banner. From the "banner" attribute or, if not set, 0.
So this doesn't give much clues about what it is...
The problem is that I don't know what it is, and can't find any info about it.
What I've tried
I've tried finding about this on the Internet, but because "banner" is such a generic name, I didn't find anything interesting...
Of course, I've also tried searching about this on the documentation of activity (here and here), but didn't find anything...
The question
Where is it used for?
Is it for Android "L" or Android wear ? or maybe both?
Why has Google decide to make it?
Where can I read about it?
Are there any guidelines about it?
Depends on the answers, do you think it will somehow be part of the support library?
It's for Android TV.
From the l developer preview reference docs:
A Drawable resource providing an extended graphical banner for its
associated item. Use with the application tag (to supply a default
banner for all application activities), or with the activity, tag to
supply a banner for a specific activity.
The given banner will be used to display to the user a graphical
representation of an activity in the Leanback application launcher.
Since banners are displayed only in the Leanback launcher, they should
only be used with activities (and applications) that support Leanback
mode. These are activities that handle Intents of category
Intent.CATEGORY_LEANBACK_LAUNCHER.
This must be a reference to a Drawable resource containing the image
definition.
Must be a reference to another resource, in the form
"#[+][package:]type:name" or to a theme attribute in the form
"?[package:][type:]name".
This corresponds to the global attribute resource symbol banner.
You can also read a bit more about it here.
Essentially a banner is just a launcher icon for the leanback launcher. For example, if your app is compatible with both phones/tablets, and android tv, specifying a banner will let you have an alternate (rectangular) icon for the leanback launcher on android tv.
In this image, I specified the banner to be a red shape drawable. By default this will be your apps launcher icon.
I don't think it will be part of any support library, as it's specific to Android L on the TV. But to use it, you will need to be targeting L.
What does requestWindowFeature() do? I used it to create a custom titlebar, but I don't really understand what its purpose is.
The explanation provided in the SDK documentation here does not make sense.
Each activity has an associated window (on which the whole UI draws). This window has default way of being drawn (whether toolbar, actionbar, icons are drawn or not).
However, you can use requestWindowFeature to ask the system to include or exclude some of windows features (toolbar, actionbar and so on).
Here you can find the full list of supported features: http://developer.android.com/reference/android/view/Window.html
As example, you can use FEATURE_NO_TITLE to make a window full screen or FEATURE_RIGHT_ICON to let system know that icon should be drawn on the right side.
I have been using the following workaround to center the activity label (without having to resort to a custom title in XML layout):
((TextView)((FrameLayout)((LinearLayout)((ViewGroup) getWindow().getDecorView()).getChildAt(0)).getChildAt(0)).getChildAt(0)).setGravity(Gravity.CENTER);
This works great but every once in a while I see one of the users (on Google Play) getting a
java.lang.ClassCastException:
com.android.internal.widget.ActionBarView cannot be cast to
android.widget.TextView
These are probably tablet users who are running Android 3.x or higher.
Short of implementing my own custom title that would give me direct access to the activity label, can you recommend another way to avoid that ActionBarView to TextView ClassCastException?
Perhaps check for the Android version under which the app currently runs and go though another level of getChildAt(0)?
The action bar is defined in the theme. So if you want to avoid that ever showing up you need to pick different theme.
Alternatively you can detect what version of OS the user is using and in the case of being 11 (Honeycomb) and higher simply skip the action bar and get the next view.
Which would look something like
if (Integer.valueOf(android.os.Build.VERSION.SDK) > 11)
{
((TextView)((FrameLayout)((LinearLayout)((ViewGroup).getWindow().getDecorView()).getChildAt(1)).getChildAt(0)).getChildAt(0)).setGravity(Gravity.CENTER);
}
else
((TextView)((FrameLayout)((LinearLayout)((ViewGroup).getWindow().getDecorView()).getChildAt(0)).getChildAt(0)).getChildAt(0)).setGravity(Gravity.CENTER);
I would also like to add like Shark said, this is a total hack and is not very robust code. You should be using findViewById() to locate your views and avoid all of that super ugly casting. You can expect your hack or even the code I just put in to break in the future if you continue down that path.
((FrameLayout)((LinearLayout)((ViewGroup) getWindow().getDecorView()).getChildAt(0)).getChildAt(0)).getChildAt(0)
Start collecting child views from here, and search for your own TextView... You just need to skip the actionbar, no need to be nice about it when you started off with a hack anyway.