I'm trying to display a list of files and folders using a RecyclerView.
Here is the Adapter and the ViewHolder :
class FilesRecyclerViewAdapter(private val files: Array<File>) : RecyclerView.Adapter<FilesRecyclerViewAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.fragment_file_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = files[position]
holder.icon.setImageResource(if (item.isDirectory) R.drawable.folder else R.drawable.file)
holder.fileName.text = item.name
}
override fun getItemCount(): Int = files.size
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val icon: ImageView = view.findViewById(R.id.icon)
val fileName: TextView = view.findViewById(R.id.fileName)
}
}
The layout for a single item in the list (R.layout.fragment_file_item) :
<?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:id="#+id/fileItem"
android:layout_width="match_parent"
android:layout_height="#dimen/file_item_height">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/icon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_launcher_foreground" />
<TextView
android:id="#+id/fileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:text="Element"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/icon"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
And this is how it's included into the main activity :
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/fileSystem"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Finally the code in the onCreate function of the main activity :
private lateinit var fileSystem: RecyclerView
// Later in the code
fileSystem = findViewById(R.id.fileSystem)
fileSystem.layoutManager = LinearLayoutManager(this)
fileSystem.adapter = FilesRecyclerViewAdapter(Environment.getExternalStorageDirectory().listFiles())
I expected to have a list of items with the icon on the left and the name of the folder slighly to the right like on the item layout preview :
Instead, I have this mess :
What did I do wrong ?
app:layout_constraintHorizontal_bias="0.5" makes your RecyclerView start on 50% of view.
Remove it, if you dont need them
Related
I have Recyclerview multiple view types and have Recyclerview in Recyclerview when scroll lag first time I do not know why scroll lag first time
here my layout fragment
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.LottoFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/teal_700"
android:padding="20dp">
<LinearLayout
android:id="#+id/searchLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/menuTextInputLayout"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/label">
<AutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="#+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_peekHeight="56dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/ic_list_header_background"
android:clickable="true"
android:elevation="4dp"
android:orientation="horizontal"
android:padding="20dp">
<TextView
android:id="#+id/lotto_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/kanit_light"
android:text="0 items(s)" />
<ImageView
android:id="#+id/filterIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:src="#android:drawable/arrow_up_float"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:id="#+id/front_layer_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/lotto_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="64dp"
tools:itemCount="3"
tools:listitem="#layout/item_lotto_prizes_one" />
</LinearLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
here my fragment
lottoRecyclerView.apply {
layoutManager = LinearLayoutManager(context)
adapter = lottoLatestAdapter
}
here my Adapter:
class LottoLatestAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
private const val VIEW_TYPE_LOTTO_PRIZE_ONE = 1
private const val VIEW_TYPE_LOTTO_PRIZE_RUNNING_NUMBER = 2
private const val VIEW_TYPE_LOTTO_PRIZE_ONE_NEAR = 3
private const val VIEW_TYPE_LOTTO_PRIZE_OTHER = 4
}
var latestList: MutableList<LottoPrizesLatestModel> = mutableListOf()
set(value) {
field = value
notifyDataSetChanged()
}
private val viewPool : RecycledViewPool = RecycledViewPool()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
VIEW_TYPE_LOTTO_PRIZE_ONE -> {
LottoPrizeOneHolder(ItemLottoPrizesOneBinding.inflate(inflater, parent, false))
}
VIEW_TYPE_LOTTO_PRIZE_RUNNING_NUMBER -> {
LottoPrizeRunningNumberHolder(
ItemLottoRunningNumbersBinding.inflate(
inflater,
parent,
false
)
)
}
VIEW_TYPE_LOTTO_PRIZE_ONE_NEAR -> {
LottoPrizeOneNearHolder(
ItemLottoPrizesOneNearBinding.inflate(
inflater,
parent,
false
)
)
}
VIEW_TYPE_LOTTO_PRIZE_OTHER -> {
LottoPrizeOtherListHolder(
ItemLottoPrizesOtherListBinding.inflate(
inflater,
parent,
false
),
LottoLatestPrizeOtherAdapter()
)
}
else -> throw NullPointerException("Not have view Type")
}
}
override fun getItemViewType(position: Int): Int {
return when (latestList[position]) {
is LottoPrizesLatestModel.LottoLatestPrizeOne -> VIEW_TYPE_LOTTO_PRIZE_ONE
is LottoPrizesLatestModel.LottoLatestRunningNumbers -> VIEW_TYPE_LOTTO_PRIZE_RUNNING_NUMBER
is LottoPrizesLatestModel.LottoLatestPrizeFirstNear -> VIEW_TYPE_LOTTO_PRIZE_ONE_NEAR
is LottoPrizesLatestModel.LottoLatestPrizeOther -> VIEW_TYPE_LOTTO_PRIZE_OTHER
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is LottoPrizeOneHolder -> holder.bind(latestList[position] as LottoPrizesLatestModel.LottoLatestPrizeOne)
is LottoPrizeRunningNumberHolder -> holder.bind(latestList[position] as LottoPrizesLatestModel.LottoLatestRunningNumbers)
is LottoPrizeOneNearHolder -> holder.bind(latestList[position] as LottoPrizesLatestModel.LottoLatestPrizeFirstNear)
is LottoPrizeOtherListHolder -> {
viewPool.putRecycledView(holder)
holder.bind(latestList[position] as LottoPrizesLatestModel.LottoLatestPrizeOther, viewPool)
}
}
}
override fun getItemCount(): Int = latestList.size
}
here my layout holder
<?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:layout_margin="8dp">
<TextView
android:id="#+id/title_prize_other_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/kanit_light"
android:gravity="center"
android:textSize="26sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/prize_other_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/title_prize_other_text_view"
tools:itemCount="10"
tools:listitem="#layout/item_lotto_prizes_other" />
<GridLayout
android:id="#+id/prize_other_grip_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/title_prize_other_text_view" />
<TextView
android:id="#+id/text_prize_one_near_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/kanit_light"
android:text="#string/lotto_prize_per_baht"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/prize_other_recycler_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
and here my holder recyclerView in RecyclerView
class LottoPrizeOtherListHolder(
private val binding: ItemLottoPrizesOtherListBinding,
private val lottoLatestPrizeOtherAdapter: LottoLatestPrizeOtherAdapter
) :
RecyclerView.ViewHolder(binding.root) {
fun bind(
lottoLatestPrizeOther: LottoPrizesLatestModel.LottoLatestPrizeOther,
viewPool: RecyclerView.RecycledViewPool
) = with(binding) {
prizeOtherRecyclerView.apply {
layoutManager = GridLayoutManager(
context,
2,
GridLayoutManager.VERTICAL,
false
).apply {
initialPrefetchItemCount = lottoLatestPrizeOther.prizeModel.number.size
}
this.adapter = lottoLatestPrizeOtherAdapter
setRecycledViewPool(viewPool)
}
lottoLatestPrizeOtherAdapter.numberList =
lottoLatestPrizeOther.prizeModel.number.toMutableList()
titlePrizeOtherTextView.text = lottoLatestPrizeOther.prizeModel.name
textPrizeOneNearTextView.text = itemView.context.getString(
R.string.lotto_prize_per_baht,
lottoLatestPrizeOther.prizeModel.reward
)
}
}
my problem is : When i scroll recyclerview for first time it is not smooth and logcat show recyclerview Skipped 51 frames! adapter but when I reach end of recyclerView and scroll to up then scroll down it is very smooth and my recyclerview have TextView Only !!! how can I solve this issue?
this my video App https://youtu.be/Li7aKWmEfXQ
In your fragment add this after applying LayoutManager:
lottoRecyclerView.setDrawingCacheEnabled(true);
lottoRecyclerView.setItemViewCacheSize(myCacheSize);
The main reason Jank occurs the first time because on the first time it is loading the values onto memory dynamically. while once it is down it already has a few elements pre loaded
You can handle it using
mRecyclerView.setHasFixedSize(true);
mRecyclerview.setNestedScrollingEnabled(false);
in your kotlin code
or add android:nestedScrollingEnabled="false" in your RecyclerView xml
You can reach some performance improvements by applying the following:
recyclerView.setHasFixedSize(true);
recyclerView.setDrawingCacheEnabled(true);
..in combination with lite mode of MapsView:
<com.google.android.gms.maps.MapView
android:layout_width="match_parent"
android:layout_height="200dp"
app:liteMode="true"
app:mapType="normal" />
For it was not an option to disable nestedScrollingEnabled as mentioned by #Narendra_Nath, which further improves performance.
I want to use databinding for recyclerview. I created a model with BindignAdapter annotation. But after that I don't know what should I do and I didn't find any solution.
I want to set some data for recyclerview adapter and set the adapter as recyclerview adapter and show data in the recyclerview.
This is my MainActivity XML file(This line has an error:android:recyclerUser="#{dog.recyclerViewBinder()}"):
<?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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="dog"
type="com.hooman.databinding.DogModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:recyclerUser="#{dog.recyclerViewBinder()}"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
This is my model class:
class DogModel(var dogName:String, var dogImage:String?, var dogBreed:String,var context: Context){
#BindingAdapter("android:loadImage")
fun loadImage(imageView: ImageView,dogImage:String?){
Picasso.get().load(dogImage).into(imageView)
}
#BindingAdapter("android:recyclerUser")
fun recyclerViewBinder(recyclerView: RecyclerView,dogList: MutableList<DogModel>){
var dogAdapter = DogAdapter(dogList)
recyclerView.layoutManager = LinearLayoutManager(context,LinearLayoutManager.VERTICAL,false)
recyclerView.adapter = dogAdapter
}
}
This is recyclerview's adapter:
class DogAdapter(var dogList:List<DogModel>): RecyclerView.Adapter<DogAdapter.DogViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DogViewHolder {
val view = DataBindingUtil.inflate<RvDogItemBinding>(LayoutInflater.from(parent.context),R.layout.rv_dog_item,parent,false)
return DogViewHolder(view)
}
override fun onBindViewHolder(holder: DogViewHolder, position: Int) {
holder.view.dog = dogList[position]
holder.view.executePendingBindings()
}
override fun getItemCount(): Int {
return dogList.size
}
inner class DogViewHolder(var view: RvDogItemBinding) : RecyclerView.ViewHolder(view.root)
}
This is rv_dog_item.xml file:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="dog"
type="com.hooman.databinding.DogModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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_margin="8dp"
app:cardCornerRadius="10dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/img_dog"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:loadImage="#{dog.dogImage}"/>
<TextView
android:id="#+id/txt_dogName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="#id/img_dog"
app:layout_constraintEnd_toStartOf="#id/img_dog"
android:textSize="22sp"
android:padding="10dp"
android:textColor="#color/black"
android:text="#{dog.dogName}"/>
<TextView
android:id="#+id/txt_dogBreed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/txt_dogName"
app:layout_constraintStart_toStartOf="#id/txt_dogName"
app:layout_constraintEnd_toEndOf="#id/txt_dogName"
android:layout_marginTop="32dp"
android:text="#{dog.dogBreed}"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
And this is mainActivity class:
class MainActivity : AppCompatActivity() {
lateinit var binding:ActivityMainBinding
lateinit var adapter:DogAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//setContentView(R.layout.activity_main)
binding = DataBindingUtil.setContentView(this,R.layout.activity_main)
var model = DogModel("Foo Dog",null,"Husky",this)
binding.dog = model
}
}
So what I should I do next and what did I make a mistake?
I have this layout and am trying to switch on a corresponding LL based on a position. However the first Linear Layout will only show up and be drawn if I give the text view inside an absolute dimension such as 200dp for the width, I have tried 0dp with constraints as well.
<?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/draft_rider_container"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#000000"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="lost"
android:textColor="#android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
<LinearLayout
android:id="#+id/section"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone">
<TextView
android:id="#+id/fake"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
tools:text="Andrea Dovizioso's"></TextView>
</LinearLayout>
<LinearLayout
android:id="#+id/row"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone">
<TextView
android:id="#+id/rider_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
tools:text="Andrea Dovizioso's"></TextView>
</LinearLayout>
This layout is rendered from a recycler view that is on my fragment which is placed like this :
<?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=".roster.RosterFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/player_rider_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ffffff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="15dp"
android:src="#drawable/baseline_edit_white_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:rippleColor="#color/colorPrimary" />
And here is my adapter :
class PlayerRidersAdapter : RecyclerView.Adapter<PlayerRidersAdapter.ViewHolder>() {
var riderList = ArrayList<Rider>()
override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.rider_item_layout, null, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return riderList.count() + 2
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when(position) {
0 -> showHeader(holder)
3 -> showSection(holder)
else -> showRow(holder)
}
}
fun showHeader(holder: ViewHolder) {
holder.headerContainer.visibility = View.VISIBLE
holder.sectionContainer.visibility = View.GONE
holder.rowContainer.visibility = View.GONE
}
fun showRow(holder: ViewHolder) {
holder.headerContainer.visibility = View.GONE
holder.sectionContainer.visibility = View.GONE
holder.rowContainer.visibility = View.VISIBLE
//holder.name.text = rider.name
}
fun showSection(holder: ViewHolder) {
holder.headerContainer.visibility = View.GONE
holder.sectionContainer.visibility = View.VISIBLE
holder.rowContainer.visibility = View.GONE
}
fun addRiders(riders : ArrayList<Rider>){
riderList.addAll(riders)
notifyDataSetChanged()
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var headerContainer = view.findViewById<LinearLayout>(R.id.header)
var sectionContainer = view.findViewById<LinearLayout>(R.id.section)
var rowContainer = view.findViewById<LinearLayout>(R.id.row)
var name = view.findViewById<TextView>(R.id.rider_name)
}
}
In your adapter, specify the following in onCreateViewHolder():
val view = LayoutInflater.from(parent.context).inflate(R.layout.rider_item_layout, parent, false)
Specifying the root argument will let the inflated layout be sized properly. This is most likely your problem.
However, match_parent sometimes has strange behavior when used in ConstraintLayout, so use 0dp instead and remember to constrain the effected sides. It would be nice for ConstraintLayout to either handle this case, report it as an error or, at least, support a Lint check.
An aside: The constraints on the TextViews that are held within a LinearLayout have no effect. Constraints only apply to direct children of ConstraintLayout.
The RecyclerView shows simple items. Each item has one TextView inside FrameLayout. TextView has no any paddings, but in some cases they appears unexpectedly. The picture below shows that the padding appears immediately after opening the keyboard. The padding appears only if the text contains newline characters. How to fix it ?
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var adapter : MyAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView : RecyclerView = findViewById(R.id.recyclerView)
val button : Button = findViewById(R.id.button)
adapter = MyAdapter();
recyclerView.adapter = adapter;
button.setOnClickListener {
adapter.notifyDataSetChanged()
}
}
}
class MyViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView;
init {
textView = view.findViewById(R.id.txt)
}
}
class MyAdapter : RecyclerView.Adapter<MyViewHolder>() {
private val data = listOf("Text without \\n ", "multiline\ntext")
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
MyViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false))
override fun getItemCount() = data.size;
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.textView.text = data[position]
}
}
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:background="#android:color/holo_blue_light"
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
activity_main.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:background="#ffffff"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="notifyDataSetChanged"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:id="#+id/button"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toTopOf="#+id/button"
android:id="#+id/recyclerView"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/editText"
app:layout_constraintStart_toEndOf="#+id/button" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The problem is that when the soft keyboard appears, it overlaps the recyclerView. But I want my soft keyboard just push recycler to the top, to be above the keyboard, like with windowSoftInputMode="adjustPan".
But adjustPan is not the option because I need my tool bar.
I have tried adjustResize already, but no luck.
Main activity layout
<?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"
tools:context=".MainActivity"
>
<include
layout="#layout/toolbar_layout"
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/recyc"
app:layout_constraintBottom_toTopOf="#+id/message_edit_text"
app:layout_constraintTop_toBottomOf="#+id/toolbar_layout"/>
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/message_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textShortMessage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Adapter 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="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Here is my MainActivity code, there is the only onCreate method
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyc.layoutManager = LinearLayoutManager(this)
val adapter = MyAdapter(
arrayOf("sd","sd2","sd2","sd2","sd2","s2d","s2d","sd",
"sd2","s2d","s2d","sd5","s8d","67sd","s76d")
)
recyc.adapter = adapter
}
Here is my adapter class
class MyAdapter(private val myDataset: Array<String>) :
RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
class MyViewHolder(val view: View) :
RecyclerView.ViewHolder(view)
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): MyAdapter.MyViewHolder {
val textView = LayoutInflater.from(parent.context)
.inflate(R.layout.container, parent, false)
return MyViewHolder(textView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int)
{ holder.itemView.textView.text = myDataset[position] }
override fun getItemCount() = myDataset.size
}