모바일 앱(안드로이드)

안드로이드 앱 만들기 : Recycleview 을 구현하다 벌어지는 흔한 실수

Billcoreatech 2021. 11. 2. 09:13
반응형

Recycleview 을 사용하다보니, RecycleAdapter 을 구성해서 화면을 구현 하게 된다.  당연한...

잠깐 소스를 볼까 ?

 

<잘못된 예시>

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityChatRoomBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(binding.mytoolBar);

        sp = getSharedPreferences(getPackageName(), MODE_PRIVATE);

        chatMsgModels = new ArrayList<>();
        chatRoom = FirebaseDatabase.getInstance().getReference(chatRoomKey);

        .....
        
        adapter = new ChatAdapter(chatMsgModels, userEmail);
        binding.rv.setLayoutManager(new LinearLayoutManager(ChatRoomActivity.this));
        binding.rv.setAdapter(adapter);

        chatRoom.orderByChild("crt_dt").startAfter(now).addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String previousChildName) {
                // Database 의 정보를 ChatMsgVO 객체에 담음
                ChatMsgModel chatMsgVO = dataSnapshot.getValue(ChatMsgModel.class);
                Log.e(TAG, "crt_dt=" + chatMsgVO.getCrt_dt()) ;
                chatMsgModels.add(chatMsgVO);

                // 채팅 메시지 배열에 담고 RecyclerView 다시 그리기
                adapter = new ChatAdapter(chatMsgModels, userEmail);
                binding.rv.setAdapter(adapter);
                binding.rv.scrollToPosition(chatMsgModels.size()-1);
                Log.e(TAG, chatMsgModels.size()+"");
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot snapshot) {

            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });

        .....
    }

흔히 하는 실수일 것 같다. adapter 을 구현해 사용하고자 하는 경우

adapter = new ChatAdapter(chatMsgModels, userEmail);  을 선언해 구현하는데,  간혹 데이터를 읽어오고 다시 넣어주는 시점에 다시 new 아덥터를 구현하는 경우 ... 위 예시와 같은 구성을 하는 경우에...

 

아래 부분 어딘가에서  adapter  을 이용한 이벤트를 실행하고자 하면, 동작을 하지 않는 것 같은 느낌이 올때가 있다. 왜 일까 ? 참 여러시간 고민을 했던 기억이 있어서 이렇게 글로 남겨 보는 건데.  new 아답터 해서 생성하는 것은 첨에 한번만 하는 것으로 해야지 위 에서와 같이 onChildAdded 내부에서 다시 new ChatAdapter 을 해서 생성하는 것은 새로 객체가 생성이 되었기 때문에 아래 부분에서 adapter.SetOnClickListener 등을 구현하게 되었을 때, 혼돈의 구렁텅이에 빠지게 될 것이다. 

 

<올바른 예시>

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityChatRoomBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(binding.mytoolBar);

        sp = getSharedPreferences(getPackageName(), MODE_PRIVATE);

        chatMsgModels = new ArrayList<>();
        chatRoom = FirebaseDatabase.getInstance().getReference(chatRoomKey);

        .....
        
        adapter = new ChatAdapter(chatMsgModels, userEmail);
        binding.rv.setLayoutManager(new LinearLayoutManager(ChatRoomActivity.this));
        binding.rv.setAdapter(adapter);

        chatRoom.orderByChild("crt_dt").startAfter(now).addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String previousChildName) {
                // Database 의 정보를 ChatMsgVO 객체에 담음
                ChatMsgModel chatMsgVO = dataSnapshot.getValue(ChatMsgModel.class);
                Log.e(TAG, "crt_dt=" + chatMsgVO.getCrt_dt()) ;
                chatMsgModels.add(chatMsgVO);

                // 채팅 메시지 배열에 담고 RecyclerView 다시 그리기
                binding.rv.setAdapter(adapter);
                binding.rv.scrollToPosition(chatMsgModels.size()-1);
                Log.e(TAG, chatMsgModels.size()+"");
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot snapshot) {

            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });

        .....
    }

이렇게 구현을 해야 그런 실수를 범하지 않게 된다.

 

오늘도 즐~

반응형