Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Como setar uma margem especifica no primeiro item da recyclerview

Galera,

Vamos supor que no primeiro item da recyclerview a margin top seja de 16dp, e nas demais fosse 8dp. Como a gente faria pra setar esse valor?

class ListaProdutosAdapter(
    private val context: Context,
    private val produto: List<Produto>
) : RecyclerView.Adapter<ListaProdutosAdapter.viewHolder>() {

    class viewHolder(view: View) : RecyclerView.ViewHolder(view) {
        fun vincula(produto: Produto) {
            val imagem = itemView.findViewById<ImageView>(R.id.img_preview)
            imagem.setBackgroundResource(produto.img)
            val nome = itemView.findViewById<TextView>(R.id.nome)
            nome.text = produto.nome.replaceFirstChar(Char::titlecase)
            val descricao = itemView.findViewById<TextView>(R.id.descricao)
            descricao.text = produto.descricao.replaceFirstChar(Char::titlecase)
            val valor = itemView.findViewById<TextView>(R.id.valor)
            valor.text = produto.valor.toPlainString()
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): viewHolder {
        val inflater = LayoutInflater.from(context)
        val view = inflater.inflate(R.layout.produto_item, parent, false)
        return viewHolder(view)
    }

    override fun onBindViewHolder(holder: viewHolder, position: Int) {
        val produto = produto[position]
        holder.vincula(produto)
    }

    override fun getItemCount(): Int = produto.size

}
1 resposta
solução!

Olá Thailan, tudo bem?

Essa é uma pergunta muito boa, antes de tudo, precisaríamos criar uma variável que nos permitisse acessar os parâmetros do layout, basta criar ela dentro do próprio método onBindViewHolder pois só vamos usá-la lá dentro:

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
.
.
.
        val params = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
        )

    }

Agora teriamos de criar uma condicional dentro de onBindViewHolder pois é lá que podemos fazer esse tratamento com a posição do item, em seguida adicionariamos uma topMargin e ao final passariamos essa variável params que são os parâmetros escolhidos por nós para essa View específica de posição 0:

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val produto = produtos[position]
        holder.vincula(produto)
        val params = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
        )

//          Fiz uma condicional para o item de posição 0 (o primeiro item do recyclerview)
        if (position == 0) {
            params.topMargin = 20
            holder.itemView.layoutParams = params
        }

    }

Porém, este metodo apresenta um problema, pois o valor passado para o params.topMargin = 20 seria em pixels e como vimos ao decorrer do curso, o recomendado seria utilizamos o DP e para solucionar esse problema eu criei uma função, onde o parâmetro é um float que representa o valor em DP da margin que você deseja, essa função vai retornar o valor em pixels dependendo da tela que ela está rodando. O Código completo do onBindViewHolder ficaria desse jeito:

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val produto = produtos[position]
        holder.vincula(produto)
        val params = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
        )

//        Variável para armazenar a altura do marginTop de 16DP
        val altura = converterDP(16f)

//          Fiz uma condicional para o item de posição 0 (o primeiro item do recyclerview)
        if (position == 0) {
            params.topMargin = altura
            holder.itemView.layoutParams = params
        }

    }

//    Função de conversão de DP para PX
    private fun converterDP(dpDesejada : Float): Int {
        val r: Resources = context.resources
        val px = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dpDesejada,
            r.displayMetrics,
        )
        return px.toInt()
    }

Vale lembrar de que como só pretende alterar o valor do primeiro, deixe o padrão de margin no XML como 8dp isso vai fazer com que você obtenha o resultado esperado.

Qualquer dúvida referente a esse implementação estarei a disposição para esclarecer, pois é um processo relativamente complexo.

Forte abraço e bons estudos !!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!