I want to draw a floating view outside a recycler view item.
It's like a tooltip in excel, each cell will be an item, and some items will have that tooltip:
I tried to use
clipChildren="false"
but it's still covered by other items.
This is item layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="50dp"
android:layout_height="50dp"
android:clipChildren="false"
android:orientation="vertical">
<View
android:id="#+id/box"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#f0f0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="30dp"
android:layout_height="20dp"
android:background="#ff00"
android:translationX="10dp"
android:translationY="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
And this is activity layout with recycler view:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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="wrap_content"
android:clipChildren="false"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is my result:
And expected result is something like this:
Is there any way to archive this?
It looks like each RecyclerView item is partially overwriting the previous item. It is not clear to me how you got the first image (not the Excel image but the next one), but you can try setting the following attributes in the XML for the RecyclerView. The result is to write the items in the reverse order from what is normally done.
<androidx.recyclerview.widget.RecyclerView
...
android:clipChildren="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toTopOf="parent"
app:reverseLayout="true" />
You could also set these, or any combination of these, in code. I would play around with these values to see where it gets you.
Related
Recyclerview crop first and last items shadows and i cant't fix it with any attributes.
I have a such xml screen:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
tools:context=".screens.view.CreateRequestFragment">
<ScrollView
android:id="#+id/createRequestScrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/sendRequestButton"
app:layout_constraintEnd_toEndOf="parent"
android:background="#color/transparent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- ... some elements inside scrollview -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/usersRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_m"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/selectUsersTitle" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<Button
android:id="#+id/sendRequestButton"
style="#style/OnDutyButtonStart"
android:text="Send Request"
android:layout_margin="#dimen/margin_m"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="Send Request" />
</androidx.constraintlayout.widget.ConstraintLayout>
In this case i get cropped last and first items shadows:
but i need it like this:
If i add margin or padding - i get the same with blank white space and always cropped shadows.
In my application i have nested recycler view. UI looks like this
XML layouts
Parent
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:background="#0F171E"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/Parent_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:scrollbars="vertical"
android:importantForAccessibility="no"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Child
<androidx.constraintlayout.widget.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="wrap_content"
android:background="#0F171E"
android:focusable="true"
android:focusableInTouchMode="true">
<TextView
android:id="#+id/category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:importantForAccessibility="no"
android:text="Category"
android:textColor="#C4DFEF"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/Child_RV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:descendantFocusability="afterDescendants"
android:importantForAccessibility="yes"
android:contentDescription="Category"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.01"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/category" />
</androidx.constraintlayout.widget.ConstraintLayout>
During vertical navigation, I'm need to announce "Category" followed by whatever child recycler view item supposed to say. Also, during vertical navigation, focus should not go to "Category" header, instead it should go directly to child recycler view item.
I have tried couple of things but it did not work. Currently i'm hearing text in format
"child item" item 2 of 15 in list "Category".
Any suggestions.
Noticed that you tube app on android Tv does this , it speaks the row title before speaking child item details.
I am making a layout for showing scanned bluetooth device. Here is the layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
tools:context=".fragments.ScannedListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_scan_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/progressBar_scan_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:itemCount="12"
tools:listitem="#layout/list_item_scanned_list" />
<ProgressBar
android:id="#+id/progressBar_scan_list"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/recycler_view_scan_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
But when there are too many list items, the progressbar will be squeezed out of the screen. Just like this:
demonstration1
I want to keep the progressbar stick to the bottom of the recyclerView when the screen has enough space to show all content and the progressbar can be completely shown above the bottom of the screen without scrolling even if there are too many items in the recyclerView.
I tried vertically chaining two views and packed chain with bias but no luck. Also, I found that adding app:layout_constraintHeight_max="" for the recyclerView can achieve similar effect. But it seems not a general solution for different screen sizes.
Create a vertical chain by constraining the bottom of the ProgressBar to the parent, then set the chain style to packed so that both views stick together and then set the vertical bias to 0 to align them to the top of the parent. To prevent the RecyclerView from pushing the ProgressBar out of the screen set the app:layout_constrainedHeight="true" attribute for the RecyclerView - it enforces constraints when the height is set to wrap_content.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
tools:context=".fragments.ScannedListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_scan_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_bias="0"
app:layout_constrainedHeight="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/progressBar_scan_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:itemCount="12"
tools:listitem="#layout/list_item_scanned_list" />
<ProgressBar
android:id="#+id/progressBar_scan_list"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/recycler_view_scan_list"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
tools:context=".fragments.ScannedListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_scan_list"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/progressBar_scan_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:itemCount="12"
tools:listitem="#layout/list_item_scanned_list" />
<ProgressBar
android:id="#+id/progressBar_scan_list"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This way it will be always visible. Make the progress bar bottom constraint to parent and recycler view height 0dp
I've tried a few different ways at getting this to work but the fragments I host inside of the ViewPager for a tab layout don't display correctly unless I position the components in the fragments oddly. Here's my fragment_tab xml and code is in Java:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="37dp" />
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF" />
</LinearLayout>
<Button
android:id="#+id/btnPost"
android:layout_width="147dp"
android:layout_height="47dp"
android:layout_marginBottom="16dp"
android:text="Post"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
And for instance in one of the fragments I host inside of it, the XML is this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swiperefresh"
android:layout_width="387dp"
android:layout_height="491dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="387dp"
android:layout_height="491dp"
android:layout_marginBottom="8dp">
</androidx.recyclerview.widget.RecyclerView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="96dp"
android:layout_height="103dp"
android:visibility="invisible"
android:layout_marginBottom="342dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="#+id/txtViewEmpty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
and this is what the design view looks like below. This fragment is hosted inside of the view pager with the tabs, inside of another screen that has an action bar but the tabs is hosted within that one.
I've been testing on Android Studio using an emulator and then when I test on hardware the UI is all messed up, but also positioning the screens like above, ideally I'd like to be able to use the whole view for the recycler view without having to place it like that as it may look right on my emulator but not hardware device if I use match_parent or the whole screen. Any ideas? I tried coordinator layout and relative layout as well and couldn't get it exact, it's possible it was done incorrectly though.
Thanks all!!
Edit: Picture on the hardware device where its messed up, but looks fine on emulator in the odd position that view was created with:
A bit of context: I am trying to implement a SearchView, when onQueryTextChange is called, it displays a ProgressBar, and when the query is done it hides the progress bar and displays another view depending on the outcome of the query. If the query returns nothing, it makes a textview visible saying "No Results" and if there is data, it populates the recyclerView.
My question is, what is the correct way of implementing this?
Do I stack them all on top of each other and make each one visible/invisible depending on the outcome of the query? Or do I use a viewflipper to display a fragment for no result and a fragment containing a recyclerview? Or lastly there is another way I do not know of?
This is what my search fragment looks like:
<?xml version="1.0" encoding="utf-8"?>
<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:fitsSystemWindows="true"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:background="#color/colorWhite">
<android.support.v7.widget.SearchView
android:id="#+id/fragsearch_searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:queryBackground="#android:color/transparent"
app:queryHint="Search"
app:iconifiedByDefault="false"
android:background="#color/backgroundColor"/>
<View
android:id="#+id/fragsearch_divider1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/dividerColor"
android:layout_below="#+id/fragsearch_searchView"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/fragsearch_recycler"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorWhite"
android:layout_below="#+id/fragsearch_divider1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragsearch_progress_layout"
android:background="#color/colorWhite"
android:visibility="invisible"
android:layout_below="#+id/fragsearch_divider1"
android:gravity="center">
<ProgressBar
android:id="#+id/fragsearch_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView
android:id="#+id/fragsearch_textview_noresults"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/fragsearch_divider1"
android:padding="12dp"
android:text="No Results Found"
android:visibility="invisible"/>
</RelativeLayout>
Right now I'm just stacking all of them on top of each other and changing the visibility on each one. Is there a better way of doing this?
I like to use a ViewFlipper for this. This way you can encapsulate the various view states in separate layouts and verify at design time that the correct layout is displayed. Much nicer than setting visibility on different Views.
<ViewFlipper>
<ViewGroup1>
</ViewGroup1>
<ViewGroup2>
</ViewGroup2>
</ViewFlipper>
To switch between the different children of a ViewFlipper call setDisplayedChild(index),
FrameLayout is used for this purpose.It is very useful for arranging views on top of each other.In your case replace RelativeLayout with FrameLayout.
I have done it using Constraintlayout considering searchview inside toolbar:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/padding_8dp">
<ProgressBar
android:id="#+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="#+id/recycler_company_details"/>
<TextView
android:id="#+id/txt_empty_data"
android:text="No data available!!"
android:layout_width="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textColor="#android:color/holo_red_dark"
android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout>
Consider using framelayout for this purpose, also we can easily set children layout gravity, it gets rendered perfectly. Relativelayout could also help, but we should avoid views termed as 'Legacy'.