1

I wanted to change font family of items on a recycler view every time I click a button. So I coded like below.

rbAritaBuri = view.findViewById(R.id.rb_aritaBuri)
rbCafe24 = view.findViewById(R.id.rb_cafe24SurroundAir)

rbAritaBuri.setOnClickListener {
            rv_work_preview.tv_work_content.typeface = Typeface.createFromAsset(requireActivity().assets, "fonts/arita_buri.otf")
        }

rbCafe24.setOnClickListener {
            rv_work_preview.tv_work_content.typeface = Typeface.createFromAsset(requireActivity().assets, "fonts/cafe24_surround_air.ttf")
        }

But it changes only the font family of the first item of the recycler view. Is there a way to change fonts of them all together runtime? And please tell me why the code I wrote doesn't work right. Thank you.

sejigner
  • 35
  • 6

2 Answers2

1

If I were in your position, I would:

  1. Put your font changing calls inside of onBindViewHolder(). If you have to, you could put a bool in there like buttonClicked and link its value to your buttons.

  2. Come up with a good way to force a call to onBindViewHolder(). Sometimes notifyDataSetChanged() is enough. But in some cases, you might have to remove the adapter by setting it to null and then reset the adapter to its original value.

  3. Place that logic from step 2 inside of your buttons' onClick()s.

Edit:

What I mean is, create a var inside the class with the most exterior scope, so outside of oncreate().

var textChoice=""

Now use your buttons to change that var.

rbAritaBuri.setOnClickListener {
 textChoice="fonts/arita_buri.otf"
        }

Now inside your onBindViewHolder(), make the font switch.

when (fontChoice){
   "fonts/arita_buri.otf"->{ rv_work_preview.tv_work_content.typeface = Typeface.createFromAsset(requireActivity().assets, "fonts/arita_buri.otf")}
//and so on and so forth for all of your fonts

Now when you want to show the change, call notifyDatasetChanged(). I think maybe the best place to do that would be inside of your buttons. So maybe you'd actually have:

rbAritaBuri.setOnClickListener {
 textChoice="fonts/arita_buri.otf"
 <The name of your recyclerview adapter>.notifyDatasetChanged()
        }
D. Kupra
  • 343
  • 1
  • 9
  • Sorry for responding late. Could you please write the code to put inside of onBindViewHolder()? – sejigner Sep 14 '21 at 09:03
  • How can you pass fontChoice to onBindViewHolder? I'm a beginner, so I would really appreciate if you could give me a little bit more details! – sejigner Sep 16 '21 at 04:16
1

Here is how I solved it, thanks to D. Kupra:

class SampleWorkAdapter(private val context: Context) :
    RecyclerView.Adapter<SampleWorkAdapter.ViewHolder>() {
var selectedFont = EditTextActivity.HAMBAK_SNOW

First, I assigned the default font Hambak_snow to selectedFont, type String.

inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

...

        fun changeFont(font: String) {
            CustomFontHelper.setCustomFont(content, font, itemView.context)
        } ...
    }

Then I wrote a function to be called on onBindViewHolder to change font-family of textview, using custom typeface. https://stackoverflow.com/a/16648457/15096801 This post helped a lot.

override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
...
        viewHolder.changeFont(selectedFont)
...
    }

Now, replaceFont will be called when the variable selectedFont get changed and adapter.notifyDatasetChanged() is called on an activity, like this:

rbMapoFlowerIsland.setOnClickListener {
            sampleWorkAdapter.selectedFont = EditTextActivity.MAPO_FLOWER
            sampleWorkAdapter.notifyDataSetChanged()
        }
ouflak
  • 2,458
  • 10
  • 44
  • 49
sejigner
  • 35
  • 6