I have this strange "bug". A button that change its backgroundcolor inside a scrollview cause the scrollview to scroll up.
Layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="#layout/img_loading" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:id="#+id/txt_read_story_title" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:id="#+id/txt_read_story_author"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:id="#+id/txt_read_story_content"
/>
<include layout="#layout/inc_reactions_buttons" />
</LinearLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
Inside the inc_reactions_buttons.xml layout there are six buttons in an horizontal linearlayout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal">
<ImageView
android:id="#+id/btn_funny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_reaction_funny" />
...
</LinearLayout>
In the OnClickListener of this buttons, I change the enabled and the backgroundColor of them
mBtnLove.setEnabled(false);
mBtnLove.setBackground(Color.parseColor("#FF000000"))
The problem is that when a button is clicked, the scrollView scroll to the top.
If I remove the setBackground, the scroll doesn't happens.
I've already tried to use other types of view (ImageView, ImageButton) but the result is the same.
Happens on API 25 and 26 (didn't test on earlier version)
Anyone knows the reason?
Thanks
Ok, found a solution.
As I stated in a comment above, the problem is caused by the TextViews having the attribute "textIsSelectable" set to True. It is not clear the reason (something calling the requestChildFocus), but I've found a workaround. In my buttons code, I set the textIsSelectable attribute to false, then change the backgroundColor of buttons, then reset the textIsSelectable to true.
Anyone have a better option?
Had same problem. In my case, simply setting
setKeyListener(null);
setFocusable(false);
for each EditText inside my ScrollView, fixed it.
Setting textIsSelectable to false is a solution too.
Related
I have a login layout with two EditText and a Button. When I'm typing some text in EditText, as the keyboard open it overlap the some of my layout. I try to scroll up but not able to scroll up layout to be visible. I'm using Relative Layout to create it. How to solve it?
Thank you.
Place your EditTexts and Button inside a ScrollView. Whatever is inside ScrollView can be scrolled. So your problem will be solved.
Note that ScrollView can host only one child. So you have to place all your Views inside a ViewGroup like LinearLayout or RelativeLayout
Although Julia Zhao's answer is correct, it uses RelativeLayout. If you use RelativeLayout you have to do more work to make your Views appear one below the other. So I suggest you to use LinearLayout with android:orientation="vertical" inside it. It will automatically place one View below the other without any extra effort. So you won't issues like one View overlapping on other.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="UserName"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:hint="Password"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Login"/>
</LinearLayout>
</ScrollView>
Try nesting everything in a ScrollView, hope this helps.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#id/RLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
xmlns:android="http://schemas.android.com/apk/res/android"
>
// Your code
</RelativeLayout>
</ScrollView>
In my app, there is a tabbed activity with three fragments. The first fragment has a form to create a new task, the second fragment has the list of all the saved tasks, and the third fragment will show the comments on a task when selected from the list in the second fragment. The third fragment is also supposed to act like a chat activity which posts comments when you type them in and tap the send button. The XML layout of this third fragment is as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
android:orientation="vertical"
tools:context="com.example.ishita.assigntasks.CommentsFragment">
<TextView
android:id="#+id/frag_task_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#dd55ff"
android:padding="10dp" />
<ListView
android:id="#+id/frag_comment_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:transcriptMode="normal" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#android:color/white">
<EditText
android:id="#+id/frag_msg_edit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:layout_weight="1" />
<ImageButton
android:id="#+id/frag_send_btn"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:background="#android:color/background_light"
android:contentDescription="#string/send_btn"
android:src="#android:drawable/ic_menu_send" />
</LinearLayout>
</LinearLayout>
As you can see, there is a TextView and a ListView and below that is another LinearLayout. Here is how it should look (the purple bar is the TextView):
And here is how it actually looks:
The TextView shows up above the ListView, but the LinearLayout does not. It is there, though. If I do android:layout_marginBottom="20dp" on the outermost LinearLayout, it does show up, but the ActionBar scrolls up and overlaps with the notification bar so that the title on the ActionBar and the notifications on the notification bar are both visible simultaneously and neither is legible.
I searched a lot and this seemed a common issue, but none of the solutions helped me. Believe me, I tried everything I could find. I tried wrapping the whole thing in a FrameLayout, using a RelativeLayout in place of the outermost LinearLayout, using two LinearLayouts--one to wrap the TextView and the ListView and the other to wrap the EditText and the ImageButton, etc., but nothing was able to show the bottom LinearLayout below the ListView. I even tried to set focus on the EditText when the fragment launches so that the keyboard would show and I can type, but even that doesn't help.
Note: On the other hand, if I use the exact same layout on an activity, the bottom LinearLayout displays exactly as it should.
I am unable to find the bug. Please help!
It looks like your toolbar pushes fragment layout down without decreasing its height. I have no idea why this happens (there are no root layout code here).
As a workaround you can set fragments layout bottom margin to ?attr/actionBarSize
As you have given layout_weight 1 in listview layout, so it occupies the whole space available. In order to get rid of you have to give some static height or use layout_weight in right manner
<ListView
android:id="#+id/frag_comment_list"
android:layout_width="match_parent"
android:layout_height="500dp"
android:transcriptMode="normal" />
or try like this
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
android:orientation="vertical"
tools:context="com.example.ishita.assigntasks.CommentsFragment">
<TextView
android:id="#+id/frag_task_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#dd55ff"
android:padding="10dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:background="#android:color/white">
<ListView
android:id="#+id/frag_comment_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transcriptMode="normal" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:background="#android:color/white">
<EditText
android:id="#+id/frag_msg_edit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:layout_weight="1" />
<ImageButton
android:id="#+id/frag_send_btn"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:background="#android:color/background_light"
android:contentDescription="#string/send_btn"
android:src="#android:drawable/ic_menu_send" />
</LinearLayout>
</LinearLayout>
All,
Thank you for all your responses. I found a workaround by trial and error now and thought I should post the answer for others who face the same issue. I set android:layout_marginBottom="50dp" on the inner LinearLayout (the one wrapping the comments bar--EditText and ImageButton). Somehow, this sets the layout correctly and the fragment functions properly in both Lollipop and Jellybean OS's. I haven't tested on other OS versions.
First of all you should read this, what is layout_weight and how it works.
You assigned layout_weight to ListView as 1, it means it covers whole height. just change it to 0.7 or any proportion you want (less than 1) will solve the problem.
<ListView
android:id="#+id/frag_comment_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.7"
android:transcriptMode="normal" />
I have a layout something like this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:background="#ff303f"
android:id="#+id/layout">
<ImageView
android:id="#+id/picture"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerInParent="true"/>
<Button
android:id="#+id/cancel"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignRight="#id/picture"
android:background="#drawable/cross_out"/>
</RelativeLayout>
I inflate it using the usual layout inflator service, set up some functionality to the button and an image to the imageview (all images are of same size and aspect ratio).
After that, I add this view to my fragment's layout which is nothing but a ScrollView which is a parent, it has a child linear layout that I call 'map' and simply add it to the map.
Expected : The added layouts should get added properly and I can scroll through it.
Actual : If more than 2 are added, the first one gets eaten up. I can see it half or sometimes it is completely eaten up. :\
Any idea whats going on here? Thanks a lot for your time.
EDIT:
Here's the layout file I add the inflated layout into:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f6ff45">
<LinearLayout
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#43ff44"
android:orientation="vertical"
android:layout_margin="10dp"
android:layout_gravity="center"
android:layout_marginTop="15dp">
</LinearLayout>
</ScrollView>
I also forgot to mention that after adding 3 or more of these layouts, I realized there's unnecessary empty space in the end. :\
If you have some android:layout_gravity or gravity property in your ScrollView, that may be the reason. Try deleting it, or make it center_horizontal.
Try this code for your layout file;
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f6ff45">
<LinearLayout
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#43ff44"
android:orientation="vertical"
android:layout_margin="10dp"
android:layout_gravity="center"
android:layout_marginTop="15dp">
</LinearLayout>
</ScrollView>
As I mentioned before, android:layout_gravity="center"in this LinearLayout causes this problem. Because it doesn't only horizontally center but also verticelly center the contents. It means when they are longer than the available height, the center part will appear. I only changed it into android:layout_gravity="center_horizontal" and the problem is fixed.
As easy as it seems to be, as stubbornly this ListView won't center itself (or it's content within - doesn't matter to me).
This is activity layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.drobiazko.den.mobineon.MainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
android:background="#drawable/bg">
<RelativeLayout android:id="#+id/clock_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!--<RelativeLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/holo_blue_dark">-->
<com.drobiazko.den.mobineon.ListViewRowsHeight
android:id="#+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:overScrollMode="never"
android:scrollbars="none"
android:divider="#null"
android:listSelector="#android:color/transparent"
android:persistentDrawingCache="scrolling|animation"
android:background="#android:color/holo_green_dark" />
<!--</RelativeLayout>-->
</LinearLayout>
This is ListView's item layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="#+id/btn_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/custom_btn_icon" />
<TextView android:id="#+id/btn_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/custom_btn_name" />
<TextView android:id="#+id/btn_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/custom_btn_count" />
</RelativeLayout>
I've tried everything (including simplifying layout to max), but it still won't go.
Funny that the first relative layout clock_container - centers like a charm, due to parent LinearLayout's android:gravity="center_horizontal". Why won't ListView?
Added later:
Inspired by FOliveira's answer, I've done some investigation and found that:
everything works fine, parent LinearLayout has android:gravity="center_horizontal" and centers his children respectfully. The reason for ListView's children are left-aligned is that ListView takes all possible width despite his android:layout_width="wrap_content" attribute.
Anyone knows why is that?
First of all , i would remove the first linear layout and stay only with the relative layout as the parent.
After having the relative layout as the main parent , set the CENTER_IN_PARENT attribute to true.
The mistake you are making is that you are setting the gravity of Linear Layout child to center horizontal, which is correct, but the only children being affected by this option is the Relative layout itself.
My Android app's main activity looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background"
android:orientation="vertical" >
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ScrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:orientation="vertical"
android:paddingLeft="60dp"
android:paddingTop="53dp" >
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/billAmountText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/billAmount_string"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/billAmount"
android:layout_width="173dp"
android:layout_height="wrap_content"
android:layout_below="#id/billAmountText"
android:layout_marginTop="3dp"
android:inputType="numberDecimal" />
</RelativeLayout>
</ScrollView>
</RelativeLayout>
In order to make sure the background image (defined in the first RelativeLayout) does not get squeezed when the keyboard pops up, I have set android:windowSoftInputMode="stateVisible|adjustPan in the manifest file for my activity. All good with the background and layout now, nothing gets resized.
But the problem is that my ScrollView doesn't work now because I suppose the system thinks the window doesn't need resizing due to my above modification to the manifest - so the ScrollView is not activated. The opposite happens when I take android:windowSoftInputMode="stateVisible|adjustPan out, the scrolling works, but the background gets squeezed when the keyboard pops out.
Is there any way to code it so that my background doesn't get squeezed, and my ScrollView still works? Thanks!
Try to use in your activity the property windowSoftInputMode with the following values:
android:windowSoftInputMode="stateAlwaysHidden|adjustResize"
I don't know if it's necessary but you can try to add to your layout's ScrollView tag the fillViewPort to true.
So it should look like something I show you below:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<!-- Other Views -->
</ScrollView>
Let me know about your progress.
In your scrollview put a relative layout, child 0 is an imageview, and child 1 is your content. Use the imageview for your background image (src) rather than the background of the scrollview. The imageview will respect scaleTypes, whereas the background of a layout will not.