プッシャーチャットキットのチュートリアルに従って "KOTLINとプッシャーチャットキットを使用してグループチャットアプリを構築する" を実行しようとしていますが、リサイクラービューアダプターで問題が発生しています。参考までに、私はまだKotlinを学んでいます。私はlateinit変数を読んでいますが、このケースに対処するものは何も見つかりません。エラーは、リサイクラービューアダプターで発生します。
これは私が得るエラーです:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.Android_myneighborsbookshelf, PID: 26692
kotlin.UninitializedPropertyAccessException: lateinit property roomClickedInterface has not been initialized
at com.example.Android_myneighborsbookshelf.adapters.ChatRoomsListAdapter.getRoomClickedInterface(ChatRoomsListAdapter.kt:13)
at com.example.Android_myneighborsbookshelf.adapters.ChatRoomsListAdapter$ViewHolder.onClick(ChatRoomsListAdapter.kt:66)
at Android.view.View.performClick(View.Java:6597)
at Android.view.View.performClickInternal(View.Java:6574)
at Android.view.View.access$3100(View.Java:778)
at Android.view.View$PerformClick.run(View.Java:25885)
at Android.os.Handler.handleCallback(Handler.Java:873)
at Android.os.Handler.dispatchMessage(Handler.Java:99)
at Android.os.Looper.loop(Looper.Java:193)
at Android.app.ActivityThread.main(ActivityThread.Java:6669)
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:858)
ChatRoomsListActivity.kt
class ChatRoomsListActivity : AppCompatActivity() {
val adapter = ChatRoomsListAdapter();
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_room_list)
initRecyclerView()
initChatManager()
}
private fun initRecyclerView() {
recycler_view.layoutManager = LinearLayoutManager(this@ChatRoomsListActivity)
recycler_view.adapter = adapter
}
private fun initChatManager() {
val chatManager = ChatManager(
instanceLocator = "blahblahblah",
userId = "username1-PCKid",
dependencies = AndroidChatkitDependencies(
tokenProvider = ChatkitTokenProvider(
endpoint = "blahblahblah",
// endpoint = "http://10.0.2.2:3000/auth",
userId = "username1-PCKid"
)
)
)
chatManager.connect(listeners = ChatListeners(
onErrorOccurred = { },
onAddedToRoom = { },
onRemovedFromRoom = { },
onCurrentUserReceived = { },
onNewReadCursor = { },
onRoomDeleted = { },
onRoomUpdated = { },
onPresenceChanged = { u, n, p -> },
onUserJoinedRoom = { u, r -> },
onUserLeftRoom = { u, r -> },
onUserStartedTyping = { u, r -> },
onUserStoppedTyping = { u, r -> }
)) { result ->
when (result) {
is Result.Success -> {
// We have connected!
val currentUser = result.value
AppController.currentUser = currentUser
val userJoinedRooms = ArrayList<Room>(currentUser.rooms)
for (i in 0 until userJoinedRooms.size) {
adapter.addRoom(userJoinedRooms[i])
}
currentUser.getJoinableRooms { result ->
when (result) {
is Result.Success -> {
// Do something with List<Room>
val rooms = result.value
runOnUiThread {
for (i in 0 until rooms.size) {
adapter.addRoom(rooms[i])
}
}
}
}
}
adapter.setInterface(object : ChatRoomsListAdapter.RoomClickedInterface {
override fun roomSelected(room: Room) {
if (room.memberUserIds.contains(currentUser.id)) {
// user already belongs to this room
roomJoined(room)
} else {
currentUser.joinRoom(
roomId = room.id,
callback = { result ->
when (result) {
is Result.Success -> {
// Joined the room!
roomJoined(result.value)
}
is Result.Failure -> {
Log.d("TAG", result.error.toString())
}
}
}
)
}
}
})
}
is Result.Failure -> {
// Failure
Log.d("TAG", result.error.toString())
}
}
}
}
private fun roomJoined(room: Room) {
val intent = Intent(this@ChatRoomsListActivity, ChatRoomsListActivity::class.Java)
intent.putExtra("room_id", room.id)
intent.putExtra("room_name", room.name)
startActivity(intent)
}
}
RecyclerView Adapter
import Android.view.View
import Android.view.ViewGroup
import Android.widget.TextView
import com.pusher.chatkit.rooms.Room
import Android.view.LayoutInflater
import androidx.recyclerview.widget.RecyclerView
import com.example.Android_myneighborsbookshelf.R
class ChatRoomsListAdapter: RecyclerView.Adapter<ChatRoomsListAdapter.ViewHolder>() {
private var list = ArrayList<Room>()
lateinit var roomClickedInterface:RoomClickedInterface // <-- Error occurs here - kt.13
fun addRoom(room:Room){
list.add(room)
notifyDataSetChanged()
}
fun setInterface(roomClickedInterface:RoomClickedInterface){
this.roomClickedInterface = roomClickedInterface
}
override fun getItemCount(): Int {
return list.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(
Android.R.layout.simple_list_item_1,
parent,
false
)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.roomName.text = list[position].name
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView), View.OnClickListener {
override fun onClick(p0: View?) {
roomClickedInterface.roomSelected(list[adapterPosition]) // <-- Error occurs here kt.66
}
var roomName: TextView = itemView.findViewById(Android.R.id.text1)
init {
itemView.setOnClickListener(this)
}
}
interface RoomClickedInterface{
fun roomSelected(room:Room)
}
}
ありとあらゆる助けをいただければ幸いです。
lateinit
は初期化が遅いことを意味します。コンストラクターで変数を初期化したくない場合は、後で初期化する必要があります。可能であれば使用する前に初期化を保証します、その変数をlateinit
で宣言します。キーワード。初期化されるまでメモリは割り当てられません。
したがって、使用する前にlateinit
プロパティを初期化する必要があります。
オプション-1:リスト項目をクリックする前に、setInterface()
を呼び出してプロパティを初期化します。以下のように、.isInitialized
を使用して、lateinit
変数がすでに初期化されているかどうかを確認することもできます。
override fun onClick(p0: View?) {
if(this::roomClickedInterface.isInitialized) {
roomClickedInterface.roomSelected(list[adapterPosition])
}
}
オプション-2:アダプタからlateinit
プロパティを削除し、セッターも削除します
//lateinit var roomClickedInterface:RoomClickedInterface
そして、アダプターのコンストラクターのパラメーターとしてRoomClickedInterface
を渡します
class ChatRoomsListAdapter(val roomClickedInterface:RoomClickedInterface):
RecyclerView.Adapter<ChatRoomsListAdapter.ViewHolder>() {
//Implementation
}
オプション-3:lateinit
を削除し、nullable
プロパティを使用します
private var roomClickedInterface: RoomClickedInterface? = null
次に、null
安全表記?.
を使用して以下のように使用します。
override fun onClick(p0: View?) {
roomClickedInterface?.roomSelected(list[adapterPosition])
}