提问人:Daniil Andreev 提问时间:4/18/2021 更新时间:4/18/2021 访问量:324
回收器视图 - 在空对象引用上
Recycler view - on a null object reference
问:
我有底部工作表视图和回收器视图。它是用 Kotlin 编写的。我正在尝试显示评论列表。尝试显示底部工作表并应用回收器视图数据时出现空指针异常。我的错误是 - 尝试在空对象引用上调用虚拟方法“void androidx.recyclerview.widget.RecyclerView.setAdapter(androidx.recyclerview.widget.RecyclerView$Adapter)”。其他答案无济于事。这是我的片段——
class AudioFragment : Fragment(R.layout.fragment_audio) {
@Inject
lateinit var glide: RequestManager
lateinit var bottomSheetDialog: BottomSheetDialog
lateinit var bottomSheetView: View
@Inject
lateinit var commentAdapter: CommentAdapter
private lateinit var mainViewModel: MainViewModel
private val audioViewModel: AudioViewModel by viewModels()
private var curPlayingAudio: Audio? = null
private var playbackState: PlaybackStateCompat? = null
private var shouldUpdateSeekbar = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bottomSheetDialog = BottomSheetDialog(requireContext(), R.style.BottomSheetDialogTheme)
bottomSheetView = LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_comment, null)
bottomSheetDialog.setContentView(bottomSheetView)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainViewModel = ViewModelProvider(requireActivity()).get(MainViewModel::class.java)
subscribeToObservers()
ivPlayPauseDetail.setOnClickListener {
curPlayingAudio?.let {
mainViewModel.playOrToggleAudio(it, true)
}
}
arrowBack.setOnClickListener {
navHostFragment.findNavController().navigate(
R.id.globalActionFromAudioFragmentToHome
)
}
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if(fromUser) {
setCurPlayerTimeToTextView(progress.toLong())
}
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
shouldUpdateSeekbar = false
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
seekBar?.let {
mainViewModel.seekTo(it.progress.toLong())
shouldUpdateSeekbar = true
}
}
})
ivSkipPrevious.setOnClickListener {
mainViewModel.skipToPreviousAudio()
}
ivSkip.setOnClickListener {
mainViewModel.skipToNextAudio()
}
commentOpen.setOnClickListener {
bottomSheetDialog.show()
rvAllComments.apply {
adapter = commentAdapter
layoutManager = LinearLayoutManager(requireContext())
}
curPlayingAudio?._id?.let { it1 ->
RetrofitService().getComments(it1).enqueue(object: Callback<List<Comment>> {
override fun onFailure(call: Call<List<Comment>>, t: Throwable) {
Log.d("err", "${t.message}")
Toast.makeText(requireContext(), t.message, Toast.LENGTH_LONG).show()
}
override fun onResponse(call: Call<List<Comment>>, response: Response<List<Comment>>) {
allCommentsProgressBar.visibility = INVISIBLE
response.body()?.let { res ->
commentAdapter.comments = res
}
}
})
}
}
}
private fun updateTitleAndAudioImage(audio: Audio) {
val title = "${audio.title}"
val writer = "${audio.writer.name}"
tvAudioName.text = title
tvAudioWriter.text = writer
glide.load(audio.writer.image).into(ivAudioImage)
}
private fun subscribeToObservers() {
mainViewModel.mediaItems.observe(viewLifecycleOwner) {
it.let { result ->
when(result.status) {
SUCCESS -> {
result.data?.let { audios ->
if(curPlayingAudio == null && audios.isNotEmpty()) {
curPlayingAudio = audios[0]
updateTitleAndAudioImage(audios[0])
}
}
}
else -> Unit
}
}
}
mainViewModel.curPlayingAudio.observe(viewLifecycleOwner) {
if(it == null) return@observe
curPlayingAudio = it.toAudio()
updateTitleAndAudioImage(curPlayingAudio!!)
}
mainViewModel.playbackState.observe(viewLifecycleOwner) {
playbackState = it
ivPlayPauseDetail.setImageResource(
if(playbackState?.isPlaying == true) R.drawable.ic_pause else R.drawable.ic_play_arrow
)
seekBar.progress = it?.position?.toInt() ?: 0
}
audioViewModel.curPlayerPosition.observe(viewLifecycleOwner) {
if(shouldUpdateSeekbar) {
seekBar.progress = it.toInt()
setCurPlayerTimeToTextView(it)
}
}
audioViewModel.curAudioDuration.observe(viewLifecycleOwner) {
seekBar.max = it.toInt()
val dateFormat = SimpleDateFormat("mm:ss", Locale.getDefault())
tvAudioDuration.text = dateFormat.format(it)
}
}
private fun setCurPlayerTimeToTextView(ms: Long) {
val dateFormat = SimpleDateFormat("mm:ss", Locale.getDefault())
tvCurTime.text = dateFormat.format(ms)
}
}
这是我的底部工作表视图 -
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottomSheet"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bottom_sheet_background"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<TextView
android:id="@+id/commentsHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Comments"
android:padding="10dp"
android:gravity="center"
android:textStyle="bold"
android:textSize="18sp"/>
<View
android:id="@+id/commentsHeaderHr"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#7A7A7A"
android:layout_marginBottom="10dp" />
<ProgressBar
android:id="@+id/allCommentsProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvAllComments"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
答:
0赞
Tanvir Ahmmad
4/18/2021
#1
尝试
bottomsheetview.rvAllComments.apply
评论
0赞
Daniil Andreev
4/19/2021
是的,这很有帮助!
评论
rvAllComments