Reputation: 103
As always I have read through several posts on this topic across this site. If this truly is duplication I will delete this question. Majority of cases on here are dealing with orientation changes or looking to amend fixed values depending on the screensize. I am not worried about fixing width and height values.
What I want to achieve is a 6x10 grid which fills the screen no matter what size it is (orientation is fixed to portrait)
Here is my recyclerview item, I started with wrap content on the views and then tried match parent, neither makes any difference. On a small screen it fits fine and on a large screen it sits in the middle but is the same size.
I know I can't directly create a chain in my recyclerview item xml because I need to make a chain out of more than 1 view. I attempted to manually set the main layout with spread chain and a weight of 1 and then set the layout to 0dp, ran the code and obviously it didnt work
So, key question, is there a way to simply write the item xml so that it is dynamic or do we always have to create a subclass of sorts to generate different layouts per screensize?
<?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="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp">
<LinearLayout
android:id="@+id/layout_background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="3dp"
android:background="@drawable/level_background"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/TV_Level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center|center_horizontal|center_vertical"
android:textColor="@color/sub_level_button_text_color" />
<RatingBar
android:id="@+id/ratingBar"
style="@style/Widget.AppCompat.RatingBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/StarOutline"
android:isIndicator="true"
android:numStars="3"
android:progressTint="@color/StarOutline"
android:stepSize="0.5" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
To further assist with this here is my adapter
package com.maxcell.sumitup
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.RatingBar
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
class LevelsAdaptor(private val onClick:(id:Int,mainLevel:Int,subLevel:Int,stars:Float,bonusGame:Boolean,type:Int)->Unit) : ListAdapter<Levels, LevelsAdaptor.LevelsViewHolder>(LevelsComparator()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LevelsViewHolder {
val view: View = LayoutInflater.from(parent.context)
.inflate(R.layout.rv_storymode_items, parent, false)
return LevelsViewHolder(view)
}
override fun onBindViewHolder(holder: LevelsViewHolder, position: Int) {
val current = getItem(position)
holder.bind(
current.id,
current.mainLevel,
current.subLevel,
current.stars,
current.unlocked,
current.bonusround,
current.questiontype
)
}
inner class LevelsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val TVLEVEL: TextView = itemView.findViewById(R.id.TV_Level)
private val rating: RatingBar = itemView.findViewById(R.id.ratingBar)
private val layoutBackground: LinearLayout = itemView.findViewById(R.id.layout_background)
private val myContext = itemView.context
//private val myContext: Context = sumView.context
fun bind(ID: Int, ML: Int, SL: Int, Stars: Float, Unlocked: Boolean,BonusRound:Boolean,QuestionType:Int) {
TVLEVEL.text = ID.toString()
rating.rating = Stars
if (Unlocked){
itemView.isEnabled=true;itemView.isClickable=true;layoutBackground.setBackgroundResource(R.drawable.level_background)
}else{
itemView.isEnabled=false;itemView.isClickable=false;layoutBackground.setBackgroundResource(R.drawable.standard_background_deactivated);TVLEVEL.setTextColor(myContext.getColor(R.color.ColorOnDeactivated))
}
itemView.setOnClickListener {
//Set your codes about intent here
onClick(ID,ML,SL,Stars,BonusRound,QuestionType)
}
}
}
}
class LevelsComparator : DiffUtil.ItemCallback<Levels>() {
override fun areItemsTheSame(oldItem: Levels, newItem: Levels): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Levels, newItem: Levels): Boolean {
return oldItem == newItem
}
}
Upvotes: 0
Views: 533
Reputation: 900
If you set the RecyclerView
width to match_parent
, your ConstraintLayout
, LinearLayout
, TextView
and RatingBar
widths to match_parent
, the items will stretch to fill the entire width of the screen (assuming you're using GridLayoutManager
)
However, you'll notice that they don't fit the screen vertically, you have to scroll to them all. Setting height to 'match_parent' won't help here, you'll have to calculate the height in your adapter if you want them to fit exact.
This might make it look a bit strange on certain devices though (such as phones with longer screens).
To give a better looking layout, you might want to set the following properties on the ConstraintLayout
:
android:layout_height="0dp"
app:layout_constraintDimensionRatio="3:1"
Upvotes: 1