wbk727
wbk727

Reputation: 8408

Correct context to use in RecyclerView adapter

Which context should I be using when I use a SharedPreference within a RecyclerView adapter? This is confusing as when during the default one, context in val mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) appears as an unresolved reference.

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
    }
}

In fragment

myTV must not be null

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)
    }
}

Upvotes: 0

Views: 231

Answers (2)

B. Pl&#252;ster
B. Pl&#252;ster

Reputation: 654

Shared Preferences is used for persisting data and isn't entirely suitable for use within a RecyclerView as its operations can slow down the application. See the developer documentation for more info on why it shouldn't necessarily be used in this way and where it is best applied.

In your case, it may be preferable to retrieve the data from SharedPreferences at some point prior to the initialization of your Adapter and pass it during initialization.

Assuming performance is not critical, you can continue doing it as before and simply retrieve a context from one of your views with viewHolder.itemView.context. You could also pass a context reference from your activity to the adapter.

Upvotes: 1

Ryan M
Ryan M

Reputation: 20167

Any Context is fine. Your context reference is unresolved because you don't have a variable or property by that name, as you would from within a View or Activity. The most convenient way to get one in onBindViewHolder would be viewHolder.itemView.context (or viewHolder.itemView.getContext() from Java).

Upvotes: 1

Related Questions