How to keep background image size when software keyboard show - android

When the software keyboard shows, it resizes my layout and thus squeezes the background image together. My question is basically a duplicate of this question, which is explained in a very good way:
Software keyboard resizes background image on Android
However, that question was closed when they found a hack to solve it. I cannot use this hack. My entire layout is inside a ScrollView, and I need to be able to use this scrollview properly at all times. By using android:windowSoftInputMode="stateVisible|adjustPan" the user will not be able to scroll down and see the bottom of the screen while the keyboard is showing, since the layout will partly exist behind the keyboard. Thus the solution is unacceptable to me. Are there any better solutions out there?
Cheers,

I actually ran into a similar problem not too long ago. I stumbled upon the correct answer with a bit of work, though.
In your android manifest for this project, attached to the specific activity that you are using, use the line android:windowSoftInputMode="adjustPan|stateVisible" in the activity tag.
adjustPan basically means that your activity will not resize itself to fit the soft keyboard, and stateVisible means that the soft keyboard will show when requested (this can be stateAlwaysVisible, etc if necessary)
source :
Android Dev for Activity tags

After days of hardcore hacking I finally managed to construct a solution so advanced it might actually hurt to read it. I place an ImageView with the background behind the scrollview, and set scaleType="matrix" so it does not shrink when the keyboard is shown.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/black"
>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/mah_kewl_background"
android:scaleType="matrix"
/>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
>
<RelativeLayout
android:id="#+id/smsLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="PLUNX"
/>
</RelativeLayout>
</ScrollView>
</RelativeLayout>

You can use the windowBackground property, which makes the drawable fit the whole screen.
To do that you need to:
1- Create a style:
<style name="Background" parent="#android:style/Theme.NoTitleBar">
<item name="android:windowBackground">#drawable/you_bg_drawable</item>
</style>
2- Set your activity style in the AndroidManifest.xml
<activity
android:name=".ui.your_activity"
android:theme="#style/Background"/>

I was googling for a solution to this exact problem when I came across this, and after doing some research I found a solution I think is slightly better. Instead of hacking with a ImageView you can use this from your activity:
getWindow().setBackgroundDrawableResource(R.drawable.bg_my_background);
Hope it helps anyone else searching for a solution for this.

I can't comment on your answer but I'd like to add something.
I understand your dilemma and why the solution you linked to isn't a complete solution for your situation (since you can't scroll to the bottom of the view). I have a similar situation with a large scrollable EditText box. When the soft keyboard pops up I don't like my background getting squished.
I have tried your solution and while at first glance it appears to work, there are some situations where it might not be ideal:
If you allow your app the have a landscape mode, the background will not resize/stretch
If you run your app on a device with a larger screen or dpi, your background may not fill the screen
Basically it seems that when you set the scaleType to matrix you're telling Android to draw the background 1:1 and not to scale. So what's happening when you open the soft keyboard using your solution is, your scrollView and imageView are all getting resized as usual, but the image src you set remains 1:1 thus continues showing the same area.
So if for example your background image was set to a specific size (e.g. 480 x 800) and it perfectly fills your Nexus One, the moment you rotate to landscape you will have a black area along the right.
This is moot, of course, if your background is simply a repeating pattern, in which case you can make it extremely large and hopefully compensate for various screens (maybe even tablets).
Or you can also supply different backgrounds for different screen sizes/densities/orientations, but this still doesn't account for scaling.
In a vain effort to try and solve this, I stumbled upon a View attribute called android:isScrollContainer. This attribute tells certain views whether or not they are allowed to resize upon display of the soft keyboard. This is also mentioned by someone in your linked solution. I have tried setting this (to false) on the ViewGroup containing my background, but any child element that scrolls seems override it causing the squishing again.
As of right now I don't think there is a complete solution for our situation. Your's definitely works in some instances and I thank you for the effort. Hopefully Google will offer a solution in the future, but I don't think they would consider this a problem/priority.

