无法将图像分配给 Nullable ImageView
Can't assign an image to a Nullable ImageView
如何将图像设置为 ImageView?
我的应用的想法是根据 RecyclerView 中的数据 class 显示不同类型的 RecyclerView 视图持有者。数据 class 看起来像这样:
abstract class Thing(open val title: String, open val body: String, open val pic: ImageView?)
data class Movie(override val title: String, override val body: String): Thing(title, body, pic = null)
data class Book(override val title: String, override val body: String): Thing(title, body, pic = null)
data class Game(override val title: String, override val body: String, override val pic: ImageView?): Thing(title, body, pic)
另外,我有一个 MainFragment,我在其中手动添加数据。在这里,我试图给出游戏的名称和描述,并将特定图像设置为 game_pic ImageView:
class MainFragment: Fragment() {
private val mMoviesBooksGames = listOf(
Game("Dixit", "Give the perfect clue so most (not all) players guess the right surreal image card.", game_pic.setImageResource(R.drawable.alias) as ImageView)
}
}
我如何声明我的 game_pic
所在的 GameViewHolder:
class GameViewHolder(inflater: LayoutInflater, parent: ViewGroup) :
ThingViewHolder(inflater.inflate(R.layout.game_list_item, parent, false)) {
private var mGameTitleView: TextView? = null
private var mGameDescriptionView: TextView? = null
private var mGamePicImageView: ImageView? = null
init {
mGameTitleView = itemView.findViewById(R.id.game_title)
mGameDescriptionView = itemView.findViewById(R.id.game_description)
mGamePicImageView = itemView.findViewById(R.id.game_pic)
}
override fun bind(dataToBind: Thing) {
mGameTitleView?.text = ">> Book ${dataToBind.title}"
mGameDescriptionView?.text = dataToBind.body
mGamePicImageView = dataToBind.pic
}
}
我在使用 game_pic.setImageResource(R.drawable.alias) as ImageView
后得到的错误是:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.recyclerview, PID: 822
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.recyclerview/com.example.recyclerview.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3555)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3707)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8019)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)' on a null object reference
at com.example.recyclerview.MainFragment.<init>(MainFragment.kt:33)
at com.example.recyclerview.MainFragment$Companion.newInstance(MainFragment.kt:67)
at com.example.recyclerview.MainActivity.createFragment(MainActivity.kt:4)
at com.example.recyclerview.MainActivity.createFragment(MainActivity.kt:3)
at com.example.recyclerview.SingleFragmentActivity.onCreate(SingleFragmentActivity.kt:25)
at android.app.Activity.performCreate(Activity.java:7957)
at android.app.Activity.performCreate(Activity.java:7946)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3530)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3707)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8019)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
I/Process: Sending signal. PID: 822 SIG: 9
错误提示您的 game_pic
变量为空。
我可以在没有看到您的代码的情况下提出一个解决方法:
private val mMoviesBooksGames = listOf( Game(
"Dixit",
"Give the perfect clue so most (not all) players guess the right surreal image card.",
ImageView(this).apply { setImageResource(R.drawable.alias) })
)
构造ImageView并在non-null实例上设置图片资源。
或者您可以在某个地方初始化您的 game_pic
,例如 onCreateView
方法,然后再初始化您的 mMoviesBooksGames
。
UPD:
- 您不应将视图声明为可为空。
- 您可以通过其他方式设置图片资源。
首先,你在init
中初始化你的mGamePicImageView
,然后在bind
中重写它。其次,您可以只将可绘制数据传递给视图持有者,而不是一个全新的 ImageView。
我建议你重新设计你的数据class:
data class Game(
override val title: String,
override val body: String,
override val imageDrawable: Drawable)
然后在viewholder的bind方法中
mGamePicImageView.setImageDrawable(dataToBind.imageDrawable)
最后
private val mMoviesBooksGames = listOf( Game(
"Dixit",
"Give the perfect clue so most (not all) players guess the right surreal image card.",
ContextCompat.getDrawable(this.activity, android.R.drawable.alias))
)
getDrawable
的第一个参数不是上下文,因此将片段的父级 activity 传递到那里。第二个参数是drawable的id,我不确定你是否需要前缀android.
,所以你也可以试试R.drawable.alias
.
data class Game(
override val title: String,
override val body: String,
override val image: Int)
像这样修改数据class
override fun bind(dataToBind: Thing) {
mGameTitleView?.text = ">> Book ${dataToBind.title}"
mGameDescriptionView?.text = dataToBind.body
mGamePicImageViewsetImageResource(dataToBind.pic)
}
之后像这样将代码替换为您的视图持有者
data class Game(
"Dixit",
"Give the perfect clue so most (not all) players guess the right surreal image card.",
R.drawable.your_pic
)
然后尝试将此值放入您的游戏缺点中。
如何将图像设置为 ImageView?
我的应用的想法是根据 RecyclerView 中的数据 class 显示不同类型的 RecyclerView 视图持有者。数据 class 看起来像这样:
abstract class Thing(open val title: String, open val body: String, open val pic: ImageView?)
data class Movie(override val title: String, override val body: String): Thing(title, body, pic = null)
data class Book(override val title: String, override val body: String): Thing(title, body, pic = null)
data class Game(override val title: String, override val body: String, override val pic: ImageView?): Thing(title, body, pic)
另外,我有一个 MainFragment,我在其中手动添加数据。在这里,我试图给出游戏的名称和描述,并将特定图像设置为 game_pic ImageView:
class MainFragment: Fragment() {
private val mMoviesBooksGames = listOf(
Game("Dixit", "Give the perfect clue so most (not all) players guess the right surreal image card.", game_pic.setImageResource(R.drawable.alias) as ImageView)
}
}
我如何声明我的 game_pic
所在的 GameViewHolder:
class GameViewHolder(inflater: LayoutInflater, parent: ViewGroup) :
ThingViewHolder(inflater.inflate(R.layout.game_list_item, parent, false)) {
private var mGameTitleView: TextView? = null
private var mGameDescriptionView: TextView? = null
private var mGamePicImageView: ImageView? = null
init {
mGameTitleView = itemView.findViewById(R.id.game_title)
mGameDescriptionView = itemView.findViewById(R.id.game_description)
mGamePicImageView = itemView.findViewById(R.id.game_pic)
}
override fun bind(dataToBind: Thing) {
mGameTitleView?.text = ">> Book ${dataToBind.title}"
mGameDescriptionView?.text = dataToBind.body
mGamePicImageView = dataToBind.pic
}
}
我在使用 game_pic.setImageResource(R.drawable.alias) as ImageView
后得到的错误是:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.recyclerview, PID: 822
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.recyclerview/com.example.recyclerview.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3555)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3707)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8019)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int)' on a null object reference
at com.example.recyclerview.MainFragment.<init>(MainFragment.kt:33)
at com.example.recyclerview.MainFragment$Companion.newInstance(MainFragment.kt:67)
at com.example.recyclerview.MainActivity.createFragment(MainActivity.kt:4)
at com.example.recyclerview.MainActivity.createFragment(MainActivity.kt:3)
at com.example.recyclerview.SingleFragmentActivity.onCreate(SingleFragmentActivity.kt:25)
at android.app.Activity.performCreate(Activity.java:7957)
at android.app.Activity.performCreate(Activity.java:7946)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3530)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3707)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8019)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
I/Process: Sending signal. PID: 822 SIG: 9
错误提示您的 game_pic
变量为空。
我可以在没有看到您的代码的情况下提出一个解决方法:
private val mMoviesBooksGames = listOf( Game(
"Dixit",
"Give the perfect clue so most (not all) players guess the right surreal image card.",
ImageView(this).apply { setImageResource(R.drawable.alias) })
)
构造ImageView并在non-null实例上设置图片资源。
或者您可以在某个地方初始化您的 game_pic
,例如 onCreateView
方法,然后再初始化您的 mMoviesBooksGames
。
UPD:
- 您不应将视图声明为可为空。
- 您可以通过其他方式设置图片资源。
首先,你在init
中初始化你的mGamePicImageView
,然后在bind
中重写它。其次,您可以只将可绘制数据传递给视图持有者,而不是一个全新的 ImageView。
我建议你重新设计你的数据class:
data class Game(
override val title: String,
override val body: String,
override val imageDrawable: Drawable)
然后在viewholder的bind方法中
mGamePicImageView.setImageDrawable(dataToBind.imageDrawable)
最后
private val mMoviesBooksGames = listOf( Game(
"Dixit",
"Give the perfect clue so most (not all) players guess the right surreal image card.",
ContextCompat.getDrawable(this.activity, android.R.drawable.alias))
)
getDrawable
的第一个参数不是上下文,因此将片段的父级 activity 传递到那里。第二个参数是drawable的id,我不确定你是否需要前缀android.
,所以你也可以试试R.drawable.alias
.
data class Game(
override val title: String,
override val body: String,
override val image: Int)
像这样修改数据class
override fun bind(dataToBind: Thing) {
mGameTitleView?.text = ">> Book ${dataToBind.title}"
mGameDescriptionView?.text = dataToBind.body
mGamePicImageViewsetImageResource(dataToBind.pic)
}
之后像这样将代码替换为您的视图持有者
data class Game(
"Dixit",
"Give the perfect clue so most (not all) players guess the right surreal image card.",
R.drawable.your_pic
)
然后尝试将此值放入您的游戏缺点中。