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);
Related
I have a dialog fragment that contains linear layout that involves a titleText above a RecyclerView, and at the very bottom, there's a button below the recyclerView.
Since a recyclerView expands or collapses based on the number of items the adapter sets, the button sometimes gets truncated and no longer appears to be on screen, since the recyclerView just covers the entire screen.
My question is, is there a way to set the maximum height of the recyclerView without ever hiding the button underneath. I also don't want to just give the view a random height just in case the recyclerView contains no items, and it would just be a blank section.
Please let me know if you've ever run into this issue, and how you resolved this. Thanks!
UPDATED
You can achieve this easily using layout weights. Here's an example:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Title"
android:textSize="21sp"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="30dp">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Submit"/>
</FrameLayout>
The Title and RecyclerView will wrap content according to contents and button will always take up bottom place.
I suggest using RelativeLayout as it handles the positioning of views for cases like yours, so that you can actually focus on main design.
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Some title" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/title"
android:layout_above="#+id/button"/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:gravity="center"/>
</RelativeLayout>
Above XML code is the skeleton code for what you need. you can add margins and dimensions to control the spacing. But in any case (until you provide negative margins) your views will never overlap each other.
Main trick of using RelativeLayout is the ability to use XML tags like
android:layout_below or android:layout_above or android:layout_start
or android:layout_end which perfectly aligns your view the way you
want.
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" />
hello I'm trying to use Recyclerview,
below code results only a blank screen, can you please tell me where I'm going wrong
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="top|center_vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/ImageSelectorRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="horizontal" />
<ImageView
android:id="#+id/ImageViewSelectPhoto"
android:layout_width="80dp"
android:layout_height="76dp"
android:src="#drawable/ic_add_a_photo_black_361px"
android:background="#drawable/back"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp" />
</LinearLayout>
Since you have provided
android:layout_width="match_parent"
android:layout_height="match_parent"
for your RecyclerView, its taking the full width and height of your device or parent view. And the ImageView is outside the device screen.
Now you have just declared the RecyclerView in your XML. You need a RecyclerView Row Layout which should define the layout for the RecyclerView items.
To show something in the RecyclerView you can set static data in the Row Layout layout iteself or need to create a RecyclerView adapter and model for dynamic/static data.
You need to make a list item layout for your Horizontal-scrollview and a seperate adapter also for it.
Try adding android:viewfillport="true"
I too asked a similar type of question ,please have a look to it yu will surely get a simple way to implement this .
Horizontal Listview Not Working from github
I think it should be similar to this
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="top|center_vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/ImageSelectorRecycler"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<ImageView
android:id="#+id/ImageViewSelectPhoto"
android:layout_width="80dp"
android:layout_height="76dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:src="#android:drawable/ic_dialog_alert"
android:background="#android:color/holo_green_dark" />
</LinearLayout>
I've got a tabbed viewpager, where swiping to the next page is disabled. The reason is, inside the fragment, I have a horizontal RecyclerView that should get the touch event.
Fragment XML :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:text="Federal Representatives"
android:fontFamily="sans-serif-medium"
android:textSize="20sp"
android:paddingTop="15dp"
android:paddingLeft="15dp"
android:textColor="#000000"
xmlns:android="http://schemas.android.com/apk/res/android" />
<android.support.v7.widget.RecyclerView
android:id="#+id/federalPager"
android:scrollbars="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
The problem is this RecyclerView won't show up... unless I delete the TextView.
At that point it looks like this :
But If I keep them both, only the TextView shows up, but not the RecyclerView.
What am I missing?
Your TextView has this attribute:
android:layout_height="match_parent"
Which tells it to be as tall as the parent is... so that pushes the RecyclerView off the bottom... try changing it to wrap_content instead.
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.