Maybe there's another (really simple!) solution:
In styles.xml:
create a new style like this:
<style name="Yourstyle" parent="AppBaseTheme">
<item name="android:windowBackground">#drawable/mybackground</item>
</style>
AppBaseTheme is your normally used theme for your app.
Then you add in Manifest.xml:
<activity
android:name="com.your.app.name.Activity"
android:theme="#style/Yourstyle">
</activity>
So you have the same style but with a background.
Important: don't set any backgrounds in your normal .xml file!
It's my first post and I hope it helps and sorry for my English.

in Androidmanifest in activity tag use:
<activity ... android:windowSoftInputMode="adjustPan" ></activity>
check Android Developer reference

How about a solution where the 'background' is a Layout. Can we inflate a layout, make it the entire window size, then insert it as a window background?

After a lot of time searching...
Put android:windowSoftInputMode="adjustPan|stateVisible" in each Activitys

Related

Elements of the layout not showing in phone auto-rotate mode

I am participating in the Udacity Android Basics degree. I am struggling with the project explained below. I am yet using only basic knowledge so please do not be surprised by the code simplicity. :)) I am eager to understand how to position elements so that they appear in every phone orientation mode using RelativeLayout.
You can find the XML here.
There are two screenshots of the app displayed in portrait and auto-rotate. The portrait looks alright but in auto-rotate half of the information displayed disappears.
My second question is related to the clickable elements. Once, I made them clickable they turned into red and underlined. Is this common or I should offset this with another statement?
This is my GitHub project.
Any help is appreciated.
Thanks,
Iva
For Your First Issue of Portrait and Landscape Try to put your view contents in a scrollview so that the screen contents will be scrollable when the height of the view is more than the screen height (In Portrait and Landscape Modes)
Sample with your code
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.helloandroid.MainActivity"
android:background="#03B3E4">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
Add Your Contents Here ...
</LinearLayout>
</ScrollView>
For the Second question
Textviews with android:autoLink="" always takes the color from your colorAccent in styles.xml in your project if it has text that can be linked like website or mobile or map
you can change the text color by adding android:textColorLink="yourcolorhere"
to your textviews
Thanks
For auto-rotation, you can either lock rotation for your app locking screen rotation. You can use any of the methods suggested by other developers.
But If you want to add landscape orientation to your app, then you will have to define a separate XML layout file for it. You can do so by Creating a
layout-landdirectory by right clicking layout under res and putting the landscape version of your layout XML file in that directory. You can also refer to this answer for some help handle screen rotation without losing data in android
Coming to the second part of your question, if you make an element clickable, it is not supposed to turn red and underlined. I am not sure how you are making them clickable but to make an element perform a function on Click, just declare the element and define it. Then you can set an OnClick listener to it. You can see an example here making a button clickable. Youcan also try this code to make the button clickable:
Button btn= (Button) findViewById(R.id.button_main);
btn.setClickable(true);

Is it possible to disapper the border of image button at particlualr selected areas in android?

I am trying to set a border for few of the image buttons for a particular screen layout in android. But for some buttons, I want to disable the border if the screen-layout background is blue colour. Please help me how to do this?
(I assume you design your app with Material Theme)
I think you can't do it (maybe possible with some hacky technique), because it's not intended to be that way.
Google has designed each view to underline each of their own purposes. So, I believe, If you can modify a button that way, it won't felt like a button to users thus can raise some misunderstanding.
What possibly user think if such button that doesn't have default blue, exist? Do they still think that as a Button?
Personally, I suggest that you leave the border as-is, if you still intended to make it feels like a Button.
Otherwise, if you really need it, you can always use CardView, put an ImageView inside it and attach OnClickListener to it. I think the result is quite similar because almost every rectangular view Google has nowadays, got similar visual to CardView.
Btw, I made this in my recent project to achieve a borderless Button-ey Image. Maybe it'll help.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true"
card_view:contentPadding="0dp">
<ImageView
android:id="#+id/clickable_photo_thumbnail_image_view"
android:layout_width="#dimen/photo_thumbnail_size"
android:layout_height="#dimen/photo_thumbnail_size"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
</android.support.v7.widget.CardView>
(UPDATE) This is the screenshot from my app, produced with above code:
(In my screenshot, I already use a RecyclerView)

