I want to make a fully transparent status bar and navigation bar like Google Play did. When I use window settings to achieve it, the keyboard covers EditText.
When this code used EditText covered by Keyboard Input:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
Also this code doesn't make it fully transparent, it just makes it translucent
getWindow().setNavigationBarColor(Color.TRANSPARENT)
or this
<item name="android:navigationBarColor">#android:color/transparent</item>
I need a window like this:
What you need is something like this:
class Utils {
static void enableInmersiveMode(Activity act, boolean drawBehindNavBar) {
View rootView = act.getWindow().getDecorView().getRootView();
int uiFlags = rootView.getSystemUiVisibility();
int flags =0;
if(drawBehindNavBar) { flags = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; }
flags = flags | uiFlags | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEEN;
rootView.setSystemUiVisibility(flags);
}
}
And in your onCreate of your activity:
#Override
void onCreate(Bundle b) {
Utils.enableInmersiveMode(this, true);
super.onCreate(b);
// setContentView and the rest of your code here...
}
Take in mind that afterwards views will go behind the system UI and you'll need to dynamically add padding to the first and last Views so the user can interact with them.
Hopefully, you can try this in your-main-path/res/values/styles.xml
This is for transparent Status Bar and Navigation Bar in any android devices.
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:navigationBarColor">#android:color/transparent</item>
One more thing if you want to try transparency and float the to the bar you can use this but the background of Navigation Bar will reduce 50% of transparency.
<item name="android:windowTranslucentNavigation">true</item>
When you want to unset the TranslucentNavigation float, this one can fit the screen between Status Bar and Navigation Bar
<item name="android:fitsSystemWindows">true</item>
Related
Like the title, I am wondering how to get rid of the green bar at the top so that it matches the background of the activity. I have no idea where to look I've had a look in the manifest and haven't found anything.
What do I do so that it matches the background of the activity?
Note. Different activities have different backgrounds, so is there a way that I just match the activity it is on?
The green bar is called Status bar, and to hide it in activity call below method in onCreate()
void hideStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
getWindow().getDecorView().setSystemUiVisibility(uiOptions);
} else {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
And to hide it in a fragment, call it in onCreateView()
void hideStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
requireActivity().getWindow().getDecorView().setSystemUiVisibility(uiOptions);
} else {
requireActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
You can change status bar color using this extension function, call this function from Activity just passing the color
fun AppCompatActivity.changeStatusBarColor(#ColorRes color: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.statusBarColor = ContextCompat.getColor(this, color)
}
}
go to following path:
app->res->values->styles
and here in style tag three item tags are available, in that colour of first and last item keep same.
then app status bar and action bar colour display same.
Example:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here.
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
-->
<item name="colorPrimary">#FFA500</item>
<item name="colorPrimaryDark">#FFA500</item>
</style>
This question specific to the issue with Xiomi devices with MIUI over it.
How can I detect Fullscreen Mode (Gesture) or Navigation Button (soft navigation) is selected?
I Have tried a few solutions, but that does work on other devices but didn't work on Xiomi or MIUI.
I have tried this solution available on SO, so please provide another if you have.
1
public boolean hasNavBar (Resources resources)
{
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
return id > 0 && resources.getBoolean(id);
}
2
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
if (hasBackKey && hasHomeKey) {
// no navigation bar, unless it is enabled in the settings
} else {
// 99% sure there's a navigation bar
}
3
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
// TODO: The navigation bar is visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
} else {
// TODO: The navigation bar is NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
}
}
});
Any idea of how can I get to know that the navigation bar is currently visible or not?
I also tried to calculate the real width and available width, it seems like MIUI always returning the reserved with of navigation bar.
Thanks.
There is no need to detect if Soft input navigation bar is visible or hidden for full screen activity you can create style and apply style to activity.
<style name="Theme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowDrawsSystemBarBackgrounds" tools:targetApi="lollipop">false</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
and add following line in activity :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
This is led you to stop the layout overlap from soft input navigation.
I have the same problem too. I found 2 solution:
This solution works for me for versions above Android Q.
public static int isEdgeToEdgeEnabled(Context context) {
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("config_navBarInteractionMode", "integer", "android");
if (resourceId > 0) {
return resources.getInteger(resourceId);
}
return 0;
}
If this method returns 2 then Full screen mode is enabled.
2.This solution works for me above Android Q and below it:
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(android.R.id.content)
) { _: View?, insets: WindowInsetsCompat ->
navigationBarHeight = insets.systemWindowInsetBottom
insets
}
I used 2 method myself
I simply want to change the backgroundTint of a normal button from inside the java code. I tried many different approaches like ColorStateList or setColorFilter, but nothing worked. I am purposefully not using setBackgroundColor since I want to keep the original shape of the button.
Furthermore, the colors I want to use are already defined in my resources. After lots of trial and error I managed to access these colors with this code:
int colorBtnDeactivated = ContextCompat.getColor(this, R.color.colorBtnDeactivated);
So basically I only need this one line of java code which enables me to access the background tint. The rest I can do myself.
I would really appreciate help, I have been stuck on this problem for hours. Thanks!
Edit: Using a selector-xlm didn't work, since it only changed the color of the button while being pressed. Also the buttons will influence each other, so by pressing one button I will need to be able to change the background tint of another button.
Edit 2: I tried again with setColorFilter:
//this is all inside the onCreate-method
int colorBtnActiveTest= ContextCompat.getColor(this, colorBtnActive);
int colorBtnDeactivatedTest=ContextCompat.getColor(this, colorBtnDeactivated);
Button btnKnockOne = (Button)findViewById(R.id.btnKnockOne);
boolean stateBtnKnockOne = false;
btnKnockOne.getBackground().setColorFilter(colorBtnDeactivatedTest, PorterDuff.Mode.SRC_IN);
btnKnockOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (stateBtnKnockOne==false){
btnKnockOne.getBackground().setColorFilter(colorBtnActiveTest, PorterDuff.Mode.SRC_IN);
stateBtnKnockOne=true;
}
else if (stateBtnKnockOne==true){
btnKnockOne.getBackground().setColorFilter(colorBtnDeactivatedTest, PorterDuff.Mode.SRC_IN);
stateBtnKnockOne=false;
}
}
});
This is the result:
When I open the activity, the button is displayed in the default grey button color, not in my custom color colorBtnDeactivatedTest
When I press the button, it briefly changes its color to colorBtnActiveTest, but then goes back to its grey color
I finally found a solution! This post helped me find it: https://stackoverflow.com/a/8748112/8952749
Now I basically have two buttons of which only one can be selected at one time. For this to work I created a selector-xlm:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="#drawable/button_active" />
<item
android:state_selected="false"
android:drawable="#drawable/button_deactivated" />
</selector>
This is the java code, which enables me to change state_selected of the buttons:
stateBtn1=false;
stateBtn2=false;
btnTest1=(Button)findViewById(R.id.button);
btnTest2=(Button)findViewById(R.id.button2);
btnTest1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (stateBtn1==false){
btnTest1.setSelected(true);
stateBtn1=true;
btnTest2.setSelected(false);
stateBtn2=false;
}
else if (stateBtn1==true){
btnTest1.setSelected(false);
stateBtn1=false;
}
}
});
btnTest2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (stateBtn2==false){
btnTest2.setSelected(true);
stateBtn2=true;
btnTest1.setSelected(false);
stateBtn1=false;
}
else if (stateBtn2==true){
btnTest2.setSelected(false);
stateBtn2=false;
}
}
});
I have 3 buttons, all of them have the same background drawable by default (subject_button)
What I want to do:
When I click one button his background changes ( to clicked_subject), all the others remain with the default background, if I click one button after clicking another, the button I just clicked changes his background while the previous one gets back to the initial background, allowing only one button to have the clicked_subject background, if the diffrent button gets clicked again his background goes back to the initial one, leting all the buttons with the initial background.
The problem:
If I click the diffrent button, his background remains the same instead of changing back to the initial one.
My logic:
theButton1.setBackgroundResource(R.drawable.subject_button);
theButton1.setOnClickListener(this);
//same for other 2
#Override
public void onClick(View v) {
if (v.getBackground() == ContextCompat.getDrawable(this, R.drawable.subject_button)) {
theButton1.setBackgroundResource(R.drawable.subject_button);
theButton2.setBackgroundResource(R.drawable.subject_button);
theButton3.setBackgroundResource(R.drawable.subject_button);
v.setBackgroundResource(R.drawable.clicked_subject);
} else {
v.setBackgroundResource(R.drawable.subject_button);
}
Why is this happening?
You can do this:
private final List<Button> mButtons = new ArrayList<>();
// somewhere in your code
mButtons.add(mButton1);
mButtons.add(mButton2);
mButtons.add(mButton3);
mButton1.setOnClickListener(mClickListener);
mButton2.setOnClickListener(mClickListener);
mButton3.setOnClickListener(mClickListener);
private final View.OnClickListener mClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
for (Button button : mButtons) {
if (button == v) {
// set selected background
} else {
// set not selected backround
}
}
}
};
If you define a stateful drawable for your buttons, then you can simply change the onclick to this:
private final View.OnClickListener mClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
for (Button button : mButtons) {
button.setSelected(v == button);
}
}
};
For changing background color/image based on the particular event(focus, press, normal), you need to define a button selector file and implement it as background for button. For example button_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/your_image1" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="#drawable/your_image2" /> <!-- focused -->
android:drawable="#drawable/your_image3" <!-- default -->
</selector>
then just apply it as :
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawable="#drawable/button_selector.xml" />
I solved it by instead of changing only the background color on clicking the button, I also change the textColor, then I can check the textColor with if (((Button) v).getCurrentTextColor() == Color.WHITE)
"Pressed", "selected", "disabled" and such are View states. As such they're supposed to be handled automatically by Android and not by your click listeners.
This is achieved using SateLists, which control the look your Views sould have depending on which state(s) they're in. So you can easily set subject_button as the unpressed state, clicked_subject as the pressed state, and let Android take care of actually switching between them.
Full explanation: https://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
I'm using a simple ListView for my navigation drawer, with android:choiceMode="singleChoice" set in the layout XML. This allows me to use a selector for the text color:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:color="#color/primary_500" />
<item android:color="#color/text_primary" />
</selector>
Which will color the selected item with primary_500 and the rest with text_primary.
The above is working fine, but one of the items will launch a new activity instead of loading a fragment, so it should never be made the ListView's selected item.
I've tried reverting it with this:
public void selectItem( int index ) { selected_item = index; }
public void revertSelectedItem() {
int y = navigation.getScrollY();
list.setSelection( selected_item );
list.scrollTo( 0, y );
}
And elsewhere:
#Override
public void onItemClick( ListView list, View view, int index, long id ) {
switch( (int)id ) {
case R.id.exampleItem_forFragment:
/* Swap fragments */
selectItem( index );
break;
case R.id.exampleItem_forActivity:
/* Launch activity */
revertSelectedItem();
break;
}
}
But, even though revertSelectedItem() is called, the selection does not change. I'm presuming that the new selection is not assigned until after onItemClick() returns, so my change is getting overwritten.
Is there a clean way to disable or revert selection changes for only certain items, but still receive click events?
Seems I just misunderstood the purpose of some methods. Changing revertSelectedItem() to look like this:
public void revertSelectedItem() {
list.setItemChecked( selected_item, true );
}
behaves exactly like I want. It looks like ListView uses the item's "checked" state, rather than the selection, to decide which items are marked. When in choiceMode="singleChoice", calling setItemChecked() also unchecks all other items automatically.