3월 16일

SJY0000·2022년 3월 16일
0

Android

목록 보기
12/15

오늘 배운 것

  • TODO프로젝트 이용해서 TODO App만들기(7)

바텀바 메뉴 완성하기

  • 할 일 목록들을 recyclerView를 이용해 만들기
  • recyclerView를 관리하기위한 Adapter가 필요함
  • (시간관계상 LocalDate 변환오류, null 에러 해결 못 함)

내 할일 프래그먼트 만들기

  • 할 일 데이터들을 아이디를 이용해 서버에서 가져오고 생성한 Adapter 클래스에 보냄
package com.example.todo.fragment.todo;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.todo.R;
import com.example.todo.domain.Todo;
import com.example.todo.domain.TodoListResult;
import com.example.todo.domain.User;
import com.example.todo.retrofit.RetrofitClient;
import com.example.todo.retrofit.TodoService;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class TodoMeFragment extends Fragment {

    public static final String TAG = "TodoMeFragment";
    private TextView tvTodoMeMsg;
    private TodoMeAdapter adapter;
    private String loginId;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.fragment_todo_me,container, false );

      Bundle bundle = getArguments();
      loginId = bundle.getString("loginId");

      // 뷰 참조 가져오기
      tvTodoMeMsg = view.findViewById(R.id.tvTodoMeMsg);
      // recyclerView는 직접사용하지 않고 최초 초기화때만 사용하고 Adapter가 주요 사용함
        RecyclerView recyclerView = view.findViewById(R.id.recyclerView);

        // Adapter 객체 생성
        adapter = new TodoMeAdapter();

        LinearLayoutManager linearLayoutManager
                = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);

        recyclerView.setLayoutManager(linearLayoutManager);

//        Random random = new Random();
//        // 샘플데이터 추가
//        for (int i = 0; i < 20; i++) {
//            Todo todo = new Todo();
//            todo.setTitle("제목 " + i);
//            todo.setDescription("설명 " + i);
//            todo.setTargetDate(LocalDate.now());
//            todo.setStatus(random.nextBoolean() ? true : false);
//
//            adapter.addItem(todo);
//        }

        // recyclerView에 Adapter 설정하기(설정하면서 자동으로 갱신)
        recyclerView.setAdapter(adapter);

        // 서버로부터 내 할일 데이터 가져오는 요청하기
        requestGetMyTodos(loginId);
      return view;
    } //onCreateView

    private void requestGetMyTodos(String loginId) {
        TodoService todoService = RetrofitClient.getTodoService();
        Call<TodoListResult> call = todoService.getTodoByUserName("me",loginId);

        call.enqueue(new Callback<TodoListResult>() {
            @Override
            public void onResponse(Call<TodoListResult> call, Response<TodoListResult> response) {
                if (!response.isSuccessful()) {
                    Log.d(TAG, "onResponse : " + response.message());
                    return;
                }
                TodoListResult todoListResult = response.body();
                setTodosAndShow(todoListResult);
            }

            @Override
            public void onFailure(Call<TodoListResult> call, Throwable t) {
            Log.d(TAG, "onFailure : " + t.getMessage());
            }
        });

    }//requestGetMyTodos

    private void setTodosAndShow(TodoListResult todoListResult) {
        //User 데이터의 존재여부 확인
        if (!todoListResult.isHasResult()) {
            tvTodoMeMsg.setVisibility(View.VISIBLE);
            return;
        }
        tvTodoMeMsg.setVisibility(View.GONE);

        // 응답받은 Result 객체에서 데이터 꺼내기
        User user = todoListResult.getUser();
        List<Todo> todoList = user.getTodolist();

        // Todo(할일) 데이터 존재여부 확인
        if (todoList == null || todoList.size() == 0) {
            return;
        }

        // Adapter에 데이터 설정하기
//        for (Todo todo : todoList) {
//            adapter.addItem(todo);
//        }
        adapter.setItems(todoList);

        // Adapter에 데이터 갱신 알리기 (아이템뷰를 다시 화면에 그려줌)
        adapter.notifyDataSetChanged();
    }// setTodosAndShow
}

Adapter 클래스

  • Adapter에서 recyclerView를 관리함
  • recyclerView는 화면에 표현되는 객체의 갯수를 자동으로 체크하고 일정 숫자의 객체를 이용하여 데이터를 출력 함으로 써 자원소비량을 낮춤
  • 순서정보를 가지고 있기 때문에 각각의 item에 접근하는 것도 가능함
package com.example.todo.fragment.todo;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.todo.R;
import com.example.todo.domain.Todo;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class TodoMeAdapter extends RecyclerView.Adapter<TodoMeAdapter.ViewHolder>{

    public static final String TAG = "TodoMeAdapter";
    // 애니메이션 효과를 위해 화면에 보여지는 아이템들보다 조금 더 생성
    private List<Todo> items = new ArrayList<>();

    // item단위 정보를 불러와서 viewHolder에 설정
    // 화면에 표현되는 객체 갯수를 자동으로 체크하여 객체 생성
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
    Context context = viewGroup.getContext();
    // 1)
    // LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    // 2)
       LayoutInflater layoutInflater = LayoutInflater.from(context);

       View itemView = layoutInflater.inflate(R.layout.todo_item, viewGroup, false);

       ViewHolder viewHolder = new ViewHolder(itemView);
      return viewHolder;
    }// onCreateViewHolder

    // 화면에 보이기 바로 직전, onCreateViewHolder에서 return한 viewHolder 값을 받음
    // position은 화면에 보이는 item들이 생성될 때마다 가지는 순서정보
    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
        Todo item = items.get(position);

        viewHolder.setItem(item);
    }// onBindViewHolder

    // 현재 item들의 갯수
    @Override
    public int getItemCount() {
        return items.size();
    }// getItemCount

   // addItem, getItem 필수
   public void addItem(Todo item) {
        items.add(item); // 제일 끝에 데이터 추가
    }
    // 선택한 데이터 순서정보 얻기
    public Todo getItem(int position) {
        return items.get(position);
    }
    // 전역변수 설정
    public void setItems(List<Todo> items) {
        this.items = items;
    }
    // 원하는 위치에 item 넣기
    public void setItem(int position, Todo item) {
        items.set(position, item);
    }

// TodoMeAdapter와 관련이 없고 위치만 안에 있고 독자적으로 존재함
     class ViewHolder extends RecyclerView.ViewHolder {

        private ImageView img1;
        private TextView tvTitle, tvtvTagetDate, tvtvDone;

        // 생성되는 item들과 연결되어있는 것이 ViewHolder
        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            img1 = itemView.findViewById(R.id.img1);
            tvTitle = itemView.findViewById(R.id.tvTitle);
            tvtvTagetDate = itemView.findViewById(R.id.tvTagetDate);
            tvtvDone = itemView.findViewById(R.id.tvDone);

            // item 클릭 이벤트 설정
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                   // 선택된 아이템의 순서정보
                    int position = getAdapterPosition();

                    Todo todo = items.get(position);
                    Toast.makeText(view.getContext(), "선택 아이템 : " + todo.toString(), Toast.LENGTH_SHORT).show();

                }
            });
        }// ViewHolder

        public void setItem(Todo item) {
            if (item == null) {
                return;
            }
            // 날짜 변환
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일");
            LocalDate localDate = item.getTargetDate();
            String strDate = dateTimeFormatter.format(localDate);

            Log.d(TAG,localDate.toString());
            Log.d(TAG,strDate);

            tvTitle.setText(item.getTitle());
            tvtvTagetDate.setText(strDate);
            tvtvDone.setText(item.isStatus() ? "완료" : "진행중");
        }// setItem
    }// ViewHolder

}// TodoMeAdapter

RetorfitClient 클래스

  • 할 일 데이터들을 받아올 Service인터페이스를 만들어 Retrofit을 준비함
    public static TodoService getTodoService() {
        TodoService todoService = getInstance().create(TodoService.class);
        return todoService;
    }

MainActivity에서 Bottom메뉴

  • Bottom 메뉴 선택 시 Bundle 객체에 아이디 정보를 담아 프래그먼트 전환 시 정보를 같이 넘김
        // Bottom 내비게이션뷰에 메뉴아이템 선택 이벤트 연결하기
        BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navi);
        bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch(item.getItemId()) {
                    case R.id.bottom_menu_mytodo:
                        Log.d(TAG, "내 할일 메뉴 선택됨");

                        Bundle bundle = new Bundle();
                        bundle.putString("loginId", loginId);

                        onFragmentChanged(TODO_ME, bundle); break;
                    case R.id.bottom_menu_alltodo: Log.d(TAG, "모든 할일 메뉴 선택됨"); break;
                    case R.id.bottom_menu_chart: Log.d(TAG, "차트 메뉴 선택됨"); break;
                }

                return false;
            }

0개의 댓글

관련 채용 정보