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

时间:2018-12-14 20:43:27

标签: android kotlin android-cardview android-gridview cardview

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

AdapterItem中的

adapter.addAdapterItem(MyFragment.AdapterItem(primeNumber))返回此错误:

  

内部类AdapterItem的构造方法只能由包含类的接收者调用

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

1 个答案:

答案 0 :(得分:2)

更改

adapter.addAdapterItem(MyFragment.AdapterItem(primeNumber))

adapter.addAdapterItem(AdapterItem(primeNumber))

或者是长格式

adapter.addAdapterItem(this.AdapterItem(primeNumber))

因为这种方式,它试图通过this.AdapterItem使用内部访问,该访问将自身用作外部类,而您的语法则强制它使用外部静态方式而不使用外部类。

据我所知,您也可以完全从您的代码中删除inner,因为您不能从内部访问外部类,而inner才允许这样做。