为什么我的自定义视图RecyclerView项目“不可见”

时间:2019-05-13 20:14:36

标签: android kotlin android-recyclerview view android-custom-view

我需要onDraw的物品RecyclerView。使用this SO link处“发现”的方法,我已经-嗯-在那儿。

请注意,我最终希望onDraw在自定义视图上方。含义是调用super以使默认绘图生效,然后在视图的paint的未使用区域上canvas

在开始执行“允许onDraw的自定义视图之前,我在下面的中看到了以下内容:

enter image description here enter image description here enter image description here

之后,我拥有所有“不可见”的视图(上面的中间图像)。我说“不可见”是因为它们仍然可以单击。为了帮助我可视化事物(以及一些onDraw概念验证),我在自定义onDraw视图中覆盖了PuzzleView,只需调用canvas.drawRect即可覆盖绿色的整个画布,现在看到上方的图片。

我不确定我在做什么错。

ALSO:如果发生这种情况,那么,为什么我不简单地onDraw整个事情……由于种种原因,这是不实际的。

所以,这是我现在的 PuzzleAdapter

class PuzzleAdapter(private val puzzles: List<Puzzle>) : RecyclerView.Adapter<PuzzleAdapter.PuzzleHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PuzzleAdapter.PuzzleHolder {
        //val v = LayoutInflater.from(parent.context).inflate(R.layout.item_puzzle, parent, false)
        //not inflating, creating PuzzleView (which is inflating itself)
        val v = PuzzleView(parent.context)
        v.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        return PuzzleHolder(v)
    }

    override fun getItemCount() = puzzles.size

    //unchanged between these two versions
    override fun onBindViewHolder(h: PuzzleAdapter.PuzzleHolder, pos: Int) {
        val p = puzzles[pos]
        h.view.puzzleItem_text_ndx.text = "# " + p.descr()
        h.view.puzzleItem_text_details.text = "Ndx: ${p.puzzleNdx}"
        h.view.setOnClickListener {
            Log.d("##", "PuzzleHolder.onClick (bunch#${p.parentBunch.bunchID}; puzzle#${p.puzzleNdx})")
            val action = BunchFragmentDirections.navBunchToPuzzle(PuzzleParcel(p.parentBunch.bunchID, p.puzzleNdx))
            it.findNavController().navigate(action)
        }
    }

    inner class PuzzleHolder(v: View) : RecyclerView.ViewHolder(v) {
        val view: PuzzleView
        init {
            view = v as PuzzleView
        }
    }
}

PuzzleAdapter之前

class PuzzleAdapter(private val puzzles: List<Puzzle>) : RecyclerView.Adapter<PuzzleAdapter.PuzzleHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PuzzleAdapter.PuzzleHolder {
        val v = LayoutInflater.from(parent.context).inflate(R.layout.item_puzzle, parent, false)
        return PuzzleHolder(v)
    }

    override fun getItemCount() = puzzles.size

    //unchanged between these two versions
    override fun onBindViewHolder(h: PuzzleAdapter.PuzzleHolder, pos: Int) {
        val p = puzzles[pos]
        h.view.puzzleItem_text_ndx.text = "# " + p.descr()
        h.view.puzzleItem_text_details.text = "Ndx: ${p.puzzleNdx}"
        h.view.setOnClickListener {
            Log.d("##", "PuzzleHolder.onClick (bunch#${p.parentBunch.bunchID}; puzzle#${p.puzzleNdx})")
            val action = BunchFragmentDirections.navBunchToPuzzle(PuzzleParcel(p.parentBunch.bunchID, p.puzzleNdx))
            it.findNavController().navigate(action)
        }
    }

    inner class PuzzleHolder(v: View) : RecyclerView.ViewHolder(v) {
        var view: View = v
    }
}

PuzzleView (我正在使用适配器的自定义视图):

class PuzzleView : RelativeLayout {
    constructor (context: Context) : super(context) { init(context, null, 0) }
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { init(context, attrs, 0) }
    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) { init(context, attrs, defStyle) }

    private fun init(context: Context, attrs: AttributeSet?, defStyle: Int) {
        inflate(getContext(), R.layout.item_puzzle, this)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        //this.layout(l, t, r, b)
    }

    val rect = Rect(0, 0, 0, 0)
    val paint = Paint()
    override fun onDraw(canvas: Canvas) {
        //super.onDraw(canvas)
        Log.d("##", "PuzzleView.onDraw()")
        rect.right = width - 10
        rect.bottom = height - 10
        val bkgrColor = ContextCompat.getColor(App.context, R.color.Green)
        paint.style = Paint.Style.FILL
        paint.color = bkgrColor
        canvas.drawRect(rect, paint)
    }
}

对上述类/代码的几点思考:

  • override fun onLayout是必需的
  • 我还有其他自定义视图,这些视图工作正常(与RecyclerView无关),onLayout为空
  • 我尝试过(在上面的代码中已将其注释掉)this.layout(l, t, r, b),但遇到了堆栈溢出异常
  

我在这里唯一真正的想法是(1)我应该使用此onLayout方法来做某事,但是我想不出什么;或(2)我夸大item_puzzle的方式有问题,但是-再次-我想不出什么。 (对此我尝试了一些尝试,但无济于事。)我什么都没想到!

以下是我认为可能相关的所有其他代码:

来自包含RecyclerView的片段(上面三幅图所示):

    bunch_recycler.layoutManager = GridLayoutManager(this.context, 3)
    bunch_recycler.adapter = PuzzleAdapter(bunch.puzzles)

最后,该商品本身的 XML item_puzzle enter image description here

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="16dp"
    android:layout_marginStart="16dp"
    android:layout_marginEnd="16dp"
    app:cardBackgroundColor="@color/facadeLight"
    app:cardElevation="0dp"
    >

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/shape_puzzle"
        >

        <TextView
            android:id="@+id/puzzleItem_text_ndx"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginEnd="16dp"
            android:ellipsize="end"
            android:fontFamily="@font/showg"
            android:maxLines="1"
            android:text="17"
            android:textColor="@color/facadeDark"
            android:textSize="32sp"
            />

        <TextView
            android:id="@+id/puzzleItem_text_details"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/puzzleItem_text_ndx"
            android:layout_marginStart="8dp"
            android:text="details"
            android:textSize="12sp"
            />
    </RelativeLayout>

</androidx.cardview.widget.CardView>
  

也:如果“自定义视图允许onDraw”不是在这里实现我的目标的正确(或最佳)方法,请也告诉我。

使用:

  • Windows 10
  • Android Studio 3.4
  • 科特林1.3.31
  • 3.4.0级
  • 以及以下内容:
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha05'
    implementation 'androidx.core:core-ktx:1.2.0-alpha01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0-beta01'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-beta01'

    implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
    implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'
  

事后:我看到了(在一个4 1/2岁的youtube video中,在getView中覆盖了getView,以便在相似的情况下分配子视图。今天在RecyclerView中要重写的{1}}方法,我所看到的最接近的是getItemViewType(position: Int): Int,这似乎也没有什么用(我对此有所了解),以为我提到了这个万一它引发了您的想法(不是我的想法)

一如既往,感谢您的帮助!

0 个答案:

没有答案