마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

null object reference 추가질문

0 추천

아래와 같이 viewholder안에 변수 선언을 넣었습니다. 따로 클래스로 분리 하라고 하셨는데, ViewHolder를 꼭 구현해줘야 하는데

밖으로 빼내면 에러가 생겨서 그 부분은 못했습니다.

public class RegisteredHealthLogAdapter extends RecyclerView.Adapter<RegisteredHealthLogAdapter.ViewHolder>{
    ArrayList<String> registeredLogs = new ArrayList<>();

    public class ViewHolder extends RecyclerView.ViewHolder {
        private RecyclerView recyclerView;
        private TextView textView;
        private Button button;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            textView = itemView.findViewById(R.id.registeredTextView);
            button = itemView.findViewById(R.id.addWeight);
            recyclerView = itemView.findViewById(R.id.todayLogRectyclerView);
        }

        public TextView getTextView() {
            return textView;
        }

        public Button getButton() { return button; }

        public RecyclerView getRecyclerView() { return recyclerView; }
    }

 

매력적인수박 (670 포인트) 님이 2021년 7월 23일 질문
RecyclerView가 널이라는 이야기는 todayLogRectyclerView가 잘못된 ID란 말인데요. 이것도 확인해 보셨나요? 그리고 밖으로 빼면 에러가 생긴다는 게 이해가 안가네요. 에러가 안생겨야 정상인데 말이죠.
todayLogRecyclerView는 일단 xml파일에 잘 있습니다.

public class ViewHolder extends RecyclerView.Viewholder를 밖으로 빼내면 코드 전체에 에러가 생깁니다. RegisterHealthLogAdapter에서 RecyclerView.Adapter를 상속하고 있고 ViewHolder 클래스를 필요로 해서 밖으로 빼내면 에러가 생기는 것 같습니다.
이중 recyclerView 생성하는 코드를 지우면 상위 리사이클러뷰까지는 잘 보이는데 상위 리사이클러뷰 안에 하위 리사이클러뷰 코드를 작성하면 상위 리사이클러뷰에서부터 에러가 발생하네요..
그건 님이 Generic 부분에 이전 Class type 을 참조해서 그런 겁니다. 리팩토링 메뉴를 사용하실 수 있다면 그걸 통해서 하시면 되고 아니면, 수동으로 해줘야 합니다. 이렇게 해보시라는 이유는 왜 에러가 나는지 분명히 알기 위해서 입니다.
RecyclerView.Adapter<T> 여기의 T부분과 onCreateViewHolder의 리턴타입, onBindViewHolder의 매개변수의 ViewHolder가 같은 타입이어야 합니다.
그리고 올리신 코드들 만으로는 에러가 날 부분이 없습니다. 직접적인 원인이 로그대로라면 findViewById로 RecyclerView 를 찾을 수 없다는 겁니다.

1개의 답변

0 추천
 
채택된 답변

제가 님이 올리신 코드를 기반으로 테스트 해보면 별문제 없이 잘 동작합니다. 님 소스랑 비교해 보세요. 일부 클래스 이름 등은 다를 수 있습니다.

Parent Adapter

public class RegisteredHealthLogAdapter extends RecyclerView.Adapter<RegisteredHealthLogViewHolder> {

    private List<String> items = new ArrayList<>();

    public RegisteredHealthLogAdapter(List<String> items) {
        this.items = items;
    }

    @NonNull
    @Override
    public RegisteredHealthLogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.health_registered_add, parent, false);
        return new RegisteredHealthLogViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RegisteredHealthLogViewHolder holder, int position) {
        String title = items.get(position);

        List<ChildItem> childItems = new ArrayList<>();
        childItems.add(new ChildItem("SET", "0", "0"));
        childItems.add(new ChildItem("SET", "1", "1"));
        childItems.add(new ChildItem("SET", "2", "2"));

        ChildAdapterData childAdapterData = new ChildAdapterData(title, childItems);
        holder.bind(childAdapterData);
    }

    @Override
    public int getItemCount() {
        return items.size();
    }
}

public class RegisteredHealthLogViewHolder extends RecyclerView.ViewHolder {

    private final TextView textView;
    private final Button button;
    private final RecyclerView recyclerView;

    private final HealthLogSetAdapter adapter;

    public RegisteredHealthLogViewHolder(@NonNull View itemView) {
        super(itemView);

        textView = itemView.findViewById(R.id.registeredTextView);
        button = itemView.findViewById(R.id.addWeight);
        recyclerView = itemView.findViewById(R.id.todayLogRectyclerView);

        adapter = new HealthLogSetAdapter(Collections.emptyList());
        recyclerView.setAdapter(adapter);
    }

    public void bind(ChildAdapterData data) {
        textView.setText(data.getTitle());
        adapter.setItems(data.getChildItems());
    }
}

//health_registered_add.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/registeredTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/addWeight"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="@string/add_weight" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/todayLogRectyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

</LinearLayout>

 

Child Adapter

public class HealthLogSetAdapter extends RecyclerView.Adapter<HealthLogSetViewHolder> {

    private List<ChildItem> items = new ArrayList<>();

    public HealthLogSetAdapter(List<ChildItem> items) {
        this.items = items;
    }

    public void setItems(List<ChildItem> items) {
        this.items = items;
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public HealthLogSetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.health_log_add_set, parent, false);
        return new HealthLogSetViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull HealthLogSetViewHolder holder, int position) {
        holder.bind(items.get(position));
    }

    @Override
    public int getItemCount() {
        return items.size();
    }
}


public class HealthLogSetViewHolder extends RecyclerView.ViewHolder {
    private TextView setTextView, weightTextView, repsTextView;

    public HealthLogSetViewHolder(@NonNull View itemView) {
        super(itemView);

        setTextView = itemView.findViewById(R.id.setTextView);
        weightTextView = itemView.findViewById(R.id.weightTextView);
        repsTextView = itemView.findViewById(R.id.repsTextView);
    }

    public void bind(ChildItem item) {
        setTextView.setText(item.getText1());
        weightTextView.setText(item.getText2());
        repsTextView.setText(item.getText3());
    }
}

public class ChildItem {
    private final String text1;
    private final String text2;
    private final String text3;

    public ChildItem(String text1, String text2, String text3) {
        this.text1 = text1;
        this.text2 = text2;
        this.text3 = text3;
    }

    public String getText1() {
        return text1;
    }

    public String getText2() {
        return text2;
    }

    public String getText3() {
        return text3;
    }
}

public class ChildAdapterData {
    private final String title;
    private final List<ChildItem> childItems;

    public ChildAdapterData(String title, List<ChildItem> childItems) {
        this.title = title;
        this.childItems = childItems;
    }

    public String getTitle() {
        return title;
    }

    public List<ChildItem> getChildItems() {
        return childItems;
    }
}


//health_log_add_set.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:paddingVertical="8dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/setTextView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/weightTextView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/repsTextView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>
spark (230,130 포인트) 님이 2021년 7월 23일 답변
매력적인수박님이 2021년 7월 23일 채택됨
감사합니다. 해결했습니다.
...