Heterogeneous Views with unknow EditText number - android

I'm working on a dynamicViews (not sure if that's the right word for creating a view from a json file).
I'm getting the schema from a JSON file, I've stepped up the recycleView and its adapter, so far so good, each Recycleview item (must or not) contain a number of EditText whose number is unknown in advance, so based on the Json file, I have to inflate inside.
I searched a lot but the similar solution I found for Heterogene Recycleview: the idea was to use separate layout and inflate each of them according to your needs inside onCreateViewHolder but the developer who published the solution knew in advance what is the combination of all possible views and he just switch.
class Adapter_base_Display(private val listener: Display_Fragment,
activity: FragmentActivity ,
liste_display : ArrayList<DisplaySections>)
: RecyclerView.Adapter<Base_DisplayViewHolder>() {
private val activityIns = activity
private val liste_display_Recycle_adapter = liste_display
interface Base_DisplayListener {
fun onClickeddisplay(position: Int)
}
private val items = ArrayList<DisplaySections>()
fun setItems(items: ArrayList<DisplaySections>) {
this.items.clear()
this.items.addAll(items)
notifyDataSetChanged()
}
fun clear() {
val size: Int = items.size
items.clear()
notifyItemRangeRemoved(0, size)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Base_DisplayViewHolder {
val binding: ItemDisplayBinding =
ItemDisplayBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return Base_DisplayViewHolder(
binding,
listener as Base_DisplayListener,
activityIns,
parent,
liste_display_Recycle_adapter)
}
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: Base_DisplayViewHolder, position: Int) =
holder.bind(items[position])
}
class Base_DisplayViewHolder(
private val itemBinding: ItemDisplayBinding,
private val listener: Adapter_base_Display.Base_DisplayListener,
private val activityIns: FragmentActivity,
private var parent: ViewGroup,
private val items: ArrayList<DisplaySections>,
) : RecyclerView.ViewHolder(itemBinding.root),
View.OnClickListener {
init {
itemBinding.root.setOnClickListener(this)
}
fun bind(item: DisplaySections) {
itemBinding.textView2.text = item.name
}
override fun onClick(v: View?) {
listener.onClickeddisplay(adapterPosition)
}
}
The EditText I want to inflate multiple time
<EditText
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/edittext_isplay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:text="TextView"
android:maxLines="3"
android:textColor="#color/black"
android:textSize="18sp" />
data class DisplaySections(
val id : Int,
val name : String,
val createdAt : String,
val updatedAt : String,
val displayTypeId : Int,
val displayCustomFields : List<DisplayCustomFields> // Contains the elements that will be displayed as EditText
The Base layout-Recycleview Item which is common for all scenarios
<LinearLayout
android:id="#+id/parent_edittext" // ALl EditText container
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:id="#+id/camera_linear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
android:visibility="visible">
<ImageView
android:id="#+id/addphoto"
android:layout_width="316dp"
android:layout_height="250dp"
android:layout_gravity="center"
android:layout_marginTop="#dimen/_20sdp"
android:src="#drawable/ajouter_photo"
app:tint="#color/clear_grey" />
<TextView
android:id="#+id/camera_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Ajouter des photos"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="#+id/plus_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_20sdp"
android:gravity="center"
android:orientation="vertical"
android:visibility="visible">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/my_photo_recycle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>

I going to post the solution I found.
To solve this problem, we absolutely must use a nested RecyclerView;
As I said above, I want to display a list of items with the same common layout (Imageview + Textview), but the tricky part here is the dynamic part of each item.
For recap:
Each element (may or may not) contain N-1 (EditText), it depends on what it gets from a json file.
if you want to solve this problem by creating multiple Viewholder and switch depending on which "ViewHolderType" you are wrong !, you will just create an infinite layout files, it doesn't make sense.
if you create more than one (EditText) and only change the visibility it may work, but if you get for example 100 EditText from the Json file you are not going to manually create 100 Edittext.
if you want to programmatically generate an EditText, you will affect every item in your view Recycle since you cannot create view inside OnbindViewHolder function.
the only way I found to solve this problem is to create a parent-child RecycleView whenever there is an (EditText) you send it to the child adapter and you keep your parent element safe in the parent adapter.
You can also put a condition (NULL tester) inside the Parent-OnbindViewholder whenever there is no data, you just don't call Child-adapter.
I hope this solution will be useful to anyone who has had this problem, and if you have another solution I will be very happy to test them.

Related

How can we create a card stackview in Android using android native stackview?

This is what I created
And what I want is like this below
Actually in here, I want my cards should look like cards in a wallet (as shown in the 2nd image above) which I can scroll like the native stack card view as shown in first image, problem I am facing is I am not able to align cards vertically straight, cards get cut if I try to do so.
I want to achieve this behaviour using Android Native stackview widget only.
My code is as below:
ActivityMain.kt
class MainActivity : AppCompatActivity() {
lateinit var cardAdapter: CardAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val stackView = findViewById<StackView>(R.id.stack_view)
cardAdapter= CardAdapter(numberWord(),numberImage(),R.layout.item_card,this)
stackView.adapter=cardAdapter
}
// the method numberWord() is used to
// add the text below corresponding images.
private fun numberWord(): List<String> {
val word: MutableList<String> = ArrayList()
word.add("One")
word.add("Two")
word.add("Three")
word.add("Four")
word.add("Five")
return word
}
// the method numberWord() is used to call
// the images that are added to the stack.
private fun numberImage(): List<Int>{
val image: MutableList<Int> = ArrayList()
image.add(R.drawable.ic_filter)
image.add(R.drawable.ic_filter)
image.add(R.drawable.ic_filter)
image.add(R.drawable.ic_filter)
image.add(R.drawable.ic_filter)
return image
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<!--We have used RelativeLayout for layout-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<!--Add StackView-->
<StackView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:id="#+id/stack_view"
android:layoutDirection="ltr"
android:layout_width="400dp"
android:layout_height="300dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
CardAdapter.kt
class CardAdapter
(
var numberWord: List<String>,
var numberImage: List<Int>,
var itemLayout: Int,
var c: Context
) : ArrayAdapter<Any?>(
c, itemLayout, numberWord
) {
// getCount() is called to return
// the total number of words to be used
override fun getCount(): Int {
return numberWord.size
}
// getView() is called to get position,
// parent and view of the images.
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var convertView = convertView
if (convertView == null) {
convertView = LayoutInflater.from(parent.context).inflate(itemLayout, parent, false)
}
val word = numberWord[position]
val image = numberImage[position]
val textView = convertView!!.findViewById<TextView>(R.id.text_view)
val imageView = convertView.findViewById<ImageView>(R.id.image_view)
textView.text = word
imageView.setImageResource(image)
return convertView
}
}
item_card.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="180dp"
android:background="#drawable/border_bg"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_filter" />
<TextView
android:id="#+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40sp"
android:textStyle="bold" />
</LinearLayout>
you guys can refer android native stackview: https://developer.android.com/reference/android/widget/StackView
I tried many different solution, I guess we can achieve that with third party library but that's not what I want. I want to create solution with using native android stackview.
Any help will be great.

Android custom expandable/collapsable view with child elements

I am working on a custom expandable view in android.
The goal is that I can add child elements in the xml files and they will be expanded and collapsed when the user clicks the expand/collapse button as on the picture below.
The expananding/collapsing works fine, but I cannot find out how to handle the child views.
In the constructor of my custom view, I inflate an xml layout, and I have a linear layout inside, in which i would like to put the child elements.
I tried using the solution suggested in the answer to the question here.
But I get StackOverflowError, and about a hundres of these:
"at android.view.ViewGroup.resetResolvedLayoutDirection(ViewGroup.java:7207)", even if I try to use the solution in the second aswer, using a while loop instead of the for.
Here is the kotlin class of my view:
class CollapsableCategoryView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
/** Declare some variables */
private var titleString : String = ""
private var subtitleString : String = ""
private var isExpaneded : Boolean = false
/** The required views */
private lateinit var ivIcon : ImageView
private lateinit var llExpandableContent : LinearLayout
init {
/** Receive the attributes */
context.theme.obtainStyledAttributes(
attrs,
R.styleable.CollapsableCategoryView,
0, 0
).apply {
try {
titleString = getString(R.styleable.CollapsableCategoryView_categoryTitle) ?: ""
subtitleString = getString(R.styleable.CollapsableCategoryView_categorySubtitle) ?: ""
} finally {
recycle()
}
}
/** Inflate the layout */
val root : View = View.inflate(context, R.layout.collapsable_task_category, this)
/** Find the views we need*/
ivIcon = root.findViewById(R.id.ivCollapsableCategoryIcon) as ImageView
llExpandableContent = root.findViewById(R.id.llExpandableContent) as LinearLayout
/** onClickListener for the icon */
ivIcon.setOnClickListener {
toggleExpanded()
}
}
override fun onFinishInflate() {
for(i in 0..childCount){
var view : View = getChildAt(i)
removeViewAt(i)
llExpandableContent.addView(view)
}
super.onFinishInflate()
}
/** This method is called when user clicks the expand/collapse button */
fun toggleExpanded(){
isExpaneded = !isExpaneded
if(isExpaneded)
{
ivIcon.setImageResource(R.drawable.ic_collapse)
llExpandableContent.visibility = VISIBLE
}else{
ivIcon.setImageResource(R.drawable.ic_expand)
llExpandableContent.visibility = GONE
}
}
}
I read somewhere else about a different solution, which also doesn't work. That solution suggests to ovverride the addView() method something like this:
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
llExpandableContent.addView(child, params)
}
But if I do so, I get an exception that the lateinint var llExpandableContent is never initialized.
I have also seen solutions that override onMeasure() method but that doesn't seem to be the right approach for me to this problem, since I don't wan't to lay my views out in a special way, just want to add them in a linear layout.
Here is the xml resource file for the layout of the custom view:
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="#dimen/collapsable_category_corner_radius"
android:background="#drawable/bg_collapsable_category_top"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/clCollapsableCategoryMain"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#drawable/bg_collapsable_category_middle">
<ImageView
android:id="#+id/ivCollapsableCategoryIcon"
android:layout_width="38dp"
android:layout_height="38dp"
android:layout_marginStart="8dp"
android:src="#drawable/ic_expand"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/clCollapsableCategoryTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Title"
app:layout_constraintStart_toEndOf="#+id/ivCollapsableCategoryIcon"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/clCollapsableCategorySubtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Subtitle"
app:layout_constraintStart_toEndOf="#+id/ivCollapsableCategoryIcon"
app:layout_constraintTop_toBottomOf="#+id/clCollapsableCategoryTitle" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="#+id/llExpandableContent"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#drawable/bg_collapsable_category_middle"
android:visibility="gone">
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="#dimen/collapsable_category_corner_radius"
android:background="#drawable/bg_collapsable_category_bottom"/>
</LinearLayout>
And here is how I am trying to use my custom view in a layout xml file:
<com.test.test.util.CollapsableCategoryView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Child view 1"/>
</com.test.test.util.CollapsableCategoryView>
Does anyone know how to solve this problem?
Thank you very much in advance for any help. Best regards,
Agoston
So I found the solution at another question, which I cannot find again...
But this solution works like a charm :)
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
if(llExpandableContent == null){
super.addView(child, index, params)
}else{
llExpandableContent?.addView(child, index, params)
}
}
Hope it will help someone else at some point :)

