3月17日

62860 ワード

きょう習った

  • TODOプロジェクトを使用してTodo App(8)
  • を作成

    LocalDateの変換


    String->LocalDateクラスの作成

    public class LocalDateDeserializer implements JsonDeserializer<LocalDate> {
    
        @Override
        public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            LocalDate localDate = LocalDate.parse(json.getAsString(), DateTimeFormatter.ofPattern("yyyyMMdd"));
    
            return localDate;
        } // deserialize
    }

    LocalDate->Stringクラスの作成

        
        private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
    
        @Override
        public JsonElement serialize(LocalDate src, Type typeOfSrc, JsonSerializationContext context) {
            String strDate = FORMATTER.format(src);
            return new JsonPrimitive(strDate);

    Retrofitの作成時に変換クラスを追加

        private static Retrofit getInstance() {
            GsonBuilder gsonBuilder = new GsonBuilder();
            gsonBuilder.registerTypeAdapter(LocalDate.class, new LocalDateSerializer());
            gsonBuilder.registerTypeAdapter(LocalDate.class, new LocalDateDeserializer()); // 서버에서 넘어오는 문자열 변환
            Gson gson = gsonBuilder.setPrettyPrinting().create();
    
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://192.168.219.104:8090") // localhost 사용할 수 없기 때문에 ip주소를 적어준다
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();
    
            return retrofit;
        } // getInstance
    }

    TodoRestServiceサーバへの変換方法の追加

    	
     @Override
    	public void init(ServletConfig config) throws ServletException {
    		System.out.println("TodoRestServlet init() 호출됨");
    		GsonBuilder gsonBuilder = new GsonBuilder();
    		gsonBuilder.registerTypeAdapter(LocalDate.class, new LocalDateSerializer());
            gsonBuilder.registerTypeAdapter(LocalDate.class, new LocalDateDeserializer());
    		gson = gsonBuilder.setPrettyPrinting().create(); // json 줄바꿈 출력
    	}

    各項目ビュー

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        
        <TextView
            android:id="@+id/tvTodoMeMsg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="데이터가 없습니다."
            android:textAlignment="center"
            android:textSize="24sp"
            android:textStyle="bold"
            android:visibility="gone" />
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>


    「≪新規保留中の追加|Add New Pending|emdw≫」ボタンを作成し、ユーザー名とIDを指定します。



    ボタンをクリックすると、bundleオブジェクトにloginId値が挿入され、「保留中の追加」画面に移動します.
            btnTodoAdd.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    MainActivity mainActivity = (MainActivity) getActivity();
                    Bundle extraBundle = new Bundle();
                    extraBundle.putString("loginId", loginId);
    
                    mainActivity.onFragmentChanged(MainActivity.TODO_ADD, extraBundle);
                }
            });
    TextViewで名前とアイデンティティを同時に出力
        private void setTodosAndShow(TodoListResult todoListResult) {
            // 응답받은 Result 객체에서 데이터 꺼내기
            User user = todoListResult.getUser();
            String username = user.getFirstName() + " " + user.getLastName() + " (" + user.getUserName() + ")";
            tvUsername.setText(username);
    
            List<Todo> todoList = user.getTodolist();
    
            // Todo(할일) 데이터 존재여부 확인
            if (todoList == null || todoList.size() == 0) {
                tvTodoMeMsg.setVisibility(View.VISIBLE);
                return;
            }
            tvTodoMeMsg.setVisibility(View.GONE);
            // Adapter에 데이터 설정하기
    //        for (Todo todo : todoList) {
    //            adapter.addItem(todo);
    //        }
            adapter.setItems(todoList);
    
            // Adapter에 데이터 갱신 알리기 (recyclerView가 변경된 데이터로 아이템뷰를 다시 화면에 그려줌)
            adapter.notifyDataSetChanged();
        }// setTodosAndShow

    新規保留画面の追加

  • のスピナーを使用する進行中であり、完了した現在のステータス
  • を表示するように設定.
  • 日付選択ボックスクリック時に日付選択ウィンドウが表示する入力フォーマット
  • が設定される.
  • サーバ接続遅延は、応答遅延を防ぐために、累進ダイヤルを使用して処理中であることを示します.
  • サーバ転送処理のProgressDialogを正常にシャットダウンし、「マイワーク」ページ
  • に移動
    package com.example.todo.fragment.todo;
    
    import android.app.DatePickerDialog;
    import android.app.ProgressDialog;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.DatePicker;
    import android.widget.EditText;
    import android.widget.Spinner;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    
    import com.example.todo.MainActivity;
    import com.example.todo.R;
    import com.example.todo.domain.Todo;
    import com.example.todo.domain.TodoResult;
    import com.example.todo.retrofit.RetrofitClient;
    import com.example.todo.retrofit.TodoService;
    
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.Calendar;
    
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    
    public class TodoAddFragment extends Fragment {
        public static final String TAG = "TodoAddFragment";
        private EditText txtTitle, txtDescription, txtTargetDate;
        private String loginId;
        private Spinner spinnerStatus;
        private DatePickerDialog datePickerDialog;
        private ProgressDialog progressDialog; // 비동기 방식으로 동작함
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_todo_add,container, false );
    
            // Bundle 객체 참조 가져오기
            Bundle bundle = getArguments();
            loginId = bundle.getString("loginId");
    
            txtTitle = view.findViewById(R.id.txtTitle);
            txtDescription = view.findViewById(R.id.txtDescription);
            txtTargetDate = view.findViewById(R.id.txtTargetDate);
            spinnerStatus = view.findViewById(R.id.spinnerStatus);
    
            // spinner 전용 Adapter라고 생각하면 됨
            // android.R.layout.simple_spinner_item은 처음 보여지는 item
            // android.R.layout.simple_spinner_dropdown_item 밑에 보여지는 item
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                    getContext(),
                    android.R.layout.simple_spinner_item,
                    new String[] {"진행중", "완료"}
            );
            // Spinner 클릭 시 펼쳐질 layout 설정
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            // Spinner에 Adapter 설정
            spinnerStatus.setAdapter(adapter);
            // 날짜 선택 EditText에 Touch 이벤트 연결
            txtTargetDate.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                        // DatePickerDialog 띄우기기
                        datePickerDialog.show();
                   }
                    return false;
                }
            });
    
            // 현재 년,월,일 값구하기
            Calendar calendar = Calendar.getInstance();
            int nowYear = calendar.get(Calendar.YEAR);
            int nowMonth = calendar.get(Calendar.MONTH); // 영미권은 0~11, 출력할 때는 +1을 해줘야함 (ex 1월 = 0, 2월 = 1)
            int nowDay = calendar.get(Calendar.DAY_OF_MONTH);
    
            //날짜선택 대화상자 준비하기
            datePickerDialog = new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() {
                @Override // 최종 결정할 때 호출됨
                public void onDateSet(DatePicker datePicker, int year, int month, int day) {
                    String strDate = "";
                    strDate += year;
                    strDate += "-" + String.format("%02d", month + 1); // 2자리 숫자로 만드는데 한자리면 앞에 0을 붙임
                    strDate += "-" + String.format("%02d", day);
    
                    txtTargetDate.setText(strDate);
                }// onDateSet
            },nowYear, nowMonth, nowDay);
    
            // progressDialog 설정하기
            progressDialog = new ProgressDialog(getContext());
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setMessage("처리 중 입니다....");
    
            // 할 일 저장 버튼 클릭 이벤트 연결
            Button btnTodoSave = view.findViewById(R.id.btnTodoSave);
            btnTodoSave.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    btnTodoSave.setEnabled(false); // 버튼 비활성화
                    progressDialog.show(); // 로딩 중
                    requestAddTodo(); // 서버에 새 Todo 등록
    
                }
            });
    
            return view;
        } // onCreateView
        private void requestAddTodo() {
    
            String title = txtTitle.getText().toString().trim();
            String description = txtDescription.getText().toString().trim();
            String strStatus = (String) spinnerStatus.getSelectedItem();
            String strDate = txtTargetDate.getText().toString().trim();
    
    
            // localDate 변환
            LocalDate localDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    
            // 추가할 Todo 객체 준비
            Todo todo = new Todo();
            todo.setUsername(loginId);
            todo.setTitle(title);
            todo.setDescription(description);
            todo.setStatus(strStatus.equals("완료")? true : false);
            todo.setTargetDate(localDate);
    
            Log.d(TAG, "todo : " + todo.toString());
    
            TodoService todoService = RetrofitClient.getTodoService();
    
            Call<TodoResult> call = todoService.addTodo(todo);
    
            call.enqueue(new Callback<TodoResult>() {
                @Override
                public void onResponse(Call<TodoResult> call, Response<TodoResult> response) {
                    if (!response.isSuccessful()) {
                        Log.d(TAG,"onResponse : " + response.message());
                        return;
                    }
                    TodoResult todoResult = response.body();
    
                    if (todoResult.isSuccess()) {
                        onResponseSuccess();
                    }
                }
    
                @Override
                public void onFailure(Call<TodoResult> call, Throwable t) {
                    Log.d(TAG, "onFailure : " + t.getMessage());
                }
            });
    
        }// requestAddTodo
    
        private void onResponseSuccess() {
            progressDialog.dismiss(); // progressDialog 닫기
    
            Bundle bundle = new Bundle();
            bundle.putString("loginId", loginId);
    
            MainActivity mainActivity = (MainActivity) getActivity();
            mainActivity.onFragmentChanged(MainActivity.TODO_ME, bundle);
        }// onResponseSuccess
    
    }