-1

I have data from RickandMorty Api and saving them on CharacterList and I am showing them in a recyclerview.I have name,location and status informations and showing them in cards.I have another carditem for displaying dead users and I want to show Alive persons in default card and Dead persons in another carditem (Default Carditem with blue backgroundcolor and other carditem is with red backgroundcolor).So as my researches people handle that with getItemViewType() but in my case I want to classify them each object's status type which is Alive or Dead.How can I do it?

Here is my Main Activity class

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    viewModel = ViewModelProviders.of(this).get(CharacterViewModel::class.java)

    CoroutineScope(Dispatchers.IO).launch {
        viewModel.getData()
    }

    viewModel.users.observe(this, Observer { characterList ->
        for (i in characterList.results){
            Log.e(TAG, "${i.name}")
            name_list.add(i.name)
        }
        recyclerview1.layoutManager = LinearLayoutManager(this)
        recyclerview1.adapter = Adapter(characterList.results)


    })


}}

Here is my ViewHolder Class

class ViewHolder (container: ViewGroup) : RecyclerView.ViewHolder(
        //xml deki verilere bakarak arayüz viewvi oluşturuyor
        LayoutInflater.from(container.context).inflate
            (
            R.layout.carditem,
            container,
            false
        )
    ) {
    val crdView: CardView = itemView.findViewById(R.id.cardview1)
    val profileLink: ImageView = itemView.findViewById(R.id.imgProfilePhoto)
    val txtname: TextView = itemView.findViewById(R.id.name)
    val txtlocation: TextView = itemView.findViewById(R.id.location)
    val txtstatus: TextView = itemView.findViewById(R.id.status)


    fun bind(characteritem: Result) {
        txtname.text = characteritem.name
        profileLink.load(characteritem.image)
        txtlocation.text = characteritem.location.name
        txtstatus.text=characteritem.status
    }
}

And my Adapter class

class Adapter(val CharacterList: List<Result>):RecyclerView.Adapter<ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(parent)
    }

    override fun getItemCount(): Int {
        return CharacterList.size
    }

    override fun onBindViewHolder(holder: ViewHolder,position: Int) {
            holder.bind(CharacterList[position])

    }


}

Here is what I've done

And what I am trying to make

The view of Cards

CSS
  • 3
  • 5
  • Have a look at the example [here](https://stackoverflow.com/a/72994172/9473786), although if all you want is to change some text and background color you should just do that with the same view layout in the bind method – Tyler V Jul 19 '22 at 13:58
  • I checked it but still couldn't understand how to use it.In the example there are some class and which function belongs to which class and how to use it, I couldn't understand how to implement to my project.Even I try to override that function in Viewholder class I got the error. – CSS Jul 19 '22 at 14:19
  • What are you referring to with "that function"? `getItemViewType`? That goes in the adapter, not the view holder – Tyler V Jul 19 '22 at 14:21
  • Okey I supposed it is in the ViewHolder – CSS Jul 19 '22 at 14:30

2 Answers2

0

If your different layouts have the same resources, just with different appearance you could just pass an alternate layout ID to your view holder, like this:

class Adapter(val CharacterList: List<Result>):RecyclerView.Adapter<ViewHolder>() {

    override fun getItemViewType(position: Int): Int {
        return if (CharacterList[position].status == "Dead") 0 else 1
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val layout = if(viewType == 0) R.layout.card_dead else R.layout.card_alive
        return ViewHolder(parent, layout)
    }

    override fun getItemCount(): Int {
        return CharacterList.size
    }

    override fun onBindViewHolder(holder: ViewHolder,position: Int) {
        holder.bind(CharacterList[position])
    }
}

Then modify the view holder to take the layout ID as a constructor input:

class ViewHolder (container: ViewGroup, layout: Int) : RecyclerView.ViewHolder(
    LayoutInflater.from(container.context).inflate
        (
            layout,
            container,
            false
        )
    ) 
{
    //...
}

Alternately you could just use a single layout and change the background color programmatically in bind

Tyler V
  • 9,694
  • 3
  • 26
  • 52
  • I tried that but all of them convert to blue or red.I mean it is still same. – CSS Jul 19 '22 at 14:41
  • Show what you tried (adapter and view holder code) - this works. Are you sure you made all the changes I listed here? – Tyler V Jul 19 '22 at 14:49
  • Yeah I treid I changed the codes you have given.Only CharacterList[position].isDead is different cause I use it like CharacterList[position].equals("Alive") but other things are same. – CSS Jul 19 '22 at 15:00
  • That looks wrong, you are comparing the character object to "Alive", not an attribute of the class. How is the `Result` class defined? – Tyler V Jul 19 '22 at 15:01
  • Yeah but can't I compare it with that way? – CSS Jul 19 '22 at 15:04
  • Does your Result class have some attribute that indicates if it is alive? – Tyler V Jul 19 '22 at 15:04
  • No It is like this for each character https://rickandmortyapi.com/api/character/814 – CSS Jul 19 '22 at 15:06
  • Try `CharacterList[position].status == "Dead"`. It looks like the status field indicates if they are dead. If your Result class doesn't have a status field, you need to add it so it can populate it from the json – Tyler V Jul 19 '22 at 15:07
  • Also, if you want to test that the layout stuff works you could use something like `return if(position>3) 0 else 1` in `getItemViewType`. It should make some red and some blue – Tyler V Jul 19 '22 at 15:12
  • Okey i will try it when i arrive to home from internship.And Thanks for help – CSS Jul 19 '22 at 15:13
  • CharacterList[position].status == "Dead" is worked.But I tried that before .contains.It wouldn't work firstly but now it worked I couldn't understand why it didn't work.Anyways Thanks for help I really get what I need. – CSS Jul 20 '22 at 06:11
  • Probably I was trying to equals instead contains.I was really tired yesterday so I couldn't notice what i did. – CSS Jul 20 '22 at 06:23
-1

In your adapter, override getItemViewType like this.

@Override
fun getItemViewType(position:Integer):Integer {
    return if (CharacterList[position].isDead) 0 else 1
}

Then in the onCreateViewHolder check the viewType to know if you need to create a view for 'alive' or 'dead'.

eimmer
  • 1,537
  • 1
  • 10
  • 29