Как RecyclerView моей библиотеки позволяет своим клиентам настраивать отображение строк? - PullRequest
1 голос
/ 23 февраля 2020

Допустим, я создал библиотеку android, которая экспортирует фрагмент, отображающий заметки в RecyclerView. Эта библиотека имеет собственную реализацию макета по умолчанию для визуализации заметок в RecyclerView, но она хочет, чтобы любые клиенты, использующие ее, могли настраивать способ визуализации заметок.

Есть ли способ сделать это? Чтобы как-то создать метод, который клиенты могут вызывать, который имеет объект Note в качестве параметра и говорит клиенту вернуть представление, которое они хотят отобразить? Если да, то как он будет работать / вызываться в отношении Адаптера?

Извиняюсь, что в этом посте мало подробностей, но я не знаю, что еще сделать вывод. Если есть какие-либо дополнительные вопросы, я был бы рад ответить

1 Ответ

0 голосов
/ 23 февраля 2020

Вы можете позволить пользователю установить пользовательский адаптер для экземпляра фрагмента, добавив метод setAdapter к вашему фрагменту.

Или вы можете создать дополнительный обратный вызов, который позволяет пользователям настраивать создание держателей представления заметок. Вот пример:

class NoteFragment : Fragment(), NoteAdapter {

    private val notes = mutableListOf<Note>()

    // This is used to resolve the note adapter from the calling activity or fragment,
    // or if none is found, use the default note adapter.
    private val noteAdapter: NoteAdapter
        get() = (parentFragment as? NoteAdapter)
            ?: (targetFragment as? NoteAdapter)
            ?: (activity as? NoteAdapter)
            ?: this

    // This method provides the default view holder used for note items.
    override fun createNoteViewHolder(inflater: LayoutInflater, parent: ViewGroup) =
        DefaultNoteViewHolder(inflater.inflate(R.layout.default_note_view, parent, false))

    abstract class NoteViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        /** In this method, the view holder views should be bound with the information of the [note]. */
        abstract fun bind(note: Note)
    }

    private inner class Adapter : RecyclerView.Adapter<NoteViewHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder {
            val inflater = LayoutInflater.from(parent.context)
            return noteAdapter.createNoteViewHolder(inflater, parent)
        }

        override fun onBindViewHolder(holder: NoteViewHolder, pos: Int) {
            holder.bind(notes[pos])
        }

        override fun getItemCount() = notes.size
    }

    class DefaultNoteViewHolder(itemView: View) : NoteViewHolder(itemView) {
        override fun bind(note: Note) {
            // Default view binding
        }
    }
}

/** Interface to be implemented by the calling activity or fragment. */
interface NoteAdapter {
    fun createNoteViewHolder(inflater: LayoutInflater, parent: ViewGroup): MyFragment.NoteViewHolder
}

data class Note(val message: String)

Фрагмент сначала пытается найти NoteAdapter из вызывающего действия или фрагмента, затем, если он терпит неудачу, он использует реализацию по умолчанию, которая обеспечивается самим фрагментом, так как он реализует интерфейс NoteAdapter.

Вот как пользователь, использующий фрагмент из действия, может настроить привязку элемента заметки:

class MyActivity : AppCompatActivity(), NoteAdapter {

    // ...

    override fun createNoteViewHolder(inflater: LayoutInflater, parent: ViewGroup)
        = CustomNoteViewHolder(inflater.inflate(R.layout.custom_note_view, parent, false))

    class CustomNoteViewHolder(itemView: View) : NoteViewHolder(itemView) {
        override fun bind(note: Note) {
            // Custom view binding behavior
        }
    }
}

Преимущество этого подхода состоит в том, что если фрагмент и, например, действие будет воссоздано при изменении конфигурации, фрагмент все равно сможет разрешить адаптер в вызывающем действии без необходимости что-либо делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...