Horizontal recyclerview with snaphelper, how to center first and last element? - android

I've made a little sample of something I'm trying to do in a real app, and I can't figure out how to solve my issue. The current solution looks like this.
So I have a vertical list of movie categories, where within each genre, I have a horizontal list of movies. The first row, is showing The Exorcist as the first element, but it's not centered. The second row in Action, shows how it looks when I've scrolled a bit to the right. Last row is showing how the end of the row looks like.
I'd like to have the first and last of the rows, to be centered as well when they're "selected".
My main activity looks like this:
<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"
android:background="#android:color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/moviesListRecyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="#layout/movie_category_item_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
The movie_category_item_view looks like this:
<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/movieListLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/movieCategoryTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="40dp"
android:textColor="#android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Horror" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/moviesRecyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:orientation="horizontal"
android:visibility="visible"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/movieCategoryTitle"
tools:listitem="#layout/movie_horizontal_item_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
And the movie_horizontal_item_view like this:
<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="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/movieTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Horror" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/image"
android:layout_width="237dp"
android:layout_height="209dp"
android:background="#android:color/black"
android:src="#drawable/ic_launcher_foreground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/movieTitle"
tools:src="#drawable/ic_launcher_foreground" />
</androidx.constraintlayout.widget.ConstraintLayout>
Hopefully what I'm asking for makes sense!
In case you want to try it out for yourself and see what I mean, it can be found on github here

use carouselview.CarouselView
<alirezat775.lib.carouselview.CarouselView
android:id="#+id/carousel_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"/>
the adapter
class MyAdapter(var ctx: Context) : CarouselAdapter() {
private var vh: CarouselViewHolder? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CarouselViewHolder {
val inflater = LayoutInflater.from(parent.context)
val v = inflater.inflate(R.layout.home_list_item, parent, false)
vh = MyViewHolder(v)
return vh as MyViewHolder
}
override fun onBindViewHolder(holder: CarouselViewHolder, position: Int) {
}
inner class MyViewHolder(itemView: View) : CarouselViewHolder(itemView) {
}
}
the activity
class MainActivity : AppCompatActivity() {
var carousel: Carousel? = null
val adapter = MyAdapter(this)
override fun onCreate(savedInstanceState: Bundle?) {
carousel = Carousel(this, carousel_view, adapter)
carousel!!.setOrientation(CarouselView.HORIZONTAL, false)
// carousel!!.autoScroll(true, 5000, true)
// carousel!!.scaleView(true)
}
}

Related

Dynamically add item into recyclerview when button pressed

I am trying to build a layout in which there is a recyclerview where each item has three edittexts horizontally aligned. I want to add the next item when a button is pressed.
This the design I am trying to build
This is the Adapter class for the recycler view
class AddProjectAdapter(private val itemsList : ArrayList<ItemDetails>) : RecyclerView.Adapter<AddProjectAdapter.AddProjectViewHolder>() {
inner class AddProjectViewHolder(private val binding : AddProjectItemViewBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(item : ItemDetails){
binding.item = item
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AddProjectViewHolder{
return AddProjectViewHolder(AddProjectItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: AddProjectViewHolder, position: Int) {
holder.bind(itemsList[position])
}
override fun getItemCount(): Int = itemsList.size
}
Layout file for the item add_project_item_view.xml
`
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="item"
type="com.example.hero.models.ItemDetails" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.card.MaterialCardView
android:id="#+id/item_name_cardview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:flow_horizontalBias="3"
app:cardBackgroundColor="#color/light_background"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="#id/g_v_1"
android:layout_marginRight="5dp">
<EditText
android:id="#+id/item_name_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Item Name"
android:text="#={item.itemName}"
android:textColor="#color/t_dark"
android:fontFamily="#font/metropolislight"
android:textSize="14dp"
android:textColorHint="#color/t_dark"
android:background="#null"
android:padding="10dp" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="#+id/rate_unit_cardview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:flow_horizontalBias="2"
android:layout_marginRight="5dp"
app:cardBackgroundColor="#color/light_background"
app:layout_constraintStart_toEndOf="#id/g_v_1"
app:layout_constraintEnd_toEndOf="#id/g_v_2">
<EditText
android:id="#+id/rate_unit_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Rate/Unit"
android:text="#={item.rate}"
android:textColorHint="#color/t_dark"
android:textColor="#color/t_dark"
android:fontFamily="#font/metropolislight"
android:textSize="14dp"
android:padding="10dp"
android:background="#null" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="#+id/unit_cardview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:flow_horizontalBias="2"
app:cardBackgroundColor="#color/light_background"
app:layout_constraintStart_toEndOf="#id/g_v_2"
app:layout_constraintEnd_toEndOf="parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/unit_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="#null"
android:fontFamily="#font/metropolislight"
android:hint="Unit"
android:padding="10dp"
android:text="#={item.unit}"
android:textColor="#color/t_dark"
android:textColorHint="#color/t_dark"
android:textSize="14dp" />
<ImageView
android:id="#+id/drop_down_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="#drawable/dropdown"
android:layout_centerVertical="true" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_v_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.4" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/g_v_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
`
//code of the activity in which the recycler view is present
private val itemsList : ArrayList<ItemDetails> = ArrayList()
private lateinit var addProjectAdapter: AddProjectAdapter
private lateinit var binding: ActivityAddProjectBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAddProjectBinding.inflate(layoutInflater)
setContentView(binding.root)
setAdapter()
setListner()
}
private fun setAdapter(){
addProjectAdapter = AddProjectAdapter(itemsList)
binding.itemDetailsRecyclerview.apply {
layoutManager = LinearLayoutManager(this#AddProject)
adapter = addProjectAdapter
}
}
override fun onClick(v : View?) {
when(v?.id){
binding.addItemButton.id -> {
itemsList.add(ItemDetails())
addProjectAdapter.notifyItemInserted(itemsList.size-1)
}
}
}
private fun setListner(){
binding.addItemButton.setOnClickListener(this)
}
data class ItemDetails(
var itemName : String = "",
var rate : String = "",
var unit : String = "")
And my recyclerview id is item_details_recyclerview.
Output for the above code
When I click the add button the item added is not visible but the add button moves down.
Can someone help me out with this issue? And also if you could provide some better approach it would be great.
Thanks in advance.
Change height of ConstraintLayout from add_project_item_view.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
to this
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

How to show particular number of item at a time in smarteist image slider github

I created the image slider using smarteist image slider github library and it's working fine. I wanted to show 3 items at a time but Item occupies whole space and visible only 1 item. I also tried recyclerview to achieve this thing but can't get same feel as image slider. So guide me how to achieve it.
Expected
To show 3 items at a time before slide.
what I had done
val partner_recyclerView: SliderView = findViewById(R.id.partnership_slider)
var partnerAdapter: PartnerAdapter = PartnerAdapter(partnerList)
partner_recyclerView.autoCycleDirection = SliderView.LAYOUT_DIRECTION_LTR
partner_recyclerView.setSliderAdapter(partnerAdapter)
partner_recyclerView.scrollTimeInSec = 3
partner_recyclerView.isAutoCycle = true
partner_recyclerView.startAutoCycle()
Item_layout
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="150dp"
android:layout_height="80dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="5dp"
android:layout_marginTop="8dp"
app:cardElevation="8dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="8dp"
app:cardCornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/myPartnerLogo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:contentDescription="#string/app_name"
android:scaleType="fitXY"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</androidx.cardview.widget.CardView></androidx.constraintlayout.widget.ConstraintLayout>
Main_Layout
<com.smarteist.autoimageslider.SliderView
android:id="#+id/partnership_slider"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_centerInParent="true"
app:sliderAnimationDuration="600"
app:sliderAutoCycleDirection="back_and_forth"
app:sliderScrollTimeInSec="1"
android:padding="10dp"
app:layout_constraintBottom_toTopOf="#+id/constraintLayout3"
app:layout_constraintEnd_toEndOf="#+id/constraintLayout3"
app:layout_constraintStart_toStartOf="#+id/constraintLayout3"
app:layout_constraintTop_toTopOf="#+id/constraintLayout3"/>
Adapter_class
class PartnerAdapter (val mList: ArrayList<PartnershipData>) :
SliderViewAdapter<PartnerAdapter.SliderViewHolder>() {
override fun getCount(): Int {
return mList.size
}
override fun onCreateViewHolder(parent: ViewGroup?): PartnerAdapter.SliderViewHolder {
val inflate: View = LayoutInflater.from(parent!!.context).inflate(R.layout.partner_item, null)
return PartnerAdapter.SliderViewHolder(inflate)
}
override fun onBindViewHolder(viewHolder: PartnerAdapter.SliderViewHolder?, position: Int) {
if (viewHolder != null) {
// if view holder is not null we are simply
// loading the image inside our image view using glide library
Glide.with(viewHolder.itemView).load(mList.get(position).pwa_iconpng).fitCenter()
.into(viewHolder.myPartnerLogo)
}
}
class SliderViewHolder (itemView: View?) : SliderViewAdapter.ViewHolder(itemView) {
val myPartnerLogo: ImageView = itemView!!.findViewById(R.id.myPartnerLogo)
}}
For better understanding
Expected
Problem

java.lang.ClassCastException: java.lang.Integer cannot be cast to android.widget.ImageButton

So I'm fairly new to Kotlin.
I am trying to create an onClickListener on an image button to open the share interface, so that the particular video from the recyclerView can be shared via SMS, etc.
I followed various tutorials on how to do this as I am trying to execute this within a fragment, and the app just keeps crashing when I try to open the fragment in question.
I get the following error
java.lang.ClassCastException: java.lang.Integer cannot be cast to android.widget.ImageButton
Here is what my fragment code looks like:
SearchFragment.kt
class SearchFragment : Fragment(), View.OnClickListener
{
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<ClipAdapter.ViewHolder>? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View
{
val rootView = inflater.inflate(R.layout.fragment_search, container, false)
loadData()
return rootView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
val shareBtn = view.findViewById<ImageButton>(R.id.button_to_share)
shareBtn.setOnClickListener(this)
}
private fun loadData()
{
val service = TwitchServiceBuilder.buildService(TwitchService::class.java)
val requestCall = service.getClips("anerdfails")
requestCall.enqueue(object : Callback<List<Clip>>
{
override fun onResponse(
call: Call<List<Clip>>,
response: Response<List<Clip>>
)
{
if (response.isSuccessful)
{
//process data
recyclerView.layoutManager = GridLayoutManager(activity, 2)
recyclerView.adapter = ClipAdapter(response.body()!!)
} else
{
//output alert
AlertDialog.Builder(activity!!)
.setTitle("API error")
.setMessage("Response, but something went wrong ${response.message()}")
.setPositiveButton(android.R.string.ok) { _, _ -> }
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
}
override fun onFailure(call: Call<List<Clip>>, t: Throwable)
{
//process failure
AlertDialog.Builder(activity!!)
.setTitle("API error")
.setMessage("No response, and something went wrong $t")
.setPositiveButton(android.R.string.ok) { _, _ -> }
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
})
}
override fun onClick(v: View?)
{
Toast.makeText(activity, "Its toast!", Toast.LENGTH_SHORT).show()
}
}
And here are my 2 layouts for the RecyclerView:
fragment_search.xml
<?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"
android:paddingStart="15dp"
android:paddingTop="?attr/actionBarSize"
android:paddingEnd="15dp"
tools:context=".ui.search.SearchFragment">
<androidx.appcompat.widget.SearchView
android:background="#drawable/search_bar"
android:id="#+id/clipSearch"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="5dp"
android:focusable="true"
android:focusableInTouchMode="true"
app:layout_constraintBottom_toTopOf="#+id/recyclerView"
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="0dp"
android:layout_height="0dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="75dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/clipSearch" />
</androidx.constraintlayout.widget.ConstraintLayout>
clip_layout.xml
<?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"
tools:context=".ui.search.SearchFragment">
<VideoView
android:id="#+id/videoClip"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintDimensionRatio="w,2:3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txtTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/videoClip"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/txtChannel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtTitle"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/txtGame"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtChannel"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/txtViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtGame"
tools:ignore="HardcodedText" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:orientation="horizontal"
android:weightSum="2"
android:layout_marginTop="15dp"
app:layout_constraintTop_toBottomOf="#+id/txtViews">
<ImageButton
android:id="#+id/favouriteButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#null"
android:scaleType="fitCenter"
android:src="#drawable/ic_baseline_favorite_border_24" />
<ImageButton
android:id="#+id/button_to_share"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#null"
android:scaleType="fitCenter"
android:src="#drawable/ic_baseline_share_24" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Seems like a simple mistake on my part, but I'm pulling my hair out trying to work out what I've done wrong to cause the error on loading.
Any help would be appreciated.
I see you're trying to find the button "ShareBtn" inside the fragment which is totally wrong.
the "ShareBtn" doesn't belong to the fragment, it belongs to the viewHolder which you have created inside "ClipAdapter"
What you need to do is creating an interface inside "ClipAdapter" and create an object from it inside the Adapter
then call the method which is should the clickListener delegates the click to it
lastly, you should implement it inside the fragment and put whatever logic you want
This link will help you implement it
You are casting ID of view which is an Integer to ImageButton which is a View in this line
val shareBtn = R.id.button_to_share as ImageButton
You should use this instead
val shareBtn = findViewById<ImageButton>(R.id.button_to_share)
UPDATE
Also you should find views after fragment view got created. It means you should call `findViewById` inside `onViewCreated` and not inside `onCreateView`. If you try to find views before view of fragment gets created then you get `NullPointerException` since there is no view yet.

Android|Kotlin recycle view and custom adapter is creating only one row

I have an issue with my custom adapter (I think) I'm getting my data using retrofit, that comes just fine, once I get the data I call another function to populate my recycle view, as follows.
I really appreciate if some one could help me on this...
private fun createMyOrdersTable(myOrders: List<OrderAssigned>){
val ordersCount = myOrders.size
val rv = myorder_rv
rv.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
val ordersList = ArrayList<OrderAssigned>()
if (ordersCount > 0){
myOrders.forEach {
ordersList.add(it)
}
// order.add(OrderAssigned("123","123213","123123","1231231","123123","123123","123123","123123"))
// order.add(OrderAssigned("123","123213","123123","1231231","123123","123123","123123","123123"))
println(ordersList)
val adapter = CustomAdapterMyOrders(ordersList)
rv.adapter = adapter
}else{
Toast.makeText(context, "You don't have any assigned order", Toast.LENGTH_LONG).show()
}
}
And this is my adapter:
package com.davesm.swiftdemexico
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.davesm.swiftdemexico.Model.OrderAssigned
import kotlinx.android.synthetic.main.myorders_layout.view.*
class CustomAdapterMyOrders(private val orders: ArrayList<OrderAssigned>): RecyclerView.Adapter<CustomAdapterMyOrders.ViewHolder>() {
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val orderID = itemView.orderID!!
val clientName = itemView.clientName!!
val no_rem = itemView.orderRem!!
val orderDate = itemView.orderDate!!
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
//
val v = LayoutInflater.from(parent?.context).inflate(R.layout.myorders_layout, parent, false)
return ViewHolder(v);
}
override fun getItemCount(): Int {
//
return orders.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val model = orders[position]
holder.orderID.text = "ID: "+model.id
holder.clientName.text = model.nom_cte
holder.no_rem.text = "RemisiĆ³n"+model.no_rem
holder.orderDate.text = model.falta_rem
}
}
When I execute my app it shows only one "row" which is a card view even when I add more than one item in the foreach in the "createMyOrdersTable" I had tried to add it manually as in the commented code but still not working, I send the data as an ArrayList.
Here is the xml files for the views:
myorder_layout.xml
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/myorder_rv"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is my items layout.
myorders_layout.xml
<?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">
<androidx.cardview.widget.CardView
android:id="#+id/cardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="10dp"
app:cardCornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:padding="10dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/rounder_button_primary_color"
tools:ignore="MissingConstraints">
<TextView
android:id="#+id/orderID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Order ID"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large" />
<TextView
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:text="Client Name"
android:id="#+id/clientName"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/orderRem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RemisiĆ³n" />
<TextView
android:id="#+id/orderDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Date" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
It is not creating 1 row, it is creating many, but they are all as tall as the screen.
Change your item layout to use wrap_content for the height
<?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">

Recyclerview missing item when element's width and height is enlarged

I've been scratching my head about this problem. I have a recyclerview inside a recyclerview that shows a grid layout where you can scroll both vertically and horizontally.
I decided to enlarge the width and height of each item. Previously, width and height were: 80 x 100
<?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"
android:id="#+id/book_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/inner_dropshadow"
android:layout_width="80dp"
android:layout_height="100dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/bookdropshadow" />
</android.support.constraint.ConstraintLayout>
And then I enlarged it to 150x 180. And then Level 4-6 row completely disappeared no matter how much I scroll up. I only expected the recyclerview to display larger images. Why does this happen?
[EDIT] I ran a debug and it seems only 3 positions are bound in the outer adapter when the app is run on a phone but there are 4 positions when run on a tablet.
<?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"
android:id="#+id/book_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/inner_dropshadow"
android:layout_width="150dp"
android:layout_height="180dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/bookdropshadow" />
</android.support.constraint.ConstraintLayout>
Please note that this also happens when I run the app on a device. In a tablet, it shows all the Levels, while on a phone, it only shows Levels 1-3.
Outer recyclerview 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"
android:id="#+id/mainlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/color_white">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/swiperefresh"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/toolbar">
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="always">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/browsebooksheader_layout"
android:id="#+id/bb_header"
app:layout_constraintBottom_toTopOf="#+id/guidelinetop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"/>
<android.support.constraint.Guideline
android:id="#+id/guidelinetop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.30"/>
<Button
android:id="#+id/btn_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="#drawable/search_btn_border"
android:padding="8dp"
android:text="Search"
android:textSize="#dimen/browse_search_textsize"
android:textColor="#android:color/darker_gray"
app:layout_constraintBottom_toTopOf="#+id/recyclerview_main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/bb_header" />
<ProgressBar
android:id="#+id/main_progressbar"
style="?android:attr/progressBarStyleSmall"
android:layout_marginTop="16dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:indeterminateTint="#color/color_grey"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btn_search"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
android:background="#color/color_white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btn_search"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/toolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/swiperefresh"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<include layout="#layout/toolbar_layout_wo_learn"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
Inner recyclerview 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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/book_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Category Title"
android:textColor="#color/defaultdark_color"
android:textSize="#dimen/browse_category_textsize"
android:fontFamily="#font/vagroundedstd_bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="#dimen/browse_seeall_imagesize"
android:layout_height="#dimen/browse_seeall_imagesize"
android:layout_marginBottom="2dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="8dp"
android:id="#+id/see_all_btn"
android:src="#drawable/seeall"
app:layout_constraintBottom_toTopOf="#+id/inner_recyclerview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="#+id/inner_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
android:background="#color/color_white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/book_category"/>
<TextView
android:id="#+id/h_line"
android:layout_width="match_parent"
android:layout_height="0.8dp"
android:background="#color/color_grey"
android:gravity="center"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:alpha="0.5"
app:layout_constraintTop_toBottomOf="#id/inner_recyclerview"/>
</android.support.constraint.ConstraintLayout>
Outer Adapter
class BrowseBooksAdapter : RecyclerView.Adapter<BrowseBooksAdapter.SimpleViewHolder>() {
private var sortedList : SortedMap<String, List<ResourcesList>> = emptyMap<String, List<ResourcesList>>().toSortedMap()
fun setData(sortedList : SortedMap<String, List<ResourcesList>>) {
if (this.sortedList != sortedList) {
this.sortedList = sortedList
notifyDataSetChanged()
}
}
override fun getItemCount(): Int {
return sortedList.count()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SimpleViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.browsebooks_layout, parent, false)
return SimpleViewHolder(view)
}
override fun onBindViewHolder(holder: SimpleViewHolder, position: Int) {
val dataList = ArrayList(sortedList.values)[position]
holder.category_text.text = ArrayList(sortedList.keys)[position]
holder.booksByCategory = dataList
holder.horizontalAdapter.setData(dataList)
}
class SimpleViewHolder(v: View, var booksByCategory : List<ResourcesList>? = null) : RecyclerView.ViewHolder(v) {
var recyclerView : RecyclerView = v.findViewById(R.id.inner_recyclerview)
var category_text : TextView = v.findViewById(R.id.book_category)
var fragmentCallback: FragmentCallback? = null
val horizontalAdapter: BooksByCategoryAdapter
init {
recyclerView.layoutManager = object : LinearLayoutManager(v.context, LinearLayoutManager.HORIZONTAL, false) {
override fun canScrollHorizontally(): Boolean {
return true
}
override fun canScrollVertically(): Boolean {
return false
}
}
horizontalAdapter = BooksByCategoryAdapter()
recyclerView.adapter = horizontalAdapter
fragmentCallback = v.context as FragmentCallback
var mLastClickTime : Long = 0
v.see_all_btn.setOnClickListener {
val category = v.book_category.text.toString()
// double-clicking prevention, using threshold of 1000 ms
if (!(SystemClock.elapsedRealtime() - mLastClickTime < 1000)){
mLastClickTime = SystemClock.elapsedRealtime()
if(fragmentCallback != null){
fragmentCallback!!.callBackSeeAllFragment(booksByCategory!!, category)
}
}
}
}
}
}
Inner Adapter
class BooksByCategoryAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var booksByCategory: List<ResourcesList> = emptyList()
fun setData(data: List<ResourcesList>) {
if (this.booksByCategory != data) {
this.booksByCategory = data
notifyDataSetChanged()
}
}
override fun getItemCount(): Int {
return booksByCategory.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val cellForRow = layoutInflater.inflate(R.layout.bookcontainer_layout, parent, false)
return CustomVH(cellForRow)
}
override fun onBindViewHolder(rawHolder: RecyclerView.ViewHolder, position: Int) {
val holder = rawHolder as CustomVH
val booksProcessModel = BooksProcessModel()
booksProcessModel.setItem(booksByCategory[position])
holder.booksByCategory = booksByCategory[position]
Picasso.get().load(booksByCategory[position].coverURI).into(holder.inner_bookcover)
}
private inner class CustomVH(v: View, var booksByCategory : ResourcesList? = null): RecyclerView.ViewHolder(v) {
var inner_bookcover : ImageView = v.findViewById(R.id.inner_bookcover)
var fragmentCallback: FragmentCallback? = null
var ctx : Context = v.context
var mLastClickTime : Long = 0
init {
fragmentCallback = ctx as FragmentCallback
v.setOnClickListener {
// double-clicking prevention, using threshold of 1000 ms
if (!(SystemClock.elapsedRealtime() - mLastClickTime < 1000)){
mLastClickTime = SystemClock.elapsedRealtime()
if(fragmentCallback != null){
fragmentCallback!!.callBackDownloadBookFragment(booksByCategory!!)
}
}
}
}
}
class BooksProcessModel {
private var processBooks : ResourcesList? = null
fun setItem(books: ResourcesList) {
this.processBooks = books
}
fun setVisibility(ctx: Context) : Int {
val sp = PreferenceManager.getDefaultSharedPreferences(ctx)
val page = sp.getString(processBooks!!.id.toString(), "")
if (page != "") {
return View.VISIBLE
}
return View.INVISIBLE
}
}
}
You need to change the layout_height of the outer recycler view to wrap_content.
Nevermind, figured it out. I should be using a NestedScrollView instead of a ScrollView. The missing items were still there. It's just that I couldn't scroll the nested recyclerview.
In my case it was because I had the RecyclerView directly and even though it scrolled (horizontally), the same thing happened to me if for example the keyboard appeared.
Solution: Put the RecyclerView inside a NestedScrollView and delegate the scroll to it, like this:
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="#layout/item"/>
</androidx.core.widget.NestedScrollView>

Categories

Resources