运行良好的 Java 代码导致 kotlin.TypeCastException:在转换为 Kotlin 代码时,无法将 null 转换为非空类型
Well working Java code is causing kotlin.TypeCastException: null cannot be cast to non-null type when converted to Kotlin code
我必须为 RecyclerView
的项目添加动画并创建一个 CustomGridRecyclerView
作为给定的打击:
public class CustomGridRecyclerView extends RecyclerView {
public CustomGridRecyclerView(Context context) {
super(context);
}
public CustomGridRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomGridRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setLayoutManager(LayoutManager layout) {
if (layout instanceof GridLayoutManager) {
super.setLayoutManager(layout);
} else {
throw new ClassCastException("This recyclerview should use grid layout manager as the layout manager");
}
}
@Override
protected void attachLayoutAnimationParameters(View child, ViewGroup.LayoutParams params, int index, int count) {
if (getAdapter() != null && getLayoutManager() instanceof GridLayoutManager) {
GridLayoutAnimationController.AnimationParameters animationParams =
(GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;
if (animationParams == null) {
animationParams = new GridLayoutAnimationController.AnimationParameters();
params.layoutAnimationParameters = animationParams;
}
int columns = ((GridLayoutManager) getLayoutManager()).getSpanCount();
animationParams.count = count;
animationParams.index = index;
animationParams.columnsCount = columns;
animationParams.rowsCount = count / columns;
final int invertedIndex = count - 1 - index;
animationParams.column = columns - 1 - (invertedIndex % columns);
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns;
} else {
super.attachLayoutAnimationParameters(child, params, index, count);
}
}
}
效果很好,但我想在另一个使用 Kotlin 的应用程序中使用以下代码实现相同的功能:
class CustomGridRecyclerView : RecyclerView {
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 setLayoutManager(layout: LayoutManager?) {
if (layout is GridLayoutManager) {
super.setLayoutManager(layout)
} else {
throw ClassCastException("This RecyclerView should use GridLayoutManager as the layout manager")
}
}
override fun attachLayoutAnimationParameters(
child: View?,
params: ViewGroup.LayoutParams,
index: Int,
count: Int
) {
if (adapter != null && layoutManager is GridLayoutManager) {
//val
val animationParams =
params.layoutAnimationParameters as GridLayoutAnimationController.AnimationParameters // CustomGridRecyclerView.kt:38 is the line where kotlin.TypeCastException occurs I have tried with GridLayoutAnimationController.AnimationParameters? as well but never succeeded
val columns = (layoutManager as GridLayoutManager?)!!.spanCount
animationParams.count = count
animationParams.index = index
animationParams.columnsCount = columns
animationParams.rowsCount = count / columns
val invertedIndex = count - 1 - index
animationParams.column = columns - 1 - invertedIndex % columns
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns
} else {
super.attachLayoutAnimationParameters(child, params, index, count)
}
}
}
它给我错误:
kotlin.TypeCastException: null cannot be cast to non-null type android.view.animation.GridLayoutAnimationController.AnimationParameters
at pk.inlab.app.expenselogger.view.custom.CustomGridRecyclerView.attachLayoutAnimationParameters(CustomGridRecyclerView.kt:38)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3267)
at android.view.View.draw(View.java:15507)
at androidx.recyclerview.widget.RecyclerView.draw(RecyclerView.java:4219)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.draw(View.java:15507)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1246)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.draw(View.java:15507)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchDraw(PhoneWindow.java:2784)
at android.view.View.draw(View.java:15507)
at android.widget.FrameLayout.draw(FrameLayout.java:658)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2763)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:279)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:285)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:335)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2939)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2753)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2367)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1292)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6598)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:800)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:572)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.L
我如何投射 android.view.animation.GridLayoutAnimationController.AnimationParameters
而不会出错?
更新
按照下面答案中的建议,我更改了我的代码
val animationParams =
params.layoutAnimationParameters as? GridLayoutAnimationController.AnimationParameters
val columns = (layoutManager as GridLayoutManager?)!!.spanCount
animationParams!!.count = count
得到这个:
kotlin.KotlinNullPointerException
at pk.inlab.app.expenselogger.view.custom.CustomGridRecyclerView.attachLayoutAnimationParameters(CustomGridRecyclerView.kt:40)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3267)
at android.view.View.draw(View.java:15507)
at androidx.recyclerview.widget.RecyclerView.draw(RecyclerView.java:4219)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.draw(View.java:15507)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1246)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.draw(View.java:15507)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchDraw(PhoneWindow.java:2784)
at android.view.View.draw(View.java:15507)
at android.widget.FrameLayout.draw(FrameLayout.java:658)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2763)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:279)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:285)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:335)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2939)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2753)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2367)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1292)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6598)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:800)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:572)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5631)
at java.lang
第一个问题是您正在尝试 cast
一个 nullable value (params.layoutAnimationParameters
) to a non null type,当 params.layoutAnimationParameters
是 null
时,这会导致 null pointer exception
。
要解决此问题,请使用 kotlin 的 safe cast operator (as?
),它会尝试 cast
给定 type
的值,如果不能,则只需 returns null
.
第二个问题是 在你的 java 代码中如果 params.layoutAnimationParameters
是 null
那么你给它分配一个新的 GridLayoutAnimationController.AnimationParameters()
,
if (animationParams == null) {
animationParams = new GridLayoutAnimationController.AnimationParameters();
params.layoutAnimationParameters = animationParams;
}
我没有看到你在 kotlin 代码中做同样的事情。 我已经修改了你的 function
以使用safe cast
和适当的 null
检查,它应该工作。
override fun attachLayoutAnimationParameters(
child: View?,
params: ViewGroup.LayoutParams,
index: Int,
count: Int
) {
if (adapter != null && layoutManager is GridLayoutManager) {
var animationParams =
params.layoutAnimationParameters as? GridLayoutAnimationController.AnimationParameters
if (animationParams == null) {
animationParams = AnimationParameters()
params.layoutAnimationParameters = animationParams
}
val columns = layoutManager.spanCount
animationParams.count = count
animationParams.index = index
animationParams.columnsCount = columns
animationParams.rowsCount = count / columns
val invertedIndex = count - 1 - index
animationParams.column = columns - 1 - invertedIndex % columns
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns
} else {
super.attachLayoutAnimationParameters(child, params, index, count)
}
}
像这样使用它:
val animationParams =
params.layoutAnimationParameters as? GridLayoutAnimationController.AnimationParameters
然后像这样将访问更改为空安全访问:
animationParams?.count = count
我必须为 RecyclerView
的项目添加动画并创建一个 CustomGridRecyclerView
作为给定的打击:
public class CustomGridRecyclerView extends RecyclerView {
public CustomGridRecyclerView(Context context) {
super(context);
}
public CustomGridRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomGridRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setLayoutManager(LayoutManager layout) {
if (layout instanceof GridLayoutManager) {
super.setLayoutManager(layout);
} else {
throw new ClassCastException("This recyclerview should use grid layout manager as the layout manager");
}
}
@Override
protected void attachLayoutAnimationParameters(View child, ViewGroup.LayoutParams params, int index, int count) {
if (getAdapter() != null && getLayoutManager() instanceof GridLayoutManager) {
GridLayoutAnimationController.AnimationParameters animationParams =
(GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;
if (animationParams == null) {
animationParams = new GridLayoutAnimationController.AnimationParameters();
params.layoutAnimationParameters = animationParams;
}
int columns = ((GridLayoutManager) getLayoutManager()).getSpanCount();
animationParams.count = count;
animationParams.index = index;
animationParams.columnsCount = columns;
animationParams.rowsCount = count / columns;
final int invertedIndex = count - 1 - index;
animationParams.column = columns - 1 - (invertedIndex % columns);
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns;
} else {
super.attachLayoutAnimationParameters(child, params, index, count);
}
}
}
效果很好,但我想在另一个使用 Kotlin 的应用程序中使用以下代码实现相同的功能:
class CustomGridRecyclerView : RecyclerView {
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 setLayoutManager(layout: LayoutManager?) {
if (layout is GridLayoutManager) {
super.setLayoutManager(layout)
} else {
throw ClassCastException("This RecyclerView should use GridLayoutManager as the layout manager")
}
}
override fun attachLayoutAnimationParameters(
child: View?,
params: ViewGroup.LayoutParams,
index: Int,
count: Int
) {
if (adapter != null && layoutManager is GridLayoutManager) {
//val
val animationParams =
params.layoutAnimationParameters as GridLayoutAnimationController.AnimationParameters // CustomGridRecyclerView.kt:38 is the line where kotlin.TypeCastException occurs I have tried with GridLayoutAnimationController.AnimationParameters? as well but never succeeded
val columns = (layoutManager as GridLayoutManager?)!!.spanCount
animationParams.count = count
animationParams.index = index
animationParams.columnsCount = columns
animationParams.rowsCount = count / columns
val invertedIndex = count - 1 - index
animationParams.column = columns - 1 - invertedIndex % columns
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns
} else {
super.attachLayoutAnimationParameters(child, params, index, count)
}
}
}
它给我错误:
kotlin.TypeCastException: null cannot be cast to non-null type android.view.animation.GridLayoutAnimationController.AnimationParameters
at pk.inlab.app.expenselogger.view.custom.CustomGridRecyclerView.attachLayoutAnimationParameters(CustomGridRecyclerView.kt:38)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3267)
at android.view.View.draw(View.java:15507)
at androidx.recyclerview.widget.RecyclerView.draw(RecyclerView.java:4219)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.draw(View.java:15507)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1246)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.draw(View.java:15507)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchDraw(PhoneWindow.java:2784)
at android.view.View.draw(View.java:15507)
at android.widget.FrameLayout.draw(FrameLayout.java:658)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2763)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:279)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:285)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:335)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2939)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2753)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2367)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1292)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6598)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:800)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:572)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.L
我如何投射 android.view.animation.GridLayoutAnimationController.AnimationParameters
而不会出错?
更新
按照下面答案中的建议,我更改了我的代码
val animationParams =
params.layoutAnimationParameters as? GridLayoutAnimationController.AnimationParameters
val columns = (layoutManager as GridLayoutManager?)!!.spanCount
animationParams!!.count = count
得到这个:
kotlin.KotlinNullPointerException
at pk.inlab.app.expenselogger.view.custom.CustomGridRecyclerView.attachLayoutAnimationParameters(CustomGridRecyclerView.kt:40)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3267)
at android.view.View.draw(View.java:15507)
at androidx.recyclerview.widget.RecyclerView.draw(RecyclerView.java:4219)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.draw(View.java:15507)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1246)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.draw(View.java:15507)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at android.view.View.updateDisplayListIfDirty(View.java:14376)
at android.view.View.getDisplayList(View.java:14413)
at android.view.View.draw(View.java:15204)
at android.view.ViewGroup.drawChild(ViewGroup.java:3532)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3325)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchDraw(PhoneWindow.java:2784)
at android.view.View.draw(View.java:15507)
at android.widget.FrameLayout.draw(FrameLayout.java:658)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2763)
at android.view.View.updateDisplayListIfDirty(View.java:14384)
at android.view.View.getDisplayList(View.java:14413)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:279)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:285)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:335)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2939)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2753)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2367)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1292)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6598)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:800)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:572)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5631)
at java.lang
第一个问题是您正在尝试 cast
一个 nullable value (params.layoutAnimationParameters
) to a non null type,当 params.layoutAnimationParameters
是 null
时,这会导致 null pointer exception
。
要解决此问题,请使用 kotlin 的 safe cast operator (as?
),它会尝试 cast
给定 type
的值,如果不能,则只需 returns null
.
第二个问题是 在你的 java 代码中如果 params.layoutAnimationParameters
是 null
那么你给它分配一个新的 GridLayoutAnimationController.AnimationParameters()
,
if (animationParams == null) {
animationParams = new GridLayoutAnimationController.AnimationParameters();
params.layoutAnimationParameters = animationParams;
}
我没有看到你在 kotlin 代码中做同样的事情。 我已经修改了你的 function
以使用safe cast
和适当的 null
检查,它应该工作。
override fun attachLayoutAnimationParameters(
child: View?,
params: ViewGroup.LayoutParams,
index: Int,
count: Int
) {
if (adapter != null && layoutManager is GridLayoutManager) {
var animationParams =
params.layoutAnimationParameters as? GridLayoutAnimationController.AnimationParameters
if (animationParams == null) {
animationParams = AnimationParameters()
params.layoutAnimationParameters = animationParams
}
val columns = layoutManager.spanCount
animationParams.count = count
animationParams.index = index
animationParams.columnsCount = columns
animationParams.rowsCount = count / columns
val invertedIndex = count - 1 - index
animationParams.column = columns - 1 - invertedIndex % columns
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns
} else {
super.attachLayoutAnimationParameters(child, params, index, count)
}
}
像这样使用它:
val animationParams =
params.layoutAnimationParameters as? GridLayoutAnimationController.AnimationParameters
然后像这样将访问更改为空安全访问:
animationParams?.count = count