Apply Material ripple to ViewPager item - android

I would like to add a Material design ripple effect to the Views shown by a ViewPager. My team has been able to do that in other parts of our app by setting ?attr/selectableItemBackground as the background of a View. However, when I assign that as the background of the View returned by my ViewPager's adapter, the effect doesn't seem to work. Has anyone gotten that to work?
From experience, it seems that ViewPagers consume events that prevent certain interactions with their children. For example, ViewPager items don't get onClick() events and you have to work around that in other ways. I wonder if there isn't a similar issue here, where the ViewPager is consuming events that are needed for the ripple to work.

You simply have to put your xml view into a FrameLayout like this:
old layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/viewpager_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#string/app_name"
android:scaleType="centerCrop"/>
<ProgressBar
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:indeterminateDrawable="#drawable/progress_medium_holo"
android:visibility="gone" />
</RelativeLayout>
new layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackground"
android:selectable="true">
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/viewpager_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#string/app_name"
android:scaleType="centerCrop"/>
<ProgressBar
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:indeterminateDrawable="#drawable/progress_medium_holo"
android:visibility="gone" />
</RelativeLayout>
</FrameLayout>

The view pager is intended for swiping, so if you want to click it, you need to specify that, either programmatically, or in the XML file. For instance, add these attributes to the layout of the item of your view pager, not the view pager itself.
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"

Related

RecyclerView get hidden under dynamic view in android

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);

Android: ListView pushes out everything else below it

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" />

Android Horizontal RecyclerView wrap_content

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>

RecyclerView with nested RecyclerView - make nested RecyclerView clickable as a whole view

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.

How to put one View over other in RelativLlayout programmatically in Android?

I am programmatically creating view in Android. Parent layout is RelativLlayout and I'm adding two views in it. First is ListView and second is custom view. I want my second custom view to come on top of the list, but somehow it is getting hidden behind the ListView. How do I make sure that my custom view is on top.
Views get placed in the order you add them to their parent views. The view added last will be on top. You might also want to try
View.bringToFront() http://developer.android.com/reference/android/view/View.html#bringToFront()
Try to use: View.bringToFront();
Solution 1 - View#bringToFront()
View.bringToFront() should work if used properly. Maybe you forgot this (source: http://developer.android.com/reference/android/view/View.html#bringToFront()):
Prior to KITKAT this method should be followed by calls to requestLayout() and invalidate()
Solution 2 - reattach view
If View.bringToFront() will not work try to remove and add the view again. The advantage is that it has the same code on pre-KITKAT versions too.
I am doing it this way in my code:
ViewGroup parentView = (ViewGroup) (listView.getParent());
parentView.removeView(addFab);
parentView.addView(addFab);
Use FrameLayout, frame layout shows last added view on top..
Try this :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<YourCustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
Please try adding android:elevation attribute to your view in the XML. It will always place your custom view over the ListView.
Again: Views get placed to the layout in the order you add it. Question is: is it realy hidden or does it not render?. Check LogCat and Console for errors. If you only add this single Custom View to your layout, does it get rendered without any problems? If so, ensure you realy add your custom to the same parent view (group), as you add your ListView. If you don't get any further, provide de respective code sample.
Give an elevation to the view which you want to bring up.
android:elevation="2dp"
This works for me :
<RelativeLayout
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="220dp"
android:gravity="bottom"
android:orientation="vertical"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="#+id/details_wrapper"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingBottom="16dip"
android:scaleType="centerCrop"
android:src="#drawable/temp_nav_image">
</ImageView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/nav_header_vertical_spacing"
android:text="Kapil Rajput"
android:textStyle="bold"
android:textColor="#android:color/black"
android:textAppearance="#style/TextAppearance.AppCompat.Body1"/>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
android:textStyle="bold"
android:text="kapil#gnxtsystems.com"/>
</LinearLayout>
</RelativeLayout>
I used relative layout and the order of the views somehow determines which one is on top.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:splitTrack="false"
android:layout_alignParentTop="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
In this layout, the textview will be on top of the seekbar
Make parent view as relative layout and add your both view in xml.It wont work for Linear Layout.
And then add FirstView.bringToFront() programtically.
<RelativeLayout 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="match_parent"
android:background="#mipmap/bg"
android:orientation="vertical"
android:padding="15dp">
<ImageView
android:id="#+id/imgIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_marginBottom="-30dp"
android:layout_marginTop="30dp"
android:src="#mipmap/login_logo" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/imgIcon"
android:layout_gravity="bottom"
android:background="#B3FFFFFF"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<View 1/>
<View 2/>
</LinearLayout>
Java file
imgIcon.brigtToFront();
what you should do is using android:layout_below or android:layout_above programmatically. so you should do this:
RelativeLayout.LayoutParams params= new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, R.id.below_id);
viewToLayout.setLayoutParams(params);
and i suggest you take a look at this answer
hope this helps

Categories

Resources