Recyclerview view not populating

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" />

4 clickable views in one Iteme of recyclerView (kotlin)

i want set many buttons (i mean clickable views) in item of recyclerView like every item has download,play,stop,delete how can i do that? if i setOnlickListener like holder.download_image.setOnClickListenr(){} its works for all item i want every item has difrent link for download
class RecyclerAdapter(private val soundList: List<SoundItem>,private val mListener: AdapterView.OnItemClickListener?) :
RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
val itemView =
LayoutInflater.from(parent.context).inflate(R.layout.recycler_view, parent, false)
return RecyclerViewHolder(itemView)
}
override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
val currnetItem = soundList[position]
holder.soundNmae.text = currnetItem.soundName
holder.play_image.setImageResource(currnetItem.playImage)
holder.stop_image.setImageResource(currnetItem.stopImage)
holder.download_image.setImageResource(currnetItem.donloadImage)
holder.delete_image.setImageResource(currnetItem.deleteImage)
}
override fun getItemCount() = soundList.size
class RecyclerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val soundNmae = itemView.soundName
val play_image = itemView.play_image
val stop_image = itemView.stop_image
val download_image = itemView.download_image
val delete_image = itemView.delete_image
}
}
this is acivity for recyclerView im new in kotlin sorry if my question is maybe simple or i couldent say if what is my mean
class RelaxSoundActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_relax_sound)
val exampleList=generatorSoundList(500)
recyceler_view.adapter=RecyclerAdapter(exampleList)
recyceler_view.layoutManager=LinearLayoutManager(this)
recyceler_view.setHasFixedSize(true)
}
fun generatorSoundList(size:Int ):List<SoundItem>{
val list=ArrayList<SoundItem>()
for(i in 0 until size){
val drawable=when(i % 5){
0->R.drawable.ic_play_arrow_black_24dp
1->R.drawable.ic_play_arrow_black_24dp
2->R.drawable.ic_play_arrow_black_24dp
3->R.drawable.ic_play_arrow_black_24dp
else->R.drawable.ic_play_arrow_black_24dp
}
val drawable2=when(i % 5){
0->R.drawable.ic_stop_black_24dp
1->R.drawable.ic_stop_black_24dp
2->R.drawable.ic_stop_black_24dp
3->R.drawable.ic_stop_black_24dp
else->R.drawable.ic_stop_black_24dp
}
val drawable3=when(i % 5){
0->R.drawable.ic_file_download_black_24dp
1->R.drawable.ic_file_download_black_24dp
2->R.drawable.ic_file_download_black_24dp
3->R.drawable.ic_file_download_black_24dp
else->R.drawable.ic_file_download_black_24dp
}
val drawable4=when(i % 5){
0->R.drawable.ic_delete_black_24dp
1->R.drawable.ic_delete_black_24dp
2->R.drawable.ic_delete_black_24dp
3->R.drawable.ic_delete_black_24dp
else->R.drawable.ic_delete_black_24dp
}
val item=SoundItem("item $i" ,drawable,drawable2,drawable3,drawable4)
list+=item
}
return list
}
}
and recycler_view.xml file is here
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.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"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="8dp"
>
<TextView
android:id="#+id/soundName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView"
android:textSize="20dp"/>
<ImageView
android:id="#+id/play_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="#drawable/ic_play_arrow_black_24dp" />
<ImageView
android:id="#+id/stop_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="#drawable/ic_stop_black_24dp" />
<ImageView
android:id="#+id/download_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="#drawable/ic_file_download_black_24dp" />
<ImageView
android:id="#+id/delete_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="#drawable/ic_delete_black_24dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
you can do it in multiple ways. You can add click listeners on your views and directly perform the operation in your adapter or you can transfer function in your recycler view holder class.
So for short cut I can just give you the way that you can understand the process.
In you adapter onBindViewHolder you can add
holder.download_image.setOnCLickListener{
val downloadLink = currnetItem.getDownloadLink()
// Download task start by this download link
}
So this one click listener on download image will be effected on each item and perform separately.
IMO you have to attach an clicklistener to each button, and then you could either make a callback to the adapter/activity and handle it from there on.
If you yous the View.OnClickListener, then you always have the clicked view. From there on, it is just a matter of writing a switch statement, where you can determine via the id of the clicked view, which action was selected.
If you need extra data, you could just add a tag to the view, and pass it via the clickListener.

RecyclerView wont display image but displays text

I am making a RecyclerView with Kotlin that will display an image and text. So far the text should be just "Textview" and the image should be one of the images that come with android. The text displays "Textview" the specified number of times but doesn't show the image at all.
I am actually following [this video](https://www.youtube.com/watch?v=jS0buQyfJfs&list=PL0dzCUj1L5JGfHj1lwxOq67zAJV3e1S9S&index=2&t=409s! exactly and run into the problem.
I have changed the cell layout of the image to wrap content and it did not help.
Adapter
class MainAdapter : RecyclerView.Adapter<CustomViewHolder>() {
val vidTitles = listOf("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
override fun getItemCount(): Int {
return vidTitles.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
//create the view for the rows
val layoutInflater = LayoutInflater.from(parent.context)
val cellForRow = layoutInflater.inflate(R.layout.video_row, parent, false)
return CustomViewHolder(cellForRow)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
holder?.view?.videoTitleTextView?.text= vidTitles[position]
}
}
class CustomViewHolder(val view: View): RecyclerView.ViewHolder(view) {
}
RecyclerView's Cell layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:contentDescription="avatar image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/videoTitleTextView"
android:layout_width="0dp"
android:layout_height="31dp"
android:text="animals"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
Main Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//recyclerView_main.setBackgroundColor(Color.CYAN)
recyclerView_main.layoutManager = LinearLayoutManager(this)
recyclerView_main.adapter = MainAdapter()
}
}
I expect it to show both the image and the text; It shows the text but not any image and it doesn't even leave any space for the image.
Change Your Image View as below.
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:contentDescription="avatar image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="#mipmap/ic_launcher" />
You are using tools:srcCompat which is wrong.
Also Change height of Constraint Layout to wrap_content. Otherwise each item in a Recyclerview is going to take full height of screen.
Tools namespace is used for Compile time behaviour. When you build the app this tools features is removed. Its helps you to preview your view at compile time.
Replace this
tools:srcCompat="#mipmap/ic_launcher"
with this:
android:src="#mipmap/ic_launcher"
Note: Here tools:srcCompat will show only in the preview of Android studio but not in the real device.
For more info check here
When I read your code right, you should see "animals" in your TextViews only :)
This is because in your cell's layout file you set the android:text and not the tools:text attribute.
Just implement your ViewHolder and bind the Views to your model.
If you want only to verify your Views are loaded, you could replace the
tools:srcCompat="#mipmap/ic_launcher"
to
app:srcCompat="#mipmap/ic_launcher"

Categories

Resources