Сохранение и восстановление состояния прокрутки FirebaseUI RecyclerView - PullRequest
0 голосов
/ 06 февраля 2020

Я новичок в разработке, в основном программирую, и пытаюсь научиться, создав приложение в Kotlin. У меня запущены некоторые базовые функции c, но у меня возникают проблемы при попытке заставить RecyclerView сохранять позицию прокрутки при возврате из других действий. Я искал и пробовал разные методы, но, вероятно, из-за отсутствия опыта я не могу заставить их работать. У меня есть один метод, который выглядит многообещающе, но я не знаю, как и где разместить предоставленный код.

Метод, который я пытаюсь применить

class MainActivity : AppCompatActivity() {
    private val db = FirebaseFirestore.getInstance()
    private val notebookRef = db.collection("Notebook")
    private lateinit var adapter: NoteAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val buttonAddNote =
            findViewById<FloatingActionButton>(R.id.button_add_note)
        buttonAddNote.setOnClickListener {
            startActivity(
                Intent(
                    this@MainActivity,
                    NewNoteActivity::class.java
                )
            )
        }
        setUpRecyclerView()
    }

    private fun setUpRecyclerView() {
        val query: Query = notebookRef.orderBy("priority", Query.Direction.DESCENDING)
        val options = FirestoreRecyclerOptions.Builder<Note>()
            .setQuery(query, Note::class.java)
            .build()
        adapter = NoteAdapter(options)
        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
        recyclerView.setHasFixedSize(true)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter
    }

    override fun onStart() {
        super.onStart()
        adapter.startListening()
    }

    override fun onStop() {
        super.onStop()
        adapter.stopListening()
    }
}
class Note {
    var title: String? = null
        private set
    var priority = 0
        private set

    constructor() { //empty constructor needed
    }

    constructor(title: String?, priority: Int) {
        this.title = title
        this.priority = priority
    }
}
class NoteAdapter(options: FirestoreRecyclerOptions<Note>) :
    FirestoreRecyclerAdapter<Note, NoteAdapter.NoteHolder>(options) {

    override fun onBindViewHolder(
        holder: NoteHolder,
        position: Int,
        model: Note
    ) {
        holder.textViewTitle.text = model.title
        holder.textViewPriority.text = model.priority.toString()
    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): NoteHolder {
        val v: View = LayoutInflater.from(parent.context).inflate(
            R.layout.note_item,
            parent, false
        )
        return NoteHolder(v)
    }

    inner class NoteHolder(itemView: View) :
        ViewHolder(itemView) {
        var textViewTitle: TextView = itemView.findViewById(R.id.text_view_title)
        var textViewPriority: TextView = itemView.findViewById(R.id.text_view_priority)
    }
}

Также RecyclerView, по-видимому, перезагружается после возвращения из действия, которое, я надеюсь, вышеописанный метод также исправит. Я пробовал "singleTop", но это, похоже, не работает.

AndroidManifest. xml:

    <activity
            android:name=".MainActivity"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".NewNoteActivity"
            android:parentActivityName=".MainActivity" />

Помощь по любой очистке кода также очень ценится.

1 Ответ

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

Я не читаю вашу огромную реализацию кода, но могу сказать несколько важных вещей о RecyclerView.

RecyclerView состоит из 5 участников:

  • RecyclerView в вашем макете
  • ViewHolder (каждый просмотр, который вам нужно повторить)
  • Сбор данных
  • LayoutManager (3 популярных реализации: Линейный - Сетка - В шахматном порядке)
  • Адаптер ( Установите все отдельные данные из коллекции с каждым viewHolder)

Вы должны только инициализировать 1 раз: Адаптер RecyclerView LayoutManager

Таким образом, в onCreate вашей Деятельности / Фрагмента вы инициируете Recycler, LayoutManager и адаптер.

После этого вам нужно только позаботиться о том, чтобы передать коллекцию обновлений в адаптер. Восстановление View, видимая последняя позиция, операция по утилизации ... Является ли RecyclerView внутренней реализацией, не беспокойтесь об этом поведении.

Как сохранить в сценарии реконструкции данные сбора? В saveInstanceState?

Если у вас нет этой реализации, при восстановлении действия / фрагмента вы получаете новые данные коллекции, эту коллекцию, которую вы передали в RecyclerView, и этот парень считает, что это те же данные или они новые? Если нужны новые данные, мне нужно показать первую позицию, если нет, мне нужно показать последнюю позицию.

Итак, вы сохраняете данные своей коллекции?

...