Правильный контекст для использования в адаптере RecyclerView - PullRequest
0 голосов
/ 11 февраля 2020

Какой context я должен использовать, когда использую SharedPreference в RecyclerView адаптере? Это сбивает с толку, когда во время настройки по умолчанию context в val mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) отображается как неразрешенная ссылка.

class MyRVAdapter(private val myString: ArrayList<String>): RecyclerView.Adapter<MyRVAdapter.MyViewHolder>() {
    private val typeA = 1
    private val typeB = 2

    override fun onCreateViewHolder(parent: ViewGroup, type: Int): MyViewHolder {
        return when (type) {
            typeA -> MyViewHolder(inflateHelper(R.layout.rv_type_a, parent))
            typeB -> MyViewHolder(inflateHelper(R.layout.rv_type_b, parent))
            else -> MyViewHolder(inflateHelper(R.layout.rv_type_a, parent))
        }
    }

    override fun onBindViewHolder(viewHolder: MyViewHolder, position: Int) {
        if (getItemViewType(position) == typeA) {
            // Check preference (what's the correct context?)
            val mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
            valueDestinationExpanded = mSharedPreferences.getBoolean("my_preference", true)
        }
        else if (getItemViewType(position) == typeB) {
        }
    }

    private fun inflateHelper(resId: Int, parent: ViewGroup): View {
        return LayoutInflater.from(parent.context).inflate(resId, parent, false)
    }

    override fun getItemViewType(position: Int): Int {
        return if (position == 0) typeA
        else typeB
    }
}

Во фрагменте

myTV не должно быть нулевым

class MyFragment : androidx.fragment.app.Fragment() {
    private lateinit var mRecyclerView: RecyclerView
    private var valueShowTextView: Boolean = false

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.my_rv, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        val v = view
        val myTV = my_tv

        mRecyclerView = v.mRecyclerViewSansToolbar

        mRecyclerView.layoutManager = LinearLayoutManager(activity)

        val mAdapter = MyRVAdapter(dataTVtext!!)

        val mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
        valueDestinationExpanded = mSharedPreferences.getBoolean("preference_DestinationExpand", true)

        if (valueShowTextView) {
            myTV.visibility = View.VISIBLE
        } else {
            myTV.visibility = View.GONE
        }

        mRecyclerView.adapter = mAdapter

        super.onActivityCreated(savedInstanceState)
    }
}

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Shared Preferences используется для сохранения данных и не совсем подходит для использования в RecyclerView, поскольку его операции могут замедлять работу приложения. См. документацию для разработчиков для получения дополнительной информации о том, почему его не обязательно использовать таким образом и где его лучше всего применять.

В вашем случае может быть предпочтительнее извлечь данные из SharedPreferences в какой-то момент до инициализации вашего адаптера и передать их во время инициализации.

Предполагая, что производительность не критична, вы можете продолжать делать это, как и раньше, и просто извлечь контекст из одного из ваших представлений с помощью viewHolder.itemView.context. Вы также можете передать контекстную ссылку из вашей деятельности в адаптер.

1 голос
/ 11 февраля 2020

Любой Context в порядке. Ваша ссылка context не разрешена, поскольку у вас нет переменной или свойства с таким именем, как если бы вы находились внутри View или Activity. Наиболее удобный способ получить единицу в onBindViewHolder будет viewHolder.itemView.context (или viewHolder.itemView.getContext() из Java).

...