Set height of RelativeLayout to match height of Soft Keyboard - java

I need to set the height of this RelativeLayout to match the height of the Soft Keyboard. To make sure the EditText appears just above the keyboard.
Is it possible to set some kind of Listener to detect every time the keyboard height changes?

The proper way to do this would be to set soft input to match your needs.
try following for a fragment put this line in your fragment's onCreate method:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
You can set multiple modes with a single line like
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
And if you are working in an activity you can just adjust it in your android manifest file for each activity
<activity
android:name=".SomeActivity"
android:windowSoftInputMode="adjustResize" />
or
android:windowSoftInputMode="adjustPan|adjustResize"
Check which settings suits your needs better between adjustPan, adjustUnspesified, adjustResize or some other soft input options.

I figured out a solution that seems to work fine. With only 1 problem. For some reason the Status Bar turns white with this piece of code.. Any idea why?
ViewCompat.setOnApplyWindowInsetsListener(this.getWindow().getDecorView(), (v, insets) -> {
int keyboardHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
//Code logic
return insets;
});
How I set the Status Bar color:
<style name="AppTheme.GuessWord">
<item name="colorPrimaryDark">#color/primaryColor</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>

Related

How to change virtual keys color [duplicate]

In guidelines of Android 5.0, the navigation bar seems customizable:
http://www.google.com/design/spec/layout/structure.html#structure-system-bars
How can I change the navigation bar color?
I would like to use a white style.
Screenshots:
Edit: In my resources, I tested the style:
<item name="android:navigationBarColor" tools:targetApi="21">#android:color/white</item>
But the buttons are white. I would like the same renderer as the second image.
Starting from API 27, it is now possible to use the light style of the navigation bar:
<item name="android:navigationBarColor">#android:color/white</item>
<item name="android:windowLightNavigationBar">true</item>
From the documentation:
windowLightNavigationBar
If set, the navigation bar will be drawn such that it is compatible with a light navigation bar background.
For this to take effect, the window must be drawing the system bar
backgrounds with windowDrawsSystemBarBackgrounds and the navigation
bar must not have been requested to be translucent with
windowTranslucentNavigation. Corresponds to setting
SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR on the decor view.
Use this in your Activity.
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setNavigationBarColor(getResources().getColor(R.color.green));
}
add this line in your v-21/style
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:navigationBarColor">#android:color/black</item>
</style>
This code changes the navigation bar color according to your screen background color:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.any_color));
}
You can also use the light style for the navigation bar:
<item name="android:navigationBarColor">#android:color/white</item>
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setNavigationBarColor(getResources().getColor(R.color.colorWhite));
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); //For setting material color into black of the navigation bar
}
Use this one if your app's API level is greater than 23
getWindow().setNavigationBarColor(ContextCompat.getColor(MainActivity.this, R.color.colorWhite));
getWindow().getDecorView().setSystemUiVisibility(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
May this code will not work for API level 30. Because " SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR" is deprecated in API level 30.
Check this out: https://developer.android.com/reference/android/view/View#SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
the navigation bar is not supposed to be colored
When you customize the navigation and status bars, either make them both transparent or modify only the status bar. The navigation bar should remain black in all other cases.
(source https://developer.android.com/training/material/theme.html )
BUT, you can use this library to achieve what you want :) https://github.com/jgilfelt/SystemBarTint
You can also set light system navigation bar in API 26 programmatically:
View.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
Where View coluld be findViewById(android.R.id.content).
However remember that:
For this to take effect, the window must request FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS but not FLAG_TRANSLUCENT_NAVIGATION.
See documentation.
getWindow().setNavigationBarColor(ContextCompat.getColor(MainActivity.this,R.color.colorPrimary)); //setting bar color
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); //additional setting items to be black if using white ui
Old question. But at this time we have a direct solution. May be helpful for someone.
public static void setNavigationBarColor(Activity activity, int color, int divColor) {
Window window= activity.getWindow();
window.setNavigationBarColor(color);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
window.setNavigationBarDividerColor(divColor);
}
}
View Official Documentation

Light Statusbar icons won't change to dark when using LAYOUT_FULLSCREEN or LAYOUT_STABLE UI flags?

So I have a problem with my app's status bar not changing its icons to dark when I'm forcing my app into a Light Theme.
I've discovered the root of the issue, which is that the icons in the status bar don't want to change dark when I have the SYSTEM_UI flags LAYOUT_STABLE and LAYOUT_FULLSCREEN applied to the Activity. When I remove these 2 flags, the icons in the status bar are properly dark.
But my problem with this "solution" above is that I am using the 2 SYSTEM_UI flags in order to have my Activity's content scroll below the status bar, which I have made semi-transparent. I have not figured out another way to make my status bar accept transparency and have content scroll below it other than using the 2 SYSTEM_UI flags I currently have for this Activity, which are, again SYSTEM_UI_FLAG_LAYOUT_STABLE and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN.
Does anyone have an idea as to how I can get around this issue?
Perhaps someone can show me a reliable way to have my status bar accept transparency and have content seen scrolling below it without having to use the SYSTEM_UI flags? That would likely solve my problem, I think...
The only code I could think would be relevant to share is this:
In my MainActivity.java, I have this set:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);`
And in my styles.xml, I have this theme set for the Light Theme:
<!-- Toolbar/NoActionBar variant of default Light Theme -->
<style name="AppTheme_Light_NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/pure_white_transparent</item>
<item name="colorPrimaryDark">#color/pure_white_transparent</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#color/pure_white_transparent</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:navigationBarColor">#color/pure_white</item>
<item name="android:windowLightNavigationBar">true</item>
</style>
Any ideas?
Okay, so I figured it out on my own. It looks like I probably was needing to set the SYSTEM_UI flags before calling setContentView. Though, it could be a combination of these changes that made it work for me - I'm not entirely sure.
What I changed was using these flags before calling setContentView:
if (lightMode) {
setTheme(R.style.AppTheme_Light_NoActionBar);
getWindow().getDecorView().setSystemUiVisibility
(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
lightMode above is a SharedPreference boolean I have set if the user has selected the Change theme button in my app's toolbar (works the same way for the dark mode/theme).
And finally, for my MainActivity's theme, I have this style set in my styles.xml (for API 27 and above - looks a bit different for lower Android APIs' styles.xml):
<!-- Toolbar/NoActionBar variant of default Light Theme -->
<style name="AppTheme_Light_NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/pure_white_transparent</item>
<item name="colorPrimaryDark">#color/pure_white_transparent</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#color/pure_white_transparent</item>
<item name="android:navigationBarColor">#color/pure_white_transparent</item>
</style>
Because it would appear to me that setting the SYSTEM_UI flags to LAYOUT_FULLSCREEN and LAYOUT_STABLE makes the toolbar sit underneath the statusbar, I've set some appropriate padding by way of:
int statusBarHeight = getStatusBarHeight(this);
Where getStatusBarHeight is a method used to account for the possibly varying sizes of statusbars on different Android devices (such as the Pixel 3XL's larger statusbar).
I got this working method from elsewhere on StackOverflow, but forgot where, so if anyone knows, feel free to link it - method below:
// Gets the StatusBar's height of the particular display.
public static int getStatusBarHeight(final Context context) {
final Resources resources = context.getResources();
final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (int) Math.ceil(24 * resources.getDisplayMetrics().density);
} else {
return (int) Math.ceil(25 * resources.getDisplayMetrics().density);
}
}
}
I've then taken the value of int statusBarHeight and used it as the top margin for my toolbar programatically:
// Setup the values for the toolbar's layout parameters.
CoordinatorLayout.LayoutParams toolbarParams = new CoordinatorLayout.LayoutParams(
CoordinatorLayout.LayoutParams.MATCH_PARENT,
CoordinatorLayout.LayoutParams.WRAP_CONTENT
);
toolbarParams.setMargins(0, statusBarHeight, 0, 0);
// Find, Assign, and Setup the Toolbar to take place of the Actionbar.
// Then inflate the proper menu to be used on-top of it, and set its layout parameters
// which have been set in the code above.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.inflateMenu(R.menu.menu_main);
getSupportActionBar().setDisplayShowTitleEnabled(true);
toolbar.setLayoutParams(toolbarParams);
Finally, I've made sure my app's RecyclerView is properly sitting below both the statusbar and the toolbar, which I have accomplished by setting the appropriate padding to it, also programatically:
// Get and set the values for the OffsetPadding for the RecyclerView to int.
int itemOffsetPaddingSide = (int) getResources().getDimension(R.dimen.item_offset);
int actionBarSize = (int) getResources().getDimension(R.dimen.actionbarSizeWithExtraPadding);
int itemOffsetPaddingTop = actionBarSize + statusBarHeight;
// Set all the OffsetPadding values to the RecyclerView programmatically, so that
// all the UI elements are padding properly, taking into account the devices screen
// density/size/resolution!
mRecyclerView.setPadding(itemOffsetPaddingSide, itemOffsetPaddingTop, itemOffsetPaddingSide, itemOffsetPaddingSide);
The value of int itemOffsetPaddingSide is 4dp, for int actionBarSize it's 60dp and for int itemOffsetPaddingTop, by combining both actionBarSize and statusBarHeight, we get 56dp plus however tall the statusBar for the particular device is (because of the values retrieved and assigned to statusBarHeight in the code further up the post).
This all allows for my RecyclerView's content to sit comfortably below the statusbar and toolbar and also to be visible while scrolling underneath both of them, due to both bars having 90% opacity.
I've been studying Java programming and Android app development for nearly 2 years now independently, and while I'm proud of where I've come in this time, I'm also not sure this is the most elegant way to accomplish this effect in my app. But either way, it works, and if you find it useful for your app too, let me know!

different color on Action Bar MenuItem in different configurations programmatically

I want to set different colors to text of MenuItem that are in action bar and in different configurations - landscape and portrait.
I figured one way to that was have different colors set in Color and Color-land.I've made a custom theme in styles as follows
<style name="MyAppTheme" parent="#android:style/Theme.DeviceDefault.Light">
<item name="android:actionMenuTextAppearance">#style/MyActionBar.MenuTextStyle</item>
</style>
<style name="MyActionBar.MenuTextStyle"
parent="android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Menu">
<item name="android:textColor" >#color/button_color</item>
</style>
and then set the color black in color resource and white in color-land resource.
This would work as the activity will be created when the configuration changes.
However in my activity when the activity is created first an AlertDialog appears which leads to a REST api call and a ProgressDialog follows while the data is fetched from the server.
The problem lies in here when i would change the configuration the activity will be recreated and i will get the AlertDialog again.
if i set in the manifest <activity android:configChanges="orientation" /> the color of the menu item won't change because the activity is never created again but it will avoid the AlertDialog and would maintain the activity state.
I am looking for a way to change the MenuItem Text color in the onConfigurationChanged event. is there some way to do it?

Space between keyboard and EditText in Android

Soft input mode is "SOFT_INPUT_ADJUST_PAN", and when keyboard shown, EditText moves up to stay visible, but the keyboard and txt's bottom are always sticked together as seen on screenshot, I want some space between them, is it possible?
Also input mode must stay as "SOFT_INPUT_ADJUST_PAN".
Sorry form my english, Thanks in Advance...
I applied above methods which worked for me was
Set android:windowSoftInputMode on the Activity to "adjustPan"
than i added the padding to the edittext with gravity bottom
and it works like charm.
Thanks,
May this help you:
If this line is written in your code then remove it:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
OR:
You should not be setting your layout_width and layout_heights with explicit pixel values. Instead, use wrap_parent or fill_parent as appropriate.
OR:
If you have set your minSdkVersion to 3 then change it to minSdkVersion=4
Edit:
Set android:windowSoftInputMode on the Activity to "adjustPan"
OR:
Add this code in your main activity in setOnTouchListener() of your EditText:
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED);
Why don't you try this?
android:windowSoftInputMode="adjustResize"
I know you want to adjust pan but this would solve your problem aswell.
Since you really want to stay with adjustPan, maybe you can try re-designing the XML layout a little bit.
You must also add your required padding to the outer most container element in the layout file.
Simple padding in edit text won't work.
Use drawable with your edit text like below:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp">
<shape android:shape="rectangle">
<corners android:radius="10dp" />
<stroke
android:width="1dp"
android:color="#color/white" />
<solid android:color="#color/transparent" />
</shape>
</item>
</layer-list>
and then use
android:windowSoftInputMode="adjustPan"
in your manifest file.
Just wondering, is your app full screen? does it have the status bar? If it is try to disable full screen mode and try to see if that solves your problem. I remember there was a bug about this some time ago.
try to use GlobalLayoutListener:
private var focusView:View?=null
// Register global layout listener.
decorView?.viewTreeObserver?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
private val windowVisibleDisplayFrame = Rect()
private var lastVisibleDecorViewHeight: Int = 0
override fun onGlobalLayout() {
// Retrieve visible rectangle inside window.
decorView.getWindowVisibleDisplayFrame(windowVisibleDisplayFrame)
val visibleDecorViewHeight = windowVisibleDisplayFrame.height()
// Decide whether keyboard is visible from changing decor view height.
if (lastVisibleDecorViewHeight != 0) {
if (lastVisibleDecorViewHeight > visibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX) {
// Calculate current keyboard height (this includes also navigation bar height when in fullscreen mode).
val currentKeyboardHeight = decorView.height - windowVisibleDisplayFrame.bottom
//keyboardHeight = currentKeyboardHeight
focusView = activity?.currentFocus
focusView.setPadding(0, 0, 0, SET_BOTTOM_PADDING_SPACE) // <---set space here
} else if (lastVisibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX < visibleDecorViewHeight) {
focusView.setPadding(0, 0, 0, 0)
}
}
// Save current decor view height for the next call.
lastVisibleDecorViewHeight = visibleDecorViewHeight
}
})

Show up/back button on android nested PreferenceScreen?

I have a two level PreferenceScreen:
<PreferenceScreen>
general settings
<PreferenceScreen android:key="adv_settings">
more advanced settings
</PreferenceScreen>
</PreferenceScreen>
My problem is that the second screen doesn't show the back/up button on the action bar automatically. How do I make the up button appear on adv_settings?
You can add the arrow by writing a custom ActionBar style to be used with your application theme.
res/values-v11/styles.xml: (or add these to your existing styles.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">#style/MyActionBar</item>
</style>
<style name="MyActionBar" parent="#android:style/Widget.Holo.ActionBar">
<item name="android:displayOptions">showHome|homeAsUp|showTitle</item>
</style>
</resources>
Then apply this theme in your AndroidManifest.xml:
<application android:theme="#style/MyTheme">
Note: The obvious way to add this arrow should be to call:
getActionBar().setDisplayHomeAsUpEnabled(true);
once the second screen has loaded, but I think there's an Android bug where getActionBar() always returns the first-tier ActionBar object, as opposed to the one that is currently visible, so setting the arrow dynamically fails.
This may be more work, but you could create two PreferenceAtivity files each with their own PreferenceFragment. Each PreferenceFragment will have its own PreferenceScreen XML (the first level screen, and the second. level screen). From the firsts level screen you launch the second PreferenceActivity with an Intent within the tag. In the second PreferenceActivity you can set the home icon by doing this:
ActionBar bar = getActionBar();
bar.setDisplayHomeAsUpEnabled(true);
and then also had a handler for the home button:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == android.R.id.home) {
finish();
}
return false;
}
Assets:
FirstPreferenceActivty
FirstPreferenceFragment
pref_first.xml (layout with PreferenceScreen and Prefernce nodes)
SecondPreferenceActivty
SecondPreferenceFragment
pref_second.xml (layout with PreferenceScreen and Prefernce nodes)
If the button does not come automatically, you could add it manually like done on these links:
Android: How can make custom PreferenceScreen?
http://pastebin.com/334Eip35
There is a example code in second answer of that SO question and the snippet in it is taken probably from the another pastebin location.

Categories

Resources