What is the ButtonBarLayout and how should we use it?

When I developed, I found a new widget called android.support.v7.widget.ButtonBarLayout unexpectedly. I tried to search it on the internet, but nothing was found, even on the official development documents site.
In the meantime, I found two ButtonBarLayout when I search ButtonBarLayout everywhere in Android Studio, one is android.support.v7.widget.ButtonBarLayout and the other is com.android.internal.widget.ButtonBarLayout. I tried to read source codes of both, I found that they are the same except package name. So I thought maybe android.support.v7.widget.ButtonBarLayout came from com.android.internal.widget.ButtonBarLayout after the internal ButtonBarLayout was through tests and released. At the same time, ButtonBarLayout is inherited from LinearLayout.
But there are some question:
What can we get from ButtonBarLayout literally and how should we use it?
I noticed the variable of private boolean mAllowStacking. When it changes, orientation of this layout would be changed. But I didn't really understand what it is used for.
So does somebody know ButtonBarLayout well?
P.S.: I used Android Studio of 2.0.0 Preview 4 and Gradle Plugin of 2.0.0-alpha3 and Android Support Library of 23.1.1 and Platform-tools of 23.1 and Build-tools of 23.0.2.
As others pointed out, the class description tells exactly what it is: an extension of LinearLayout that automatically switches to vertical orientation when it can't fit its child views horizontally.
I might add that this was clearly done to fit with the material design specifications about dialogs. They make a distinction between side by side buttons and stacked buttons. See for example:
Side-by-side buttons are recommended when the text of each label does
not exceed the maximum button width, such as the commonly used
OK/Cancel buttons.
While you should go for stacked buttons when the single button is too large, or there's not enough room for both:
When text labels exceed the maximum button width, use stacked buttons
to accommodate the text. Affirmative actions are stacked above
dismissive actions.
So, one possible use of this class, is when designing your own dialogs. For example, AlertDialog and AlertDialog.Builder offer internal support for dialogs with buttons, but sometimes you just want to subclass DialogFragment or AppCompatDialogFragment for a better control.
There, it might be useful to setup a bottom button bar that follows the design guidelines, and have full control on the buttons (like enabling and disabling, things you can't do with an AlertDialog AFAIK).
The source code describes ButtonBarLayout as follows:
/**
* An extension of LinearLayout that automatically switches to vertical
* orientation when it can't fit its child views horizontally.
*/
So, in essence, it is nothing but a smart LinearLayout which manages auto-switching orientations based on available space on screen.
The same ButtonBarLayout.java file describes mAllowStacking in comments as follows:
/** Whether the current configuration allows stacking. */
Source Code Here
You are right first of all. ButtonBar layout does not seem to be featured anywhere in the official Android documentation. I tried myself to search about it, but to no avail. However I have found some information which defines what is a ButtonBar layout and when to use it. Hopefully this will help you.
Most tutorials use the Buttonbar layout in a dialogbox or at the bottom of a screen to confirm or decline an option. The image below is a visual representation of how the ButtonBar layout has been used in a screen.
The screenshot above has the following layout xml:
<LinearLayout
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/Button01"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Show" />
<Button
android:id="#+id/Button02"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Change" />
</LinearLayout>
<EditText
android:id="#+id/myView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
So essentially what Android is doing here is simply creating two buttons next to each other in a LinearLayout with each button having the match_parent parameter set to the width. Hence each button takes half the size of the screen. Android have actually taken away the hassle of creating seperate buttons and positioning them correctly to fit different screens, by creating a simple widget handling this altogether.
As with the support library, Android have implemented this for developers using an earlier API. It is normal for them to use the support library for this purpose.
Hope this helps :)
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/com/android/internal/widget/ButtonBarLayout.java
Looking into the code, I think it's a LinearLayout for buttons (duh). You can probably look at it like the Dialog buttons divided by a vertical spacer: | . AllowStacking will change the orientation to vertical and the gravity to the right instead of bottom. I should try it out to give a better answer
ButtonBarlayout is not featured anywhere in the official Android documentation.
it is used for auto-switching orientations according to the space.
Regarding your question:
How should we use it?
I guess it is undocumented because it is not stable yet.
It just popped up because this long lasting complaint originate from poor ROM modification by device vendor.
https://code.google.com/p/android/issues/detail?id=78377
See #270 for the resolution regarding classpath and why all classes inside .internal. were made public.
And nope even that fix a lot of bugs from poor ROM modification are still out there (in lots of device of well known brands). The issue is soon declined by project member.
I don't think we should use it just yet until the document show up.
Just my $.02 though.
Just to add to the other answers, if you guys want to check the orientation of a ButtonBarLayout you should check the orienation AFTER the value has called on measure.
In other words (Kotlin):
buttonBarLayout.post {
val orientation = buttonBarLayout.orientation
val height = buttonBarLayout.measuredHeight
}

GPU Artifacts on Android app

I've an app which have a very strange problem. Sometimes when launching the app all the fragments suffer this issue. It looks like the GPU is doing something fancy with it.
In the animated Gif below you can clearly see a PreferenceFragment which has the above mentioned artifacts.
Edit 1. it looks like i've a specific fragment that once "draws" on screen the bug appears. Switching fragment using .replace won't actually "clean" the problem.
How can i debug this?
it looks like garbage coming from the GPU.
The first thing you need to look at is your window background (and after that, the various fullscreen layouts backgrounds).
It is probably defined as null or another similar issue.
Ok my problem was caused because I had within my theme
<item name="android:windowBackground">#color/dark</color>
where dark is a color item set to #313131
Then i had a view that I used as a cover over some other piece of content to darken the underlying views as follow:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/mydrawable"
/>
<View
android:id="#+id/coverview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/dark"/>
</FrameLayout>
Programmatically I had to set the alpha of the coverview by using coverView.getBackground().setAlpha((int)(0.6f*255));
Surprisingly this new alpha value was also applied to the window background and generated a lot of artifacts you see in my question (even after switching fragment where the coverview was no longer in the view tree)
By default, all drawables instances loaded from the same resource share a common state. Hence my code was wrong and i needed to call .mutate on the background before applying the new alpha value.
Except for me being wrong # calling .setAlpha without calling .mutate() the GPU flickering is still a mistery to me.
Why the GPU Flickers then? As pointed out by Christophe here:
the GPU flickers cause the background is now translucent and the
system tries to blend it with what was currently in the empty buffer
(mostly garbage).
To showcase the bug problem I created a github repo with a sample project showcasing the issue here: https://github.com/vekexasia/gpuflickering-background-alpha
Workarounds: Several. If you like to use the same approach (which also causes overdrawing) you should set the color programmatically and then set the alpha value to it. Like so:
coverView.setBackground(new ColorDrawable(getResources().getColor(R.color.dark)));
A better approach would be to apply a ColorFilter to the ImageView or if you're using Picasso use a Transformation
Another approach would be to just call .mutate() before .setAlpha()

Design view problem in xml file : Android

When I run my application, buttons are not displaying(A little part is displaying, that makes feel that something is there), although I scroll down.
How to solve my problem. Is there any way to set size of textboxes (Where size depends on screen size).
Pankaj did you checked the orientation of the root LinearLayout tag ??
All you need to do is change root LinearLayout's orientation to vertical & you will see every button in your layout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
& please read more about layouts before implementing them.
As #100rabh already said you should really start reading about Android layouts.
Some very good articles by Romain Guy are here and of course on his blog.
There is also a very good series of articles on Mobiletuts+ called Android User Interface Design by Lauren Darcey and Shane Conder.
You should really check that out and then redesign your layout.
As you're using linear layouts, you can use android:layout_weight. If you search, you'll find many examples.

Categories

Resources