I'm trying to add some items into a GridView programmatically but it's not working. I have seen answers for similar questions about this error, but I'm not sure of what should be done in this scenario. Creating an outer class or something else?
AdapterItem
in adapter.addAdapterItem(MyFragment.AdapterItem(primeNumber))
returns this error:
Constructor of inner class AdapterItem can be called only with receiver of containing class
class MyFragment : androidx.fragment.app.Fragment() {
private val primeNumbers = arrayOf("2", "3", "5", "7", "11", "13", "17", "19", "23", "29")
private lateinit var adapter: MyAdapter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_linearlayout, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
val v = view
val mainLinearLayout = v!!.findViewById(R.id.my_linearLayout) as LinearLayout
val cardLinearLayout = LinearLayout(context)
cardLinearLayout.orientation = LinearLayout.VERTICAL
val cardView = context?.let { CardView(it) }
when {
cardView != null -> {
cardView.radius = twoDp.toFloat()
cardView.setContentPadding(36,36,36,36)
cardView.layoutParams = params
cardView.cardElevation = twoDp.toFloat()
}
}
val mTitle = TextView(context)
mTitle.text = "Prime numbers"
TextViewCompat.setTextAppearance(mTitle, android.R.style.TextAppearance_Large)
val mGridView = com.companyname.appname.MyGridView(context!!)
mGridView.columnWidth = 100f
mGridView.run {
numColumns = GridView.AUTO_FIT
stretchMode = GridView.STRETCH_COLUMN_WIDTH
}
adapter = MyAdapter(activity!!.applicationContext, 0)
mGridView.adapter = adapter
for (primeNumber in primeNumbers) {
adapter.addAdapterItem(MyFragment.AdapterItem(primeNumber))
}
cardLinearLayout.addView(mTitle)
cardLinearLayout.addView(mGridView)
cardView!!.addView(cardLinearLayout)
mainLinearLayout.addView(cardView)
super.onActivityCreated(savedInstanceState)
}
private inner class MyAdapter internal constructor(context: Context, textviewid: Int) : ArrayAdapter<AdapterItem>(context, textviewid) {
private val items = ArrayList<AdapterItem>()
internal fun addAdapterItem(item: MyFragment.AdapterItem) {
items.add(item)
}
override fun getCount(): Int {
return items.size
}
override fun getItem(position: Int): MyFragment.AdapterItem? {
return items[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
@NonNull
override fun getView(position: Int, convertView: View?, @NonNull parent: ViewGroup): View {
val rowView: View = when (convertView) {
null -> activity!!.layoutInflater.inflate(R.layout.gridview_item, parent, false)
else -> convertView
}
val tv = rowView.findViewById(R.id.item_gridview) as TextView
tv.text = items[position].first
return rowView
}
}
internal inner class AdapterItem // add more items
(var first: String)
}
GridView class
class MyGridView : GridView {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val heightSpec: Int = when {
layoutParams.height == AbsListView.LayoutParams.WRAP_CONTENT -> View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE shr 2, View.MeasureSpec.AT_MOST)
else -> heightMeasureSpec
}
super.onMeasure(widthMeasureSpec, heightSpec)
}
}
change
adapter.addAdapterItem(MyFragment.AdapterItem(primeNumber))
to
adapter.addAdapterItem(AdapterItem(primeNumber))
or it's long form
adapter.addAdapterItem(this.AdapterItem(primeNumber))
because that way it's trying to use the internal access via this.AdapterItem
which uses itself as outer class while your syntax forces it to use the external static way without an outer class.
You could also just drop inner
from your code entirely - as far as I see - since you don't access the outer class from the inner and that's what inner
allows.