我需要onDraw
的物品RecyclerView
。使用this SO link处“发现”的方法,我已经-嗯-在那儿。
请注意,我最终希望onDraw
在自定义视图上方。含义是调用super
以使默认绘图生效,然后在视图的paint
的未使用区域上canvas
。
在开始执行“允许onDraw
的自定义视图之前,我在下面的左中看到了以下内容:
之后,我拥有所有“不可见”的视图(上面的中间图像)。我说“不可见”是因为它们仍然可以单击。为了帮助我可视化事物(以及一些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
是必需的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 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”不是在这里实现我的目标的正确(或最佳)方法,请也告诉我。
使用:
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
,这似乎也没有什么用(我对此有所了解),以为我提到了这个万一它引发了您的想法(不是我的想法)
一如既往,感谢您的帮助!