I am working with an activity that has a few different stages. It is designed like a wizard so a few sections of it are tutorial like pages where I hide the toolbar and status bar. The Activity starts off with the toolbar hidden. In each of the fragments, I have an onToolbarShown(ActionBar ab) (called in the base fragments onStart() method) which I use to edit the title, if the back button shows etc, and then I call the showToolbar method below:
public void showSystemUi(boolean show){
if(show){
KKDeviceUtil.showSystemUI(mRootLayout);
}else {
KKDeviceUtil.hideSystemUI(mRootLayout);
}
}
#Override
public void showToolbar(boolean show){
if(getSupportActionBar() != null){
showSystemUi(show);
if(show) {
mRootLayout.setFitsSystemWindows(true);
getSupportActionBar().show();
}else{
getSupportActionBar().hide();
mRootLayout.setFitsSystemWindows(false);
}
}
}
(showSystemUi is the stock show/hide method suggested by android here)
The problem is that the first time I show the toolbar, the status bar is the wrong colour and the layout is shunted down by the height of the status bar. As seen here:
When I next switch fragments, the problem clears up:
And if I go back to the previous fragment, it looks correct:
I don't get this problem if I never hide the toolbar/system windows in the first place. I originally had some of the operations in a different order and thought that re-arranging them could help, but It didn't seem to make any difference. I also tried calling setStatusBarColor but that had no effect. I also have <item name="android:statusBarColor">#color/status_bar_color</item> in my v21/styles.xml which is the correct colour for my status bar, and my primaryDark is the same colour as the screenshot (buggy) above shows.
I can't seem to find what I am doing wrong here, is this the correct way to show/hide my toolbar/system ui and why does this only happen on the first showing of the toolbar?
(Note: it is hard to see from the screenshots, but in the first screenshot, the 'Done' button is much closer to the bottom than the correct placing in the third screenshot)
Please see below i've shown you demo style that will reflect color on the status bar.
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/side_bar_color</item>
<item name="colorPrimaryDark">#color/side_bar_color</item>
<item name="colorAccent">#color/side_bar_color</item>
</style>
There "colorPrimaryDark" is that color which will used at status bar, you need to set this style to your application or activity at manifest class
Related
I have been struggling with this for a few days now, i have tried lots of the articles on SO and none seem to match my requirements, i have set the Toolbar.xml and set the theme as below
<style name="ToolbarStyle" parent="Theme.AppCompat.Light">
<!-- Customize color of navigation drawer icon and back arrow -->
<item name="colorControlNormal">#color/white</item>
</style>
This works on a per app basis, but i need to alternate between white and black arrows depending on the content page i am on, i have tried custom renderers as well but this doesn't work dynamically as well
Any pointers massively appreciated, even if i can clarify, is the Xamarin forms navigation a Toolbar or an ActionBar?
Cheers
Anthony
is the Xamarin forms navigation a Toolbar or an ActionBar?
It is a Toolbar and not an ActionBar
Android.Support.V7.Widget.Toolbar
You can set the color via the ToolBar.NavigationIcon.SetColorFilter(...), but you have to find it first as Xamarin is not applying it via SetSupportActionBar...
Red backbutton PlatformEffect example:
public class RedBackButtonColorNameEffect : PlatformEffect
{
protected override void OnAttached()
{
void ViewGroups(ViewGroup viewGroup)
{
for (int i = 0; i < viewGroup.ChildCount; i++)
{
Android.Views.View v = viewGroup.GetChildAt(i);
switch (v)
{
case Toolbar tb:
tb.NavigationIcon?.SetColorFilter(viewGroup.Resources.GetColor(Android.Resource.Color.HoloRedDark), PorterDuff.Mode.SrcAtop);
return;
case ViewGroup vg:
ViewGroups(vg);
break;
}
}
}
var rootView = (Control.Context as AppCompatActivity).FindViewById(Android.Resource.Id.Content).RootView as ViewGroup;
ViewGroups(rootView);
}
protected override void OnDetached()
{
}
}
Usage:
someControl.Effects.Add(Effect.Resolve("Effects.RedBackButtonColorNameEffect"));
(remember set your ResolutionGroupName & ExportEffect attributes...)
Note: Xamarin does not apply a value for the Control instance within a PlatformEffect if you attach the effect at the page level or a container level and thus this will not work. You could store the Activity context somewhere (static var) from the MainActivity in order to workaround that issue and thus have the proper Context to search within, your choice..
Note!: PlatformEffects are whack in so many ways, especially since they never get garage collected and thus are a memory leak, they are nice for a quick example/prototype, but use a custom renderer for production code).
I understand that this question has been asked here many times but after of spending hours searching for the solution I am unable to find one.
My requirement simple, I just want to change share icon on Action Bar to white color. I've the white drawables and using built-in Action Bar.
have tried setting icon in menu xml but didn't work. Any help would be appreciated.
<item
android:id="#+id/action_share"
android:actionProviderClass="android.widget.ShareActionProvider"
android:showAsAction="ifRoom"
android:icon="#drawable/ic_action_share_white"
android:title="#string/action_share"/>
Take a look at the ShareActionProvider's onCreateActionView() method:
public View onCreateActionView() {
// Create the view and set its data model.
...
// Lookup and set the expand action icon.
TypedValue outTypedValue = new TypedValue();
mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true);
Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId);
...
So, to change this image, it looks like you should change the value of actionModeShareDrawable for your app's theme. Unfortunately this attribute seems not to be public in the framework (though it is if using AppCompat or ActionBarSherlock).
If you are using neither of these libraries, a possible solution is to create a subclass of ShareActionProvider and reimplement the onCreateActionView() method (though you'll have to duplicate its code and, possibly, the resources it uses).
I declared my menu items with android:showAsAction="ifRoom". My Activity is extending ActionBarActivity. In preview it is as expected but when run on my phone is it always in overflow.
From what I've seen nothing else is needed. My phone runs in Android 4.4.2 KitKat.
Am I missing anything else?
You have to define your own namespace, if you want to use the showAsAction attribute with ActionBarCompat(I assume you are using ActionBarCompat because you mentioned, that you're extending ActionBarActivity):
xmlns:app="http://schemas.android.com/apk/res-auto"
and use showAsAction like this:
<item [...] app:showAsAction="always"></item>
Just try this...
<item android:id="#+id/action_blah"
android:icon="#drawable/ic_c"
android:title="#string/action_blah"
app:showAsAction="(yourOptions)"/>
(yourOptions):
always = To force to show on the actionbar.
never = Not to show on your actionbar ever.
and
ifRoom = It will let your item if there is enough space on your action bar.
You can see these in Landscape mode.
HappyCoding
I know that I can make the ActionBar overlay using requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY)
and can toggle/show the status bar in my screen (by switching between FLAG_FULLSCREEN and FLAG_FORCE_NOT_FULLSCREEN).
This works great. However, I don't want my layout moving when I toggle the status bar.
I know that I can make the status bar "overlay" (albeit not transparently) the content using:
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
This works also great, except for the (expected) consequence that, when using an ActionBar, the ActionBar gets half cut off - half of it is under the status bar basically.
So I am wondering, is there a way to "move the ActionBar down" by the status bar's height in this case?
I know that in worse case, I can do this with a custom view that lives within the layout, but I rather not do this (want to benefit from the ActionBar).
thanks!
so apparently, you can do this in Jellybean. google includes two examples in the api docs. here is a link: http://developer.android.com/reference/android/view/View.html#setSystemUiVisibility%28int%29
summary:
use setSystemUiVisibility on a view to toggle visibility (on jellybean+).
It's not perfect, but this is how I have achieved what you want:
In onCreate:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
Then:
private void hideStatusBar() {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
}
private void showStatusBar() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
I also have a style on the activity with the following:
<style name="readingStyle" parent="#style/Theme.Sherlock">
<item name="android:windowActionBarOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
</style>
Your activity will shift down when the status bar shows, but I don't think it's too noticeable.
Why you dont make it in the Manifest
android:theme="#android:style/Theme.Black.NoTitleBar"
than you have no statusbar and more space for the Actionbar??
Put this method in onCreate() method activity:
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
refer: link
I have a AlertDialog box with approximately 10 controls (text and TextView) on it. These controls are in a ScrollView with AlertDialog, plus I got 2 buttons positive and negative. The issue I have is when the soft keyboard pops up the two buttons are hidden behind the keyboard.
I was looking for something like redraw function on my inner View or the dialog box. Below is the screen shot of what I am talking about.
If your dialog was an activity using one of the Dialog themes you could effect this behavior by setting the adjustResize flag for the windowSoftInputMode parameter of the activity.
I'm using:
android:windowSoftInputMode="adjustResize|stateHidden"
I think you can still use this flag with regular dialogs, but I'm not sure how to apply it. You may have to create your AlertDialog with a custom theme that inherits the right parent theme and also sets that flag, or you might have to use ContextThemeWrappers and stuff.
Or maybe you can just use Window#setSoftInputMode.
alertDialog.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
I've found a best way to handle this. Because this is a dialog, So the code
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
doesn't work very well.
Besides this code, you must set a dialog style for this dialog. The style should like below:
<style name="DialogStyle" parent="#android:style/Theme.Black.NoTitleBar.Fullscreen">
<item name="android:windowFullscreen">false</item>
......
......
</style>
NOTICE that the attribute parent is Theme.Black.NoTitleBar.Fullscreen like an activity's style. and the attribute android:windowFullScreen should be false.
Now, the dialog will be resized when the soft keyboard toggles.
Nothing worked for me except adjustPan
as per the documentation
The activity's main window is not resized to make room for the soft keyboard. Rather, the contents of the window are automatically panned so that the current focus is never obscured by the keyboard and users can always see what they are typing. This is generally less desirable than resizing, because the user may need to close the soft keyboard to get at and interact with obscured parts of the window.
So just simply use it in your onCreate() or onCreateView() method like:
getDialog().getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Or simply put android:windowSoftInputMode="adjustPan" in manifest for the Activiry in which we are playing with dialogs
and use android:windowSoftInputMode="adjustResize|stateHidden" in each edittext which will help the user to navigate to next textbox easily.
Point to remember
Never use MATCH_PARENT to make the dialog full screen as adjustPan will not work here. If anyone wants to make the dialog to fit the screen, just use points till 0.96 (not more than this) for the height, so the keyboard will properly reach to the edittext. I did like below :
#Override
public void onStart()
{
super.onStart();
Dialog dialog = getDialog();
if (dialog != null)
{
//int height = ViewGroup.LayoutParams.MATCH_PARENT;
int width = ViewGroup.LayoutParams.MATCH_PARENT;
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
//int width = (int)(size.x * 0.96);
int h = (int)(size.y * 0.96);
dialog.getWindow().setLayout(width, h);
}
}
Look, If I will use the total height (MATCH_PARENT) then soft_keyboard will squize the dialog. But if I will use points for the height (here 0.96 which is almost near to match_parent), then it will properly work.
Hope it will help someone :)
maybe you don't need to resize Dialog
add android:imeOptions="actionNext" to EditText(all but last) (it will add "Next" button to the keyboard - go to next EditText)
and add android:imeOptions="actionDone" to last EditText ("Done" button - hide keyboard)
now user should be able to click buttons
if you're creating textboxes in code use EditText#setImeOptions function
HTH
Are you forced to have it as a popup? The popup looks so large, that you may just want to have it as a separate activity. In general, popups are used to provide a brief question or statement with a few options, not a full blown data entry form. Since you can't see much behind the large popup, you're not exposing any underlying controls anyways.
to show keyboard immediately and adjust size:
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
}
});
To those who are in the same situation as me.
in my case, the problem was activity having these attributes in style
<style name="SomeStyleName">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
If windowTranslucentStatus and windowTranslucentNavigation both are true,
the keyboard came up as it overlay dialog.
So I override those values to false, only for materialAlertDialog. (maybe AlertDialog or Dialog in your case)
<style name="SomeStyleName">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="materialAlertDialogTheme">#style/TranslucentMaterialAlertDialogTheme</item>
</style>
<style name="TranslucentMaterialAlertDialogTheme" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowTranslucentNavigation">false</item>
</style>