i am having an issue with my gson parsing. I have a nested gson and i would like get the value of "name" under attributes. The problem is my recyclerview is only showing the first value(which is bill 1) and not bill 2 or bill 3. here is my code
// MainActivity.kt
recycler_view.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(LineItemDecorator(requireContext()))
val bill = GsonBuilder().create().fromJson(jsonString, Bills::class.java)
val nameList: List<Bill> = Arrays.asList(bill)
val adapter = BillsRecyclerAdapter(nameList)
recycler_view.adapter = adapter
adapter.notifyDataSetChanged()
// Bills.kt
data class Bills(
val data: ArrayList<Data>,
val meta: Meta,
val links: Links
)
// BillsRecyclerAdapter.kt
class BillsRecyclerAdapter(private val items: List<Bill>):
RecyclerView.Adapter<BillsRecyclerAdapter.BillsHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BillsHolder {
return BillsHolder(parent.inflate(R.layout.bills_list_item))
}
override fun onBindViewHolder(holder: BillsHolder, position: Int) {
holder.billName.text = items[position].data[position].attributes.name
}
override fun getItemCount() = items.size
class BillsHolder(view: View): RecyclerView.ViewHolder(view) {
val billName: TextView = view.billName
val billAmount: TextView = view.billAmount
}
}
<!-- recyclerview.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_marginTop="#dimen/materialize_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<!-- bill_list_item.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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/billName"
android:textSize="20sp"
android:layout_marginStart="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="#+id/billAmount"
android:textSize="20sp"
android:layout_marginEnd="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
here is my json string. https://pastebin.com/iEqhmB35
thanks for any help provided
Check the following
Check your items.size if it really is not zero,
Also check your bills_list_item.xml try to set the root parent's height to wrap_content
Also check if you have this on you recyclerview
recyclerView.setHasFixedSize(true);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
What's important there is the layout manager
If it doesn't help, can you share your Bills.java class, there might be something wrong with the serialization of JSON raw data.
Hope this helps.
Cheers
Related
I have an activity with recycleView this is what I should show in design
I use this code to show it
val arr:ArrayList<string> = arrayListOf("English","Intermediate","English","English","arr","UICollectionViewFlowLayoutFlowFlowFlow","English","UICollectionViewDelegate","English","Intermediate","UIViewController","viewDidLoad","Intermediate","String","Intermediate","arr","Intermediate","UIKit","Intermediate","English","columnLayout","English","languageLabel")
recyclerView.setLayoutDirection(View.LAYOUT_DIRECTION_RTL)
recyclerView.layoutManager = GridLayoutManager(this, 3)
adaAdapter = CustomAdapter(this, arr)
recyclerView.adapter = adaAdapter
With this adapter
class CustomAdapter(val context: DreamsActivity, val items: ArrayList<String>) : RecyclerView.Adapter<CustomAdapter.ViewHolderProductList>() {
// holds this device's screen width,
private var screenWidth = 0
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolderProductList {
val displayMetrics = DisplayMetrics()
context.windowManager.getDefaultDisplay().getMetrics(displayMetrics)
screenWidth = displayMetrics.widthPixels
val layoutInflater = LayoutInflater.from(parent.context)
val cellForRow = layoutInflater.inflate(R.layout.dreams_collection,parent, false)
val devicewidth: Int = (displayMetrics.widthPixels / 3) - 10
val params = cellForRow.getLayoutParams() as GridLayoutManager.LayoutParams
params.width = devicewidth
cellForRow.setLayoutParams(params)
return ViewHolderProductList(cellForRow)
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: ViewHolderProductList, position: Int) {
val item = items[position]
holder.typeTv.text = item
}
inner class ViewHolderProductList(itemView: View) : RecyclerView.ViewHolder(itemView) {
var typeTv: TextView = itemView.findViewById(R.id.typeTv)
var mainL: ConstraintLayout = itemView.findViewById(R.id.mainL)
}
}
With this 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"
tools:context=".MainActivity">
<RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="15dp"
android:background="#FFFFFF"
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 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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mainL"
android:layout_width="60dp"
android:padding="10dp"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/typeTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="5dp"
android:text="TextView"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
But I got this
And don't know how to do it as I need the number of items to be dynamic according to the text length but the GridLayoutManager only sets the number of columns static.
Any help is greatly appreciated
The desired layout tends to be Chips rather than a RecyclerView
Here is a demo:
Material app gradle dependency: implementation 'com.google.android.material:material:1.4.0'
Layout:
<com.google.android.material.chip.ChipGroup xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/my_chip_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
app:chipSpacing="16dp"
app:chipSpacingHorizontal="4dp"
app:chipSpacingVertical="4dp" />
Adding chips:
val arr =
arrayListOf(
"English",
"Intermediate",
"English",
"English",
"arr",
"UICollectionViewFlowLayoutFlowFlowFlow",
"English",
"UICollectionViewDelegate",
"English",
"Intermediate",
"UIViewController",
"viewDidLoad",
"Intermediate",
"String",
"Intermediate",
"arr",
"Intermediate",
"UIKit",
"Intermediate",
"English",
"columnLayout",
"English",
"languageLabel"
)
fun addChips(context: Context) {
val chipGroup = findViewById<ChipGroup>(R.id.my_chip_group)
for (i in 0 until arr.size) {
val chip = Chip(context)
chip.layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
chip.text = arr[i]
chipGroup.addView(chip)
}
}
What you're asking for is something with the visual look of a Chip from Material Components. While the documentation for Chips suggests putting them in a ChipGroup, this loses the benefit of recycling views if you have more than enough to cover the screen. On the other hand, if they need to behave like a RadioGroup, where you can select only one to be toggled at a time, then ChipGroup would be easier to use.
To do this with RecylerView, you can change your item view layouts to use a Chip instead of a TextView. Set the item's layout width to wrapContent. Then use Google's Flexbox Layout library to get the layout with variable length items.
In Gradle dependencies: implementation 'com.google.android.flexbox:flexbox:3.0.0'
In your activity:
recyclerView.layoutManager = FlexboxLayoutManager(this)
.apply { flexDirection = FlexDirection.ROW }
Result:
There's a related question here that is helpful.
I'm a Kotlin newbie learning how to create simple recyclerview apps. My code is supposed to list the integers 1..10 in vertically stacked cells. However, it only lists the first item. I've consulted several tutorials and reviewed my code several times(after long breaks), but I can't see anything wrong in my code.
I got the bright idea early today to print Log statements. Examining them, I note that my onBindViewHolder function is only called once. What blunder am I making?
Here is my log output:
D/QuoteAdapter: value is: 1
D/QuoteAdapter: index is: 0
D/QuoteAdapter: Size is: 10
my activity:
class MainActivity : AppCompatActivity() {
lateinit var mRecyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mRecyclerView = findViewById(R.id.recyclerView)
mRecyclerView.layoutManager = LinearLayoutManager(this)
mRecyclerView.adapter = QuoteAdapter()
//mRecyclerView.setHasFixedSize(true)
}
}
my adapter:
class QuoteAdapter : RecyclerView.Adapter<QuoteViewHolder>() {
private val listOfInts = intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
private val TAG = "QuoteAdapter"
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QuoteViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.recyclerview_item_row, parent, false)
return QuoteViewHolder(view)
}
override fun getItemCount(): Int {
Log.d(TAG, "Size is: ${listOfInts.size.toString()}")
return listOfInts.size
}
override fun onBindViewHolder(holder: QuoteViewHolder, position: Int) {
val item = listOfInts[position]
Log.d(TAG, "value is: ${item.toString()}")
Log.d(TAG, "index is: ${position.toString()}")
holder.listTitle.text = item.toString()
}
}
my viewholder:
class QuoteViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val listTitle = itemView.findViewById(R.id.itemString) as TextView
}
my layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/itemString"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
my main layout is shown below:
<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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
In your "my layout" try this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/itemString"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Notice layout_height of LinearLayout has changed to wrap_content
Also doubt you need the android:orientation="vertical" on your ViewHolders item xml unless you will add more than just 1 TextView in the future.
Like Zain says, you can just use a TextView on its own in a layout file, which will also fix the problem (so long as its height is wrap_content!)
There are actually a few included with Android - type android.R.layout. and you'll see a few things, like simple_list_item_1 which is just a styled TextView (you can ctrl+click the reference or whatever to look at the file). Can be nice if you just want to make a quick thing!
The ID of the TextView in android.R.layout.simple_list_item_1 is #android:id/text1 - note the android prefix, because its part of the android resources, not your app's. Which means you have to reference the ID in the same way as the layout, with android at the front: android.R.id.text1
You can get rid of the LinearLayout in the list item layout, and only keep the TextView.
So, replace your list item layout with:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/itemString"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Why do I get a NullPointerException in my ViewHolder's bindItems() method?
I've highlighted the line where I get the NullPointerException. The blogpost_author ID exists, as you can see in the XML, so what's the problem here? How is findViewById<TextView>(R.id.blogpost_author) returning null?
Adapter and ViewHolder code:
class BlogPostAdapter(val blogList: ArrayList<BlogPost>) : RecyclerView.Adapter<BlogPostAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : BlogPostAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.blog_post_list, parent, false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return blogList.size
}
override fun onBindViewHolder(holder: BlogPostAdapter.ViewHolder, position: Int) {
holder.bindItems(blogList[position])
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(blogPost: BlogPost) {
val blogPostAuthor = itemView.findViewById<TextView>(R.id.blogpost_author) // THIS LINE - NULL POINTER EXCEPTION
val blogPostTitle = itemView.findViewById<TextView>(R.id.blogpost_title)
blogPostAuthor.text = blogPost.author
blogPostTitle.text = blogPost.title
}
}
}
Activity code:
class BlogPostListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.blog_post_list)
// Get the RecyclerView from XML itself
val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)
// Add a layout manager - What does a layout manager do?
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
// Create an array list to store blogposts using the the data class blogPost
val blogPosts = ArrayList<BlogPost>()
// Add some dummy data to the list
blogPosts.add(BlogPost(123, "First Blog Post", "John"))
blogPosts.add(BlogPost(456, "Second Blog Post", "Bob"))
blogPosts.add(BlogPost(789, "Third Blog Post", "Mary"))
// Create an adapter
val adapter = BlogPostAdapter(blogPosts)
// Add the adapter to the recyclerview
recyclerView.adapter = adapter
}
}
Kotlin data class:
data class BlogPost(val id: Int, val title: String, val author: String)
XML for RecyclerView:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.topzap.android.kotlinlistapptest.BlogPostListActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
XML for CardView layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/blogpost_author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="AuthorPlaceHolder"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large"
/>
<TextView
android:id="#+id/blogpost_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="TitlePlaceHolder"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
You may be inflating the wrong layout within your RecyclerView.
This line within your onCreateViewHolder method:
val v = LayoutInflater.from(parent.context).inflate(R.layout.blog_post_list, parent, false)
You are inflating the blog_post_list.xml, which I'm assuming is the wrong layout file due to the fact you're also inflating that layout within your BlogPostListActivity here:
setContentView(R.layout.blog_post_list)
So when this line is called:
val blogPostAuthor = itemView.findViewById<TextView>(R.id.blogpost_author)
It is looking for the id 'blogpost_author' within R.layout.blog_post_list and as you can see there is no blogpost_author TextView within that layout so it returns null.
To sort it out, it should be straight forward and just change the layout resource that you're assigning to each ViewHolder within your onCreateViewHolder method with the correct layout for your CardView layout.
Which means the line should read something like:
val v = LayoutInflater.from(parent.context).inflate(R.layout.your_card_layout, parent, false)
I was trying to make a custom RecyclerView with Adapter which takes a HashMap as parameter, I succeeded but now only 1 item is showing in recyclerView list and I have no idea why.
Here my code snippet:
Custom RecyclerAdapter:
class ProductsRecyclerAdapter(private val dataSet: HashMap<Int, ProductEntry>) : RecyclerView.Adapter<ProductsRecyclerAdapter.ViewHolder>() {
class ViewHolder(val linearLay: LinearLayout) : RecyclerView.ViewHolder(linearLay)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : ProductsRecyclerAdapter.ViewHolder {
val linearLay = LayoutInflater.from(parent.context).inflate(R.layout.test_text_view, parent, false) as LinearLayout
return ViewHolder(linearLay)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.linearLay.textView.text = dataSet[position]?.pName
holder.linearLay.textView2.text = dataSet[position]?.pExpiry
}
override fun getItemCount(): Int {
return dataSet.size
}
}
Initialization:
// Setup RecyclerView
val prod1 = ProductEntry("Milk", "04/06/1996")
val prod2 = ProductEntry("Bread", "04/01/2012")
val testArray : HashMap<Int, ProductEntry> = hashMapOf(1 to prod1, 2 to prod2)
viewManager = LinearLayoutManager(this)
viewAdapter = ProductsRecyclerAdapter(testArray)
recyclerView = findViewById<RecyclerView>(R.id.productsRecyclerView).apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = viewAdapter
}
And finally, custom XML for row:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/linearLay"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_weight="1"
android:text="TextView" />
Despite everything seems to be OK, I get only 1 row showing "milk".
Thanks for all help!
position in override fun onBindViewHolder(holder: ViewHolder, position: Int) starts at index 0.
So in your case, it will be [0, 1] and your map keys are [1, 2]. Only key "1" will be displayed correctly.
try:
val testArray : HashMap<Int, ProductEntry> = hashMapOf(0 to prod1, 1 to prod2)
But no need to use a map here! Just use a simple list of ProductEntry.
What is the best strategy to achieve this feature:
I Have a horizontal RecyclerView with cards.
Each card will fulfil the entire screen, but I want it to show part of the next card and previous one if it has more than one item.
I know I can achieve this by setting my card android:layout_width at the adapter to have a specific DP like 250dp instead of match_parent.
But it doesn't look like a proper solution.
This is my code:
Activity with RecyclerView:
class ListPokemon : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val items = createListPokemons()
recyclerView.adapter = PokemonAdapter(items)
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
recyclerView.setHasFixedSize(true)
val pagerSnapHelper = PagerSnapHelper()
pagerSnapHelper.attachToRecyclerView(recyclerView)
}
private fun createListPokemons(): List<Pokemon> {
val pokemons = ArrayList<Pokemon>()
pokemons += createPokemon("Pikachu")
pokemons += createPokemon("Bulbasaur")
pokemons += createPokemon("Charmander")
pokemons += createPokemon("Squirtle")
return pokemons
}
private fun createPokemon(name: String) = Pokemon(name = name, height = 1, weight = 69, id = 1)
}
Layout of Activity:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"/>
</android.support.constraint.ConstraintLayout>
Adapter:
class PokemonAdapter(val list: List<Pokemon>) : RecyclerView.Adapter<PokemonAdapter.PokemonVH>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PokemonAdapter.PokemonVH {
return PokemonVH(LayoutInflater.from(parent.context)
.inflate(R.layout.pokemon_item, parent, false))
}
override fun onBindViewHolder(holder: PokemonAdapter.PokemonVH, position: Int) {
holder.textViewName.text = list[position].name
}
override fun getItemCount(): Int {
return list.size
}
class PokemonVH(itemView: View) : RecyclerView.ViewHolder(itemView) {
var textViewName: TextView = itemView.findViewById(R.id.textViewName)
}
}
Layout of Adapter:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android:layout_gravity="center_horizontal"
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:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:padding="36dp"
android:id="#+id/textViewName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="22sp"
tools:text="Teste String"/>
</LinearLayout>
</android.support.v7.widget.CardView>
This is my result:
I would like to show part of the next card at this situation. How can I do this?
Thanks.
What you need to do is set padding to your RecyclerView, set clipToPadding to false, use a SnapHelper with it, and you need to make sure the margins on your cards are less than or equal to the padding in the RecylerView.
So, let's say you want the distance from the cards to the sides of the screen to be 16dp and you want the distance between the cards to be 8dp. You'll have to set the margins on each card to 4dp, so the total margin is 8dp. And you have to set the padding to 12dp, given there's already a margin of 4dp on each side of the card.
It'll look a bit like this:
Your list:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
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"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:clipToPadding="false"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingEnd="12dp"/>
Your cards:
<?xml version="1.0" encoding="utf-8"?>
<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:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
app:cardElevation="2dp"/>
I think the padding solution is not a good for all cases, because forces the last item to have padding to the right.
Personally i use runtime width calculation of each item and i am very satisfied with this. So you can do the following:
onBindViewHolder
if (position == data.size - 1) {
holder.itemView.layoutParams = RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT)
} else {
if (width == null) {
holder.itemView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
holder.itemView.viewTreeObserver.removeOnGlobalLayoutListener(this)
width = holder.itemView.width
params.width = width!! - partOfPage
holder.itemView.requestLayout()
}
})
} else {
params.width = width!! - partOfPage
holder.itemView.requestLayout()
}
}
The outcome is that all middle items are rendered showing a part of the next page, but the last one is rendered full width.
Change your CardView width from "match_parent" to "0dp". And add, layout_weight as "80" (or similar). Make your parent view (RecyclerView) layout_weightSum as "100".
android:layout_width="0dp"
android:layout_weight="80"