为 GridView 创建适配器时内部 class 构造函数问题

Inner class constructor issue when creating adapter for GridView

我正在尝试以编程方式将一些项目添加到 GridView 中,但它不起作用。我已经看到有关此错误的类似问题的答案,但我不确定在这种情况下应该做什么。创建外部 class 或其他东西?

AdapterItemadapter.addAdapterItem(MyFragment.AdapterItem(primeNumber)) returns 这个错误:

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

网格视图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)
    }
}

改变

adapter.addAdapterItem(MyFragment.AdapterItem(primeNumber))

adapter.addAdapterItem(AdapterItem(primeNumber))

或者长格式

adapter.addAdapterItem(this.AdapterItem(primeNumber))

因为这样它试图通过 this.AdapterItem 使用内部访问,它使用自己作为外部 class 而你的语法强制它使用没有外部 class 的外部静态方式.

您也可以完全从您的代码中删除 inner - 据我所知 - 因为您不会从内部访问外部 class 而这就是 inner允许。