I have a main Scrollview layout with a LinearLayout including several elements:
ExpandableListView #1 (1 children for yet)
TextView
ExpandableListView #2 (1 children for yet)
Several text views
The issue I encounter is when I click on any of the ExpandableListView, le display by itself is not expanding.
You can see the non-expanded view in this screen-capture (not clikced yet):
https://plus.google.com/photos/101037819512700772601/albums/5870915782494751761/5870915784486932322
You can see the should be expanded view (once I clicked on the ExpandableListViews) in this screen captures:
https://plus.google.com/photos/101037819512700772601/albums/5870915782494751761/5870915780856077570
There you have my layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ExpandableListView
android:id="#+id/expandableView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ExpandableListView>
<TextView
android:id="#+id/providerNameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="ABCDEF1"
android:textSize="25sp"
android:textStyle="bold" />
<ExpandableListView
android:id="#+id/expandableView2"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ExpandableListView>
<TextView
android:id="#+id/providerNameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="ABCDEF2"
android:textSize="25sp"
android:textStyle="bold" />
. . .
</LinearLayout>
</ScrollView>
Do you have a solution for my issue?
First things first. You can't nest multiple vertical scrolling views. Otherwise you're going to have a field day trying to override the appropriate touch events to get everything right.
If you need other views to scroll as the list scrolls, you can simply add header/footer views. If you need that to be 'sticky' a cursory Google search came up with Sticky headers library.
Related
I have a RecyclerView in an xml and a LinearLayout at the bottom of that Activity. This activity works as a chat window where a question appears as the chat message and user gets some random multiple choice options in the view, but when the RecyclerView gets populated with a page full of data, I want to make that RecyclerView always above the layout where options are created, but what I have done so far does not work as expected, the RecyclerView data always gets hidden under the layout and each time I need to scroll down to see what's written there. I have used the method
adapter.notifyItemInserted(array.size());
recyclerView.scrollToPosition(array.size());
This adds item in the RecyclerViewand also scrolls down but it gets hidden under the layout, but I have set it always above the layout in the xml, I think the problem is I am creating some views dynamically in that layout which's size is wrap content, so the RecyclerView is not being updated time to time with the height of the layout in the bottom. Here is the xml code of that Activity
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/rlMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChatBotActivity">
<include
android:id="#+id/header"
layout="#layout/header"></include>
<android.support.v7.widget.RecyclerView
android:id="#+id/rcv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/ll"
android:layout_below="#+id/header" />
<LinearLayout
android:id="#+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical"></LinearLayout>
<LinearLayout
android:id="#+id/ll2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:visibility="invisible"
android:weightSum="7">
<EditText
android:id="#+id/etMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="5"
android:hint="Type a message"
android:paddingLeft="#dimen/ten_dp"
android:textColorHint="#color/fade" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_gravity="center"
android:layout_marginRight="#dimen/five_dp"
android:layout_weight="2"
android:background="#android:color/transparent"
android:onClick="sendClick"
android:src="#drawable/ic_send_black_24dp"
android:text="send" />
</LinearLayout>
</RelativeLayout>
The RecyclerView is always above of the LinearLayout which id is ll but I am populating that layout from the java and it's height changes time to time, but RecyclerView height doesn't changed accordingly, please help!
Finally I myself solved the question, It was a funny mistake I was doing, the layout was all right, but my recylerview was just not scrolling, I had to change this:
Previous:
adapter.notifyItemInserted(array.size());
recyclerView.scrollToPosition(array.size());
Later:
adapter.notifyItemInserted(array.size()-1);
recyclerView.scrollToPosition(array.size()-1);
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 use a RecyclerView that shows a list of entries. Each entry hosts another RecyclerView that is a list of images.
I now want to make this nested RecyclerView clickable, not the items of it, but the whole view.
How can I achieve that?
Problem:
setting the onClickListener for the main view of the nested RecyclerView does work, but only if I click outside the RecyclerView itself
clicking on the nested RecyclerView does not hand on the clicks to the parent view (I even tried to set clickable, focusable, focusableIntouch to false, still, the touch is not delegated but consumed by the nested RecyclerView...
Here's the view for the wrapping adapter:
<?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="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="0dp"
android:layout_margin="5dp"
android:foreground="?android:attr/selectableItemBackground" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/rlTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="Datum"
android:textStyle="bold"
android:id="#+id/tvDate" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Info"
android:id="#+id/tvInfo" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/rvData"
android:clickable="false"
android:focusableInTouchMode="false"
android:focusable="false"
android:layout_below="#+id/rlTop"
android:layout_width="match_parent"
android:layout_height="68dp"
android:scrollbars="horizontal" />
</RelativeLayout>
</android.support.v7.widget.CardView>
I looked into RecyclerView source and this helped:
recyclerView.setLayoutFrozen(true)
This is an old question, but i have the same task and didn't find good solution.
I just placed the transparent view over recyclerview and set click listener to this view.
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:cardBackgroundColor="#color/white"
app:cardCornerRadius="0dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/dataLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="#dimen/history_margin_v"
android:paddingEnd="#dimen/history_margin_h"
android:paddingLeft="#dimen/history_margin_h"
android:paddingRight="#dimen/history_margin_h"
android:paddingStart="#dimen/history_margin_h"
android:paddingTop="#dimen/history_margin_v">
<TextView
android:id="#+id/day"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/widget_margin_v"
android:textColor="#color/font_blue"
android:textSize="#dimen/font_size_large"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/images"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<View
android:id="#+id/clickView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:layout_alignLeft="#+id/dataLayout"
android:layout_alignRight="#+id/dataLayout"
android:layout_alignStart="#+id/dataLayout"
android:layout_alignEnd="#+id/dataLayout"
android:layout_alignTop="#+id/dataLayout"
android:layout_alignBottom="#+id/dataLayout"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
In order to do the entire row clickable and not every image u need to implement a custom onItemClickListener (name comes from listview , sorry).
Take a look at this link
this worked out perfectly for me.
Edit:
The nested recycler steals your clicks. in order to fix that u will need to create a cusom touch listener and pass it to the nested recycler. Just like the one that u put to the outer ercycler but pass the event to the outer.
Edit 2:
Add a selector with two states just like a button to the entire row, then at the onclick on the inner recycler setSelected(true) the row and postDelay with 50ms for setSelected(false) this will give the "click" effect.
I have built the following XML layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/white"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/ll1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.2"
android:orientation="horizontal" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="0.3"
android:gravity="center"
android:src="#drawable/logo" />
<TextView
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="0.7"
android:gravity="center"
android:text="#string/my_profile"
android:textColor="#A669DA"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:id="#+id/ll2"
android:background="#A669DA"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.15"
android:orientation="horizontal" >
<TextView
android:id="#+id/TextView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:text="#string/payroll_header"
android:textColor="#FFFFFF"
android:textSize="20sp" />
</LinearLayout>
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.65" >
<LinearLayout
android:id="#+id/ll3"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:weightSum="2" >
<ExpandableListView
android:id="#+id/expandableListView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadeScrollbars="true" >
</ExpandableListView>
<HorizontalScrollView
android:id="#+id/horizontalScrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ExpandableListView
android:id="#+id/expandableListView2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ExpandableListView>
</HorizontalScrollView>
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
</ScrollView>
</LinearLayout>
The root element of this XML layout is a linear layout. It contains 2 linear layouts and one scroll. Since scroll view can only have one child, it contains a linear layout which in turn contains an expandable listView, horizontal scrollview (which contains an expandable listview) and a listview. As you can see, this is a very complicated layout, and I think it should be possible to simplify. Basically, I want the top 2 linear layouts to always take 35% of the screen, and the scrollview to take the rest. That's why I gave a weight of 0.2 to the first linear layout, 0.15 to the second linear layout, and 0.65 to scrollView.
Within the scrollView, I would like each of the 3 elements to take as much space as they would need, so that user scrolls down if he/she doesn't see everything. I know that expandableListView and ListView are already scrollable, so I will disable scrolling in them, so that parent's scroll bar is used.
However, I am facing several problems with this design:
1) In the first screenshot, you can see an expandableListView, horizontalScrollBar (with an expandableListView), and a listView.
Each of them has height set to "wrap content", so I would expect each of them to take as much space as they need. However, you can see in the second screenshot that when I open the second expandable listView (the one within a horizontal scrollBar), listview doesn't move down to make space for the expanded list view. How can I achieve it, so that each of them moves down when the expandable list above expands? Is the only way to do it is to combine them all in one expandableListView?
2) My second expandableListView is in the horizontalScrollBar, however, I can't scroll it horizontally. Can I even put horizontal scrollBar inside a vertical scrollBar?
First off, a little simplification: Your second LinearLayout (the 0.15 one) can be left out since it only has a single child. Just be sure to adjust the layout parameters of that single child (the TextView).
For your problem #1, try calling invalidate() or requestLayout() on your root view.
Problem #2 is actually solved: Link
My general impression is that this nesting of ScrollViews and ListViews is pretty complex. Have you considered alternatives such as TabLayout or DrawerLayout?
Cheers
I have applied scroll view to the entire layout and that layout has one listview. when running the application in the emulator both scroll views are working one scroll view for entire layout and another scroll view for listview (both works fine). but when i installed my app in the phone only outer scroll view is working scroll view for listview is not working. Can any one please tell me the reason and solution for my problem.
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ScrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/bg4"
android:orientation="vertical"
android:scrollbarAlwaysDrawVerticalTrack="true" >
<ListView
android:id="#+id/listViewTickets"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp" >
</ListView>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginBottom="70dp"
android:orientation="horizontal"
>
<Button
android:id="#+id/btnNew"
android:layout_width="80dp"
android:layout_height="30dp"
android:background="#drawable/btnnew" />
<Button
android:id="#+id/btnUpdate"
android:layout_width="80dp"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#drawable/edit" />
</LinearLayout>
The content of list view is displayed dynamically.
I have found the youtube video Google I/O 2010 - The world of ListView an essential watch. In it it's mentioned to never use multiple scrolling widgets unless they scroll on a different axis.
A list view is already scrollable so you can't add it to a scroll view.
Here's a similar question and an answer from the Google engineer in charge of the ListView:
How can I put a ListView into a ScrollView without it collapsing?