From 9f272e5579dde3211990c8ebd31b125e1de9fb1a Mon Sep 17 00:00:00 2001 From: dkyuuum Date: Mon, 19 Feb 2024 20:16:38 +0900 Subject: [PATCH 1/5] =?UTF-8?q?Design:=20=ED=99=88=20margin=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/deploymentTargetDropDown.xml | 4 +- .../mobile/project/ui/home/HomeFragment.kt | 11 +++-- app/src/main/res/layout/activity_login.xml | 6 ++- app/src/main/res/layout/fragment_home.xml | 41 ++++------------- app/src/main/res/values-night/themes.xml | 46 +++++++++++++++++-- app/src/main/res/values/themes.xml | 5 ++ 6 files changed, 67 insertions(+), 46 deletions(-) diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 401569e5..52cce6f8 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -7,11 +7,11 @@ - + - + \ No newline at end of file diff --git a/app/src/main/java/umc/com/mobile/project/ui/home/HomeFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/home/HomeFragment.kt index ce980b49..6987dc85 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/home/HomeFragment.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/home/HomeFragment.kt @@ -61,6 +61,9 @@ class HomeFragment : Fragment() { binding.layoutNextPlan.setOnClickListener { navigate(R.id.action_fragment_home_to_planSettingFragment) } + binding.constraintLayout3.setOnClickListener { + navigate(R.id.action_fragment_home_to_planSettingFragment) + } } private fun setupRecyclerView() { @@ -87,11 +90,9 @@ class HomeFragment : Fragment() { /** * 기본 정보 */ - binding.tvName.text = it?.result?.name - binding.tvStdId.text = it?.result?.id.toString() - binding.tvSchool.text = it?.result?.department - binding.tvGrade.text = it?.result?.grade - binding.tvStatus.text = it?.result?.status + binding.tvNameStdId.text = "${it?.result?.name} ${it?.result?.id.toString()}" + binding.tvSchool.text = "한성대학교 ${it?.result?.department}" + binding.tvGradeStatus.text = "${it?.result?.grade} ${it?.result?.status}" binding.tvGraduateDday.text = it?.result?.dday.toString() binding.tvCheeringWord.text = it?.result?.message diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 29b250bb..7b854dcb 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -74,7 +74,8 @@ android:paddingTop="18dp" android:paddingBottom="18dp" android:singleLine="true" - android:text="@={vm.id}" /> + android:text="@={vm.id}" + android:theme="@style/EditText.DarkMode" /> @@ -114,7 +115,8 @@ android:paddingTop="18dp" android:paddingBottom="18dp" android:singleLine="true" - android:text="@={vm.pw}" /> + android:text="@={vm.pw}" + android:theme="@style/EditText.DarkMode" /> diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 315c3a26..f2c0a06e 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -107,7 +107,7 @@ - - - - + app:layout_constraintTop_toBottomOf="@+id/tv_name_stdId" /> + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 676b1094..06dbe6fc 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -44,4 +44,9 @@ @drawable/custom_dialog_background @android:color/transparent + + + \ No newline at end of file From 0677c83c294a1c76b9a2b33d5c42caf99ee06f68 Mon Sep 17 00:00:00 2001 From: dkyuuum Date: Mon, 19 Feb 2024 21:28:46 +0900 Subject: [PATCH 2/5] =?UTF-8?q?Fix:=20=ED=99=88=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/fragment_grade.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/layout/fragment_grade.xml b/app/src/main/res/layout/fragment_grade.xml index d3beceda..3c243624 100644 --- a/app/src/main/res/layout/fragment_grade.xml +++ b/app/src/main/res/layout/fragment_grade.xml @@ -326,7 +326,6 @@ android:layout_height="wrap_content" android:layout_marginStart="10dp" android:layout_marginTop="9dp" - android:background="@color/selector_selected_gray_else_white" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tv_grade_average_title" tools:listitem="@layout/item_average_grade" /> From b90d4ef30002615aca21ba34031c941002b72e24 Mon Sep 17 00:00:00 2001 From: dkyuuum Date: Mon, 19 Feb 2024 22:08:34 +0900 Subject: [PATCH 3/5] =?UTF-8?q?Design:=20=EC=A1=B8=EC=97=85=20=EC=9A=94?= =?UTF-8?q?=EA=B1=B4/=EC=84=B1=EC=A0=81=20=EC=82=AC=ED=95=AD=20item=20widt?= =?UTF-8?q?h=20=EC=A1=B0=EC=A0=95=20#21?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/fragment_grade.xml | 47 +++++++++++-------- .../main/res/layout/item_average_grade.xml | 10 ++-- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/app/src/main/res/layout/fragment_grade.xml b/app/src/main/res/layout/fragment_grade.xml index 3c243624..f3a597d5 100644 --- a/app/src/main/res/layout/fragment_grade.xml +++ b/app/src/main/res/layout/fragment_grade.xml @@ -326,6 +326,8 @@ android:layout_height="wrap_content" android:layout_marginStart="10dp" android:layout_marginTop="9dp" + android:layout_marginBottom="13dp" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tv_grade_average_title" tools:listitem="@layout/item_average_grade" /> @@ -334,7 +336,6 @@ android:id="@+id/layout_average" android:layout_width="0dp" android:layout_height="0dp" - android:layout_marginStart="9dp" android:layout_marginTop="15dp" android:layout_marginEnd="19dp" android:background="@drawable/bg_stroke_gray_radius_16_5" @@ -347,30 +348,36 @@ app:layout_constraintStart_toEndOf="@+id/recyclerView2" app:layout_constraintTop_toBottomOf="@+id/tv_grade_average_title"> - + app:layout_constraintTop_toTopOf="parent"> + + + + + + - diff --git a/app/src/main/res/layout/item_average_grade.xml b/app/src/main/res/layout/item_average_grade.xml index 07d94c89..960c0b3d 100644 --- a/app/src/main/res/layout/item_average_grade.xml +++ b/app/src/main/res/layout/item_average_grade.xml @@ -11,20 +11,24 @@ From 1623cec50e03fe5908d32e66ba73e4dc2c9f9696 Mon Sep 17 00:00:00 2001 From: dkyuuum Date: Mon, 19 Feb 2024 22:15:13 +0900 Subject: [PATCH 4/5] =?UTF-8?q?Fix:=20=ED=96=A5=ED=9B=84=EA=B3=84=ED=9A=8D?= =?UTF-8?q?/=EC=8B=9C=EA=B0=84=ED=91=9C=20=EC=84=B1=EC=A0=81=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20=ED=83=AD=20=EC=9D=B4=EB=8F=99=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project/ui/plan/PlanSemesterFragment.kt | 94 +++++++------------ .../project/ui/plan/PlanSettingFragment.kt | 79 +++++++++------- .../project/ui/plan/PlanTimeFragment.kt | 68 +++++++------- .../main/res/navigation/mobile_navigation.xml | 8 -- 4 files changed, 115 insertions(+), 134 deletions(-) diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterFragment.kt index c173abbd..03e82f7b 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterFragment.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterFragment.kt @@ -1,74 +1,50 @@ package umc.com.mobile.project.ui.plan -import android.content.res.ColorStateList import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels -import androidx.gridlayout.widget.GridLayout -import umc.com.mobile.project.R -import umc.com.mobile.project.databinding.FragmentPlanlicenseBinding -import android.widget.EditText -import androidx.core.view.setMargins import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager - -import umc.com.mobile.project.data.model.plan.SavelicenseRequest import umc.com.mobile.project.data.model.plan.semesterResult import umc.com.mobile.project.databinding.SemesterChooseBinding -import java.time.LocalDate class PlanSemesterFragment : Fragment() { - private var _binding: SemesterChooseBinding? = null - private val viewModel: PlanViewModel by viewModels() - private val binding get() = _binding!! - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - _binding = SemesterChooseBinding.inflate(inflater, container, false) - - - - - - return binding.root - } - - - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - - val adapter = PlanSemesterAdapter(listOf()) // 초기 데이터로 빈 리스트 사용 - - // RecyclerView에 어댑터와 레이아웃 매니저 설정 - binding.recyclerViewPlanSemester.adapter = adapter - binding.recyclerViewPlanSemester.layoutManager = LinearLayoutManager(context) - - - viewModel.planSemesterInfo.observe(viewLifecycleOwner) { semesterInfo -> - // 데이터가 업데이트되면 어댑터의 리스트 업데이트 - adapter.semesterList = semesterInfo?.result ?: emptyList() - adapter.notifyDataSetChanged() - - } - - viewModel.getSemesterInfo() // 데이터 로드 - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } + private var _binding: SemesterChooseBinding? = null + private val viewModel: PlanViewModel by viewModels() + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = SemesterChooseBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val adapter = PlanSemesterAdapter(emptyList()) // 초기 데이터로 빈 리스트 사용 + + // RecyclerView에 어댑터와 레이아웃 매니저 설정 + binding.recyclerViewPlanSemester.adapter = adapter + binding.recyclerViewPlanSemester.layoutManager = LinearLayoutManager(context) + + viewModel.planSemesterInfo.observe(viewLifecycleOwner) { semesterInfo -> + // 데이터가 업데이트되면 어댑터의 리스트 업데이트 + adapter.semesterList = semesterInfo?.result ?: emptyList() + adapter.notifyDataSetChanged() + } + + viewModel.getSemesterInfo() // 데이터 로드 + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } - - diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSettingFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSettingFragment.kt index 51b01b19..28ed2e9b 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSettingFragment.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSettingFragment.kt @@ -7,67 +7,76 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Observer +import androidx.navigation.fragment.findNavController import androidx.viewpager.widget.ViewPager import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator +import umc.com.mobile.project.R import umc.com.mobile.project.databinding.FragmentSettingBinding +import umc.com.mobile.project.databinding.PlanSubjectListBinding import umc.com.mobile.project.databinding.PlanTimeTabMainBinding +import umc.com.mobile.project.databinding.SemesterChooseBinding import umc.com.mobile.project.ui.gradInfo.adapter.GradInfoVPAdapter import umc.com.mobile.project.ui.gradInfo.viewmodel.GradInfoViewModel class PlanSettingFragment : Fragment() { - private var _binding:PlanTimeTabMainBinding? = null - private val viewModel: PlanViewModel by viewModels() - private val binding get() = _binding!! + private var _binding: PlanTimeTabMainBinding? = null + private val viewModel: PlanViewModel by viewModels() + private val binding get() = _binding!! - private lateinit var viewPager : ViewPager2 - private lateinit var tabLayout : TabLayout + private lateinit var viewPager: ViewPager2 + private lateinit var tabLayout: TabLayout - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - _binding = PlanTimeTabMainBinding.inflate(inflater, container, false) + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + // PlanTimeTabMainBinding을 인플레이트하여 루트 뷰를 가져옴 + _binding = PlanTimeTabMainBinding.inflate(inflater, container, false) + val view = binding.root - initTabLayout() - initViewPager() - return binding.root - } + // 탭 레이아웃 및 뷰페이저 초기화 + initTabLayout() + initViewPager() - private fun initTabLayout() { + return view + } - val tabTitle = arrayOf("시간표", "자격증", "자유") + private fun initTabLayout() { - viewPager = binding.viewPagerTimeTabMain - tabLayout = binding.tabLayoutPlanTime + val tabTitle = arrayOf("시간표", "자격증", "자유") - val adapter = PlanVPAdapter(this) + viewPager = binding.viewPagerTimeTabMain + tabLayout = binding.tabLayoutPlanTime - adapter.addFragment(PlanTimeFragment()) - adapter.addFragment(PlanlicenseFragment()) - adapter.addFragment(PlanFreeFragment()) - viewPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL - viewPager.adapter = adapter + val adapter = PlanVPAdapter(this) - TabLayoutMediator(tabLayout, viewPager - ) { tab, position -> tab.text = tabTitle[position] }.attach() - } + adapter.addFragment(PlanTimeFragment()) + adapter.addFragment(PlanlicenseFragment()) + adapter.addFragment(PlanFreeFragment()) - private fun initViewPager() { + viewPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL + viewPager.adapter = adapter - binding.viewPagerTimeTabMain.isUserInputEnabled = false - } + TabLayoutMediator(tabLayout, viewPager + ) { tab, position -> tab.text = tabTitle[position] }.attach() + } + private fun initViewPager() { - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } + binding.viewPagerTimeTabMain.isUserInputEnabled = false + } + + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } \ No newline at end of file diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeFragment.kt index 8def1b7a..e0ed2c64 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeFragment.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeFragment.kt @@ -17,54 +17,56 @@ import umc.com.mobile.project.ui.common.NavigationUtil.navigate import umc.com.mobile.project.ui.plan.PlanViewModel class PlanTimeFragment : Fragment() { - private var _binding: PlanSubjectListBinding? = null - private val viewModel: PlanViewModel by viewModels() - private val binding get() = _binding!! + private var _binding: PlanSubjectListBinding? = null + private val viewModel: PlanViewModel by viewModels() + private val binding get() = _binding!! - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View { - _binding = PlanSubjectListBinding.inflate(inflater, container, false) + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View { + _binding = PlanSubjectListBinding.inflate(inflater, container, false) - viewModel.getListTimeInfo() - val adapter = viewModel.listTimeInfo.value?.let { PlanRecyclerAdapter(it.result) } + viewModel.getListTimeInfo() + val adapter = viewModel.listTimeInfo.value?.let { PlanRecyclerAdapter(it.result) } - binding.recyclerView.adapter = adapter - binding.recyclerView.layoutManager = - LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + binding.recyclerView.adapter = adapter + binding.recyclerView.layoutManager = + LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) - viewModel.listTimeInfo.observe(viewLifecycleOwner) { timenewList -> - if (timenewList != null) { - if (adapter != null) { - adapter.timeList=timenewList.result - adapter.notifyDataSetChanged() - } - } + viewModel.listTimeInfo.observe(viewLifecycleOwner) { timenewList -> + if (timenewList != null) { + if (adapter != null) { + adapter.timeList=timenewList.result + adapter.notifyDataSetChanged() + } + } - } + } + _binding!!.planSubjectListSemester.setOnClickListener { + //api 연결 +// viewModel.addCareer() + navigate(R.id.action_planSettingFragment_to_planSemesterFragment) + } - return binding.root - } + return binding.root - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) - binding.planSubjectListSemester.setOnClickListener { + } - findNavController().navigate(R.id.action_planTimeFragment_to_planSemesterFragment) - } - } @@ -72,9 +74,11 @@ class PlanTimeFragment : Fragment() { - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } + + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index 0323287e..49a03376 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -246,13 +246,5 @@ android:id="@+id/planSemesterFragment" android:name="umc.com.mobile.project.ui.plan.PlanSemesterFragment" android:label="PlanSemesterFragment" /> - - - \ No newline at end of file From e86564dd0dab57dda8afff894702b0759f14f60e Mon Sep 17 00:00:00 2001 From: dkyuuum Date: Mon, 19 Feb 2024 23:41:39 +0900 Subject: [PATCH 5/5] =?UTF-8?q?Feat:=20=ED=96=A5=ED=9B=84=20=EA=B3=84?= =?UTF-8?q?=ED=9A=8D/=EC=8B=9C=EA=B0=84=ED=91=9C=20=EA=B3=BC=EB=AA=A9,=20?= =?UTF-8?q?=ED=8A=B8=EB=9E=99=20=EA=B2=80=EC=83=89=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?#50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project/data/model/plan/AddTimeRequest.kt | 18 ++ .../data/model/plan/AddTimeResponse.kt | 19 +- .../model/plan/CertificateLicenseRequest.kt | 7 + .../data/model/plan/EditMemoRequest.kt | 6 + .../data/model/plan/PlanFreeRequest.kt | 6 + .../data/model/plan/PlanFreeResponse.kt | 13 + .../project/data/network/api/PlanApi.kt | 41 ++- .../project/ui/plan/PlanFreeFragment.kt | 42 ++- .../project/ui/plan/PlanRecyclerAdapter.kt | 47 +-- .../project/ui/plan/PlanSemesterAdapter.kt | 19 +- .../project/ui/plan/PlanSemesterFragment.kt | 83 +++--- .../project/ui/plan/PlanSettingFragment.kt | 100 ++++--- .../mobile/project/ui/plan/PlanTimeAdapter.kt | 44 +++ .../project/ui/plan/PlanTimeFragment.kt | 137 +++++---- .../project/ui/plan/PlanTimetableFragment.kt | 95 ++++++ .../project/ui/plan/PlanTrackAdapter.kt | 20 +- .../project/ui/plan/PlanTrackFragment.kt | 74 +++-- .../mobile/project/ui/plan/PlanViewModel.kt | 270 +++++++++++++++--- .../project/ui/plan/PlanlicenseFragment.kt | 3 +- app/src/main/res/drawable/plan_time_back.xml | 13 + .../res/drawable/plan_time_move_table.xml | 11 + .../main/res/layout/fragment_plan_free.xml | 44 +-- app/src/main/res/layout/item_time_subject.xml | 12 +- app/src/main/res/layout/plan_subject_list.xml | 117 ++++---- .../res/layout/plan_time_choose_track.xml | 3 +- app/src/main/res/layout/plan_time_main.xml | 45 ++- app/src/main/res/layout/semester_choose.xml | 39 +-- .../main/res/navigation/mobile_navigation.xml | 35 ++- 28 files changed, 983 insertions(+), 380 deletions(-) create mode 100644 app/src/main/java/umc/com/mobile/project/data/model/plan/AddTimeRequest.kt create mode 100644 app/src/main/java/umc/com/mobile/project/data/model/plan/CertificateLicenseRequest.kt create mode 100644 app/src/main/java/umc/com/mobile/project/data/model/plan/EditMemoRequest.kt create mode 100644 app/src/main/java/umc/com/mobile/project/data/model/plan/PlanFreeRequest.kt create mode 100644 app/src/main/java/umc/com/mobile/project/data/model/plan/PlanFreeResponse.kt create mode 100644 app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeAdapter.kt create mode 100644 app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimetableFragment.kt create mode 100644 app/src/main/res/drawable/plan_time_back.xml create mode 100644 app/src/main/res/drawable/plan_time_move_table.xml diff --git a/app/src/main/java/umc/com/mobile/project/data/model/plan/AddTimeRequest.kt b/app/src/main/java/umc/com/mobile/project/data/model/plan/AddTimeRequest.kt new file mode 100644 index 00000000..fd852fd6 --- /dev/null +++ b/app/src/main/java/umc/com/mobile/project/data/model/plan/AddTimeRequest.kt @@ -0,0 +1,18 @@ +package umc.com.mobile.project.data.model.plan + +data class AddTimeRequest( +val semesterDto: SemesterDto, +val subjectDtoList: List, +) + +data class SemesterDto( + val grade: Long, + val semester: Long, +) + +data class SubjectDtoList( + val type: String, + val name: String, + val credit: String, +) + diff --git a/app/src/main/java/umc/com/mobile/project/data/model/plan/AddTimeResponse.kt b/app/src/main/java/umc/com/mobile/project/data/model/plan/AddTimeResponse.kt index 44890c9c..e210bcae 100644 --- a/app/src/main/java/umc/com/mobile/project/data/model/plan/AddTimeResponse.kt +++ b/app/src/main/java/umc/com/mobile/project/data/model/plan/AddTimeResponse.kt @@ -1,18 +1,17 @@ package umc.com.mobile.project.data.model.plan data class AddTimeResponse( -val semesterDto: SemesterDto, -val subjectDtoList: List, + val isSuccess: Boolean, + val code: String, + val message: String, + val result: AddResponseResult ) -data class SemesterDto( - val grade: Long, - val semester: Long, +data class AddResponseResult( + val addResponseDtos: List ) -data class SubjectDtoList( - val type: String, - val name: String, - val credit: Long, +data class AddResponseDto( + val subjectId: Long, + val createdAt: String ) - diff --git a/app/src/main/java/umc/com/mobile/project/data/model/plan/CertificateLicenseRequest.kt b/app/src/main/java/umc/com/mobile/project/data/model/plan/CertificateLicenseRequest.kt new file mode 100644 index 00000000..4a49f7ef --- /dev/null +++ b/app/src/main/java/umc/com/mobile/project/data/model/plan/CertificateLicenseRequest.kt @@ -0,0 +1,7 @@ +package umc.com.mobile.project.data.model.plan + +data class CertificateLicenseRequest( + val certificateId: Long, + val name: String, + val date: String +) diff --git a/app/src/main/java/umc/com/mobile/project/data/model/plan/EditMemoRequest.kt b/app/src/main/java/umc/com/mobile/project/data/model/plan/EditMemoRequest.kt new file mode 100644 index 00000000..20fa4b33 --- /dev/null +++ b/app/src/main/java/umc/com/mobile/project/data/model/plan/EditMemoRequest.kt @@ -0,0 +1,6 @@ +package umc.com.mobile.project.data.model.plan + +data class EditMemoRequest( + val memo: String +) + diff --git a/app/src/main/java/umc/com/mobile/project/data/model/plan/PlanFreeRequest.kt b/app/src/main/java/umc/com/mobile/project/data/model/plan/PlanFreeRequest.kt new file mode 100644 index 00000000..953dfb79 --- /dev/null +++ b/app/src/main/java/umc/com/mobile/project/data/model/plan/PlanFreeRequest.kt @@ -0,0 +1,6 @@ +package umc.com.mobile.project.data.model.plan + +data class PlanFreeRequest( + val memo: String, +) + diff --git a/app/src/main/java/umc/com/mobile/project/data/model/plan/PlanFreeResponse.kt b/app/src/main/java/umc/com/mobile/project/data/model/plan/PlanFreeResponse.kt new file mode 100644 index 00000000..ac41ce3c --- /dev/null +++ b/app/src/main/java/umc/com/mobile/project/data/model/plan/PlanFreeResponse.kt @@ -0,0 +1,13 @@ +package umc.com.mobile.project.data.model.plan + +data class PlanFreeResponse( + val isSuccess: Boolean, + val code: String, + val message: String, + val result: FreeInfo, +) + +data class FreeInfo( + val memo: String, +) + diff --git a/app/src/main/java/umc/com/mobile/project/data/network/api/PlanApi.kt b/app/src/main/java/umc/com/mobile/project/data/network/api/PlanApi.kt index 61e5b44c..614f3748 100644 --- a/app/src/main/java/umc/com/mobile/project/data/network/api/PlanApi.kt +++ b/app/src/main/java/umc/com/mobile/project/data/network/api/PlanApi.kt @@ -3,35 +3,56 @@ package umc.com.mobile.project.data.network.api import retrofit2.http.GET import retrofit2.Call import retrofit2.http.Body +import retrofit2.http.PATCH import retrofit2.http.POST import retrofit2.http.Query +import umc.com.mobile.project.data.model.plan.AddTimeRequest +import umc.com.mobile.project.data.model.plan.AddTimeResponse import umc.com.mobile.project.data.model.plan.BringlicenseResponse import umc.com.mobile.project.data.model.plan.ListTimeResponse +import umc.com.mobile.project.data.model.plan.PlanFreeRequest +import umc.com.mobile.project.data.model.plan.PlanFreeResponse import umc.com.mobile.project.data.model.plan.PlanTrackResponse import umc.com.mobile.project.data.model.plan.SaveInfo import umc.com.mobile.project.data.model.plan.SemesterTimeResponse import umc.com.mobile.project.data.model.plan.UPlicenseResponse +import umc.com.mobile.project.data.model.plan.EditMemoRequest interface PlanApi { - @GET("plans/certifications") - fun getUPlicense(): Call + @GET("plans/certifications") + fun getUPlicense(): Call - @POST("plans/certifications") - fun saveLicense(@Body request: List): Call + @POST("plans/certifications") + fun saveLicense(@Body request: List): Call - @GET("/plans/timetable/searchSubject") - fun getListTime(@Query("hakki") hakki:String, @Query("track") track : String) : Call + @GET("/plans/timetable/searchSubject") + fun getListTime(@Query("hakki") hakki:String, @Query("track") track : String) : Call + + @GET("/plans/timetable/searchTrack") + fun getTrackInfo(@Query("hakki") hakki: String) : Call + + @GET("/plans/timetable/searchHakki") + fun getSemesterInfo():Call + + @POST("/plans/timetable") + fun addTime(@Body addTimeRequest: AddTimeRequest): Call + + @GET("/plans/memo") + fun getFreeInfo() : Call + + @POST("/plans/memo") + fun postFreeMemo(@Body request: PlanFreeRequest): Call + + @PATCH("/plans/memo") + fun editMemo(@Body editMemoRequest: EditMemoRequest) : Call + - @GET("/plans/timetable/searchTrack") - fun getTrackInfo(@Query("hakki") hakki: String) : Call - @GET("/plans/timetable/searchHakki") - fun getSemesterInfo():Call diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanFreeFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanFreeFragment.kt index 9e52d868..ae8e0a56 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanFreeFragment.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanFreeFragment.kt @@ -4,14 +4,17 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels +import umc.com.mobile.project.data.model.plan.PlanFreeRequest import umc.com.mobile.project.databinding.FragmentPlanFreeBinding import umc.com.mobile.project.ui.plan.PlanViewModel class PlanFreeFragment : Fragment() { private var _binding: FragmentPlanFreeBinding? = null - private val viewModel: PlanViewModel by viewModels() + private val viewModel: PlanViewModel by activityViewModels() private val binding get() = _binding!! override fun onCreateView( @@ -19,11 +22,39 @@ class PlanFreeFragment : Fragment() { ): View { _binding = FragmentPlanFreeBinding.inflate(inflater, container, false) - viewModel.text.observe(viewLifecycleOwner) { text -> - // Update your UI here with the LiveData update - // Make sure 'textViewExample' matches the ID of the TextView in your layout -// binding.textViewExample.text = text + // 버튼 클릭 이벤트 설정 + binding.freeStoreButton.setOnClickListener { + val memoText = binding.planFreeMemo.text.toString() + if (memoText.isNotEmpty()) { + viewModel.postMemo(PlanFreeRequest(memo = memoText)) + } } + + // 메모 저장 결과 관찰 + viewModel.postMemoResult.observe(viewLifecycleOwner) { isSuccess -> + if (isSuccess) { + Toast.makeText(context, "메모가 성공적으로 저장되었습니다.", Toast.LENGTH_SHORT).show() + viewModel.getFreeInfo() // 저장 후 메모 정보 다시 불러오기 + } else { + Toast.makeText(context, "메모 저장에 실패했습니다.", Toast.LENGTH_SHORT).show() + } + } + + // 저장된 메모 정보를 불러와서 EditText에 표시 + viewModel.planFreeInfo.observe(viewLifecycleOwner) { planFreeResponse -> + planFreeResponse?.result?.memo?.let { + binding.planFreeMemo.setText(it) + } + } + + binding.editMemo.setOnClickListener { + val memoText = binding.planFreeMemo.text.toString() + if (memoText.isNotEmpty()) { + viewModel.editMemo(memoText) // 수정된 메모를 서버에 전송 + } + } + + return binding.root } @@ -32,3 +63,4 @@ class PlanFreeFragment : Fragment() { _binding = null } } + diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanRecyclerAdapter.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanRecyclerAdapter.kt index b7dad88a..57440ad9 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanRecyclerAdapter.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanRecyclerAdapter.kt @@ -10,30 +10,39 @@ import umc.com.mobile.project.data.model.plan.TimeResult import umc.com.mobile.project.databinding.ItemCertificateBinding import umc.com.mobile.project.databinding.ItemTimeSubjectBinding -class PlanRecyclerAdapter( timeList: List): RecyclerView.Adapter(){ - var timeList: List = timeList - set(value) { - field = value - notifyDataSetChanged() - //데이터가 바뀌었다 알려줌. - } - +class PlanRecyclerAdapter( + private var timeList: List, + private val onAddButtonClicked: ((TimeResult?) -> Unit)? = null +) : RecyclerView.Adapter() { - override fun getItemCount(): Int { - return timeList?.size ?: 0 + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NonSubjectViewHolder { + val itemBinding = ItemTimeSubjectBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return NonSubjectViewHolder(itemBinding) } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlanRecyclerAdapter.NonSubjectViewHolder { - val itemBinding = ItemTimeSubjectBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return PlanRecyclerAdapter.NonSubjectViewHolder(itemBinding) + override fun onBindViewHolder(holder: NonSubjectViewHolder, position: Int) { + val timeResult = timeList[position] + holder.bind(timeResult, onAddButtonClicked) } - override fun onBindViewHolder(holder: PlanRecyclerAdapter.NonSubjectViewHolder, position: Int) { + override fun getItemCount(): Int = timeList.size - holder.itemBinding.timeItemScore.text =timeList[position]?.searchCredit.toString() - holder.itemBinding.timeItemSemester.text =timeList[position]?.searchGrade.toString() - holder.itemBinding.timeItemSubject.text = timeList[position]?.searchName.toString() + fun updateTimeList(newTimeList: List) { + this.timeList = newTimeList + notifyDataSetChanged() // 데이터가 변경되었음을 알리고 UI를 갱신 } - class NonSubjectViewHolder(val itemBinding: ItemTimeSubjectBinding) : RecyclerView.ViewHolder(itemBinding.root) -} \ No newline at end of file + class NonSubjectViewHolder(private val itemBinding: ItemTimeSubjectBinding) : RecyclerView.ViewHolder(itemBinding.root) { + fun bind(timeResult: TimeResult?, onAddButtonClicked: ((TimeResult?) -> Unit)?) { + itemBinding.timeItemSubject.text=timeResult?.searchName.toString() + itemBinding.timeItemSemester.text = timeResult?.searchGrade.toString() + val divisionAndCredit = "${timeResult?.searchType} / ${timeResult?.searchCredit}" + itemBinding.timeItemScore.text = divisionAndCredit + + // 버튼 클릭 이벤트 설정 + itemBinding.planTimeAddButton.setOnClickListener { + onAddButtonClicked?.invoke(timeResult) + } + } + } +} diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterAdapter.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterAdapter.kt index 912f19e5..4ea7acba 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterAdapter.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterAdapter.kt @@ -1,37 +1,40 @@ package umc.com.mobile.project.ui.plan +import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import umc.com.mobile.project.data.model.plan.semesterResult import umc.com.mobile.project.databinding.ItemChooseSemesterBinding -class PlanSemesterAdapter( semesterList: List): RecyclerView.Adapter(){ +class PlanSemesterAdapter(semesterList: List, private val onItemClick: (semesterResult) -> Unit): RecyclerView.Adapter() { var semesterList: List = semesterList set(value) { field = value notifyDataSetChanged() - //데이터가 바뀌었다 알려줌. } - override fun getItemCount(): Int { - return semesterList?.size ?: 0 + return semesterList.size } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlanSemesterAdapter.NonSubjectViewHolder { val itemBinding = ItemChooseSemesterBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return PlanSemesterAdapter.NonSubjectViewHolder(itemBinding) + return NonSubjectViewHolder(itemBinding) } override fun onBindViewHolder(holder: PlanSemesterAdapter.NonSubjectViewHolder, position: Int) { - val semesterInfo = semesterList[position] if (semesterInfo != null) { holder.itemBinding.planTimeSemesterItem.text = semesterInfo.hakkiText } - + holder.itemBinding.root.setOnClickListener { + if (semesterInfo != null) { + onItemClick(semesterInfo) + } + } } + class NonSubjectViewHolder(val itemBinding: ItemChooseSemesterBinding) : RecyclerView.ViewHolder(itemBinding.root) -} \ No newline at end of file +} diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterFragment.kt index 03e82f7b..8c754399 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterFragment.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSemesterFragment.kt @@ -5,46 +5,55 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels -import androidx.lifecycle.Observer +import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager -import umc.com.mobile.project.data.model.plan.semesterResult import umc.com.mobile.project.databinding.SemesterChooseBinding +import umc.com.mobile.project.R + + class PlanSemesterFragment : Fragment() { - private var _binding: SemesterChooseBinding? = null - private val viewModel: PlanViewModel by viewModels() - private val binding get() = _binding!! - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - _binding = SemesterChooseBinding.inflate(inflater, container, false) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - val adapter = PlanSemesterAdapter(emptyList()) // 초기 데이터로 빈 리스트 사용 - - // RecyclerView에 어댑터와 레이아웃 매니저 설정 - binding.recyclerViewPlanSemester.adapter = adapter - binding.recyclerViewPlanSemester.layoutManager = LinearLayoutManager(context) - - viewModel.planSemesterInfo.observe(viewLifecycleOwner) { semesterInfo -> - // 데이터가 업데이트되면 어댑터의 리스트 업데이트 - adapter.semesterList = semesterInfo?.result ?: emptyList() - adapter.notifyDataSetChanged() - } - - viewModel.getSemesterInfo() // 데이터 로드 - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } + private var _binding: SemesterChooseBinding? = null + private val viewModel: PlanViewModel by activityViewModels() + private val binding get() = _binding!! + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + _binding = SemesterChooseBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + viewModel.resetSemesterSelection() // 상태 초기화 + + val adapter = PlanSemesterAdapter(emptyList()) { selectedItem -> + // ViewModel을 통해 hakki 값을 설정 + viewModel.setHakki(selectedItem.hakkiNum) + + // PlanTrackFragment로 화면 전환. Bundle 대신 ViewModel 사용 + findNavController().navigate(R.id.action_planSemesterFragment_to_planTrackFragment) + } + + binding.recyclerViewPlanSemester.adapter = adapter + binding.recyclerViewPlanSemester.layoutManager = LinearLayoutManager(context) + + viewModel.planSemesterInfo.observe(viewLifecycleOwner) { semesterInfo -> + adapter.semesterList = semesterInfo?.result ?: emptyList() + adapter.notifyDataSetChanged() + } + + viewModel.getSemesterInfo() // 데이터 로드 + + binding.planSemesterBackspace.setOnClickListener { + findNavController().navigateUp() + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSettingFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSettingFragment.kt index 28ed2e9b..b14bf819 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSettingFragment.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanSettingFragment.kt @@ -1,10 +1,12 @@ package umc.com.mobile.project.ui.plan import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController @@ -21,62 +23,84 @@ import umc.com.mobile.project.ui.gradInfo.adapter.GradInfoVPAdapter import umc.com.mobile.project.ui.gradInfo.viewmodel.GradInfoViewModel class PlanSettingFragment : Fragment() { - private var _binding: PlanTimeTabMainBinding? = null - private val viewModel: PlanViewModel by viewModels() - private val binding get() = _binding!! + private var _binding: PlanTimeTabMainBinding? = null + private val viewModel: PlanViewModel by activityViewModels() + private val binding get() = _binding!! - private lateinit var viewPager: ViewPager2 - private lateinit var tabLayout: TabLayout + private lateinit var viewPager: ViewPager2 + private lateinit var tabLayout: TabLayout - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - // PlanTimeTabMainBinding을 인플레이트하여 루트 뷰를 가져옴 - _binding = PlanTimeTabMainBinding.inflate(inflater, container, false) - val view = binding.root + // 선택된 학기와 트랙 정보 + private var selectedHakki: String = "" + private var selectedTrackId: String = "" + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + // PlanTimeTabMainBinding을 인플레이트하여 루트 뷰를 가져옴 + _binding = PlanTimeTabMainBinding.inflate(inflater, container, false) + val view = binding.root - // 탭 레이아웃 및 뷰페이저 초기화 - initTabLayout() - initViewPager() - return view - } + // 탭 레이아웃 및 뷰페이저 초기화 + initTabLayout() + initViewPager() + return view + } - private fun initTabLayout() { - val tabTitle = arrayOf("시간표", "자격증", "자유") + private fun initTabLayout() { + val tabTitle = arrayOf("시간표", "자격증", "자유") - viewPager = binding.viewPagerTimeTabMain - tabLayout = binding.tabLayoutPlanTime + viewPager = binding.viewPagerTimeTabMain + tabLayout = binding.tabLayoutPlanTime - val adapter = PlanVPAdapter(this) - adapter.addFragment(PlanTimeFragment()) - adapter.addFragment(PlanlicenseFragment()) - adapter.addFragment(PlanFreeFragment()) + val adapter = PlanVPAdapter(this) - viewPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL - viewPager.adapter = adapter + adapter.addFragment(PlanTimeFragment()) + adapter.addFragment(PlanlicenseFragment()) + adapter.addFragment(PlanFreeFragment()) - TabLayoutMediator(tabLayout, viewPager - ) { tab, position -> tab.text = tabTitle[position] }.attach() - } + viewPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL + viewPager.adapter = adapter - private fun initViewPager() { + TabLayoutMediator(tabLayout, viewPager + ) { tab, position -> tab.text = tabTitle[position] }.attach() + } - binding.viewPagerTimeTabMain.isUserInputEnabled = false - } + private fun initViewPager() { + binding.viewPagerTimeTabMain.isUserInputEnabled = false + } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } + // 학기 및 트랙 선택 후 호출되는 함수 +// fun onSemesterAndTrackSelected(hakki: String, trackId: String) { +// selectedHakki = hakki +// selectedTrackId = trackId +// +// Log.d("PlanSettingFragment", "Selected Hakki: $hakki, TrackId: $trackId") +// +// } +// +// +// fun navigateToPlanTrackFragment() { +// val bundle = Bundle().apply { +// putString("hakki", selectedHakki) +// putString("trackId", selectedTrackId) +// } +// findNavController().navigate(R.id.action_planSettingFragment_to_planTimeFragment, bundle) +// } + + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } \ No newline at end of file diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeAdapter.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeAdapter.kt new file mode 100644 index 00000000..6b143b95 --- /dev/null +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeAdapter.kt @@ -0,0 +1,44 @@ +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import umc.com.mobile.project.data.model.plan.TimeResult +import umc.com.mobile.project.databinding.ItemPlanTimeBinding + +class PlanTimeAdapter : ListAdapter(TimeResultDiffCallback()) { + + // ViewHolder 클래스는 그대로 유지합니다. + class ViewHolder(private val binding: ItemPlanTimeBinding) : RecyclerView.ViewHolder(binding.root) { + fun bind(item: TimeResult) { + binding.timeKindTitle.text = item.searchType + binding.timeClassTitle.text = item.searchName + binding.timeGradeTitle.text = item.searchCredit.toString() // toString() 추가, 학점을 문자열로 표시 + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val binding = ItemPlanTimeBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val item = getItem(position) + holder.bind(item) + } + + // 현재 데이터 리스트를 가져오는 편의 메서드를 추가합니다. + fun getCurrentData(): List { + return currentList + } + + class TimeResultDiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: TimeResult, newItem: TimeResult): Boolean { + return oldItem.searchName == newItem.searchName + } + + override fun areContentsTheSame(oldItem: TimeResult, newItem: TimeResult): Boolean { + return oldItem == newItem + } + } +} diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeFragment.kt index e0ed2c64..06982e7a 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeFragment.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimeFragment.kt @@ -1,84 +1,83 @@ package umc.com.mobile.project.ui.plan import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels -import androidx.lifecycle.Observer -import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import umc.com.mobile.project.R -import umc.com.mobile.project.data.model.plan.TimeResult -import umc.com.mobile.project.databinding.FragmentPlanTimeBinding import umc.com.mobile.project.databinding.PlanSubjectListBinding import umc.com.mobile.project.ui.common.NavigationUtil.navigate -import umc.com.mobile.project.ui.plan.PlanViewModel - -class PlanTimeFragment : Fragment() { - private var _binding: PlanSubjectListBinding? = null - private val viewModel: PlanViewModel by viewModels() - private val binding get() = _binding!! - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View { - _binding = PlanSubjectListBinding.inflate(inflater, container, false) - - - - viewModel.getListTimeInfo() - val adapter = viewModel.listTimeInfo.value?.let { PlanRecyclerAdapter(it.result) } - - binding.recyclerView.adapter = adapter - binding.recyclerView.layoutManager = - LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) - - - - viewModel.listTimeInfo.observe(viewLifecycleOwner) { timenewList -> - if (timenewList != null) { - if (adapter != null) { - adapter.timeList=timenewList.result - adapter.notifyDataSetChanged() - } - } - - - - - } - - _binding!!.planSubjectListSemester.setOnClickListener { - //api 연결 -// viewModel.addCareer() - navigate(R.id.action_planSettingFragment_to_planSemesterFragment) - } - - return binding.root - - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - } - - - - - - - - - - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - +class PlanTimeFragment : Fragment() { + private var _binding: PlanSubjectListBinding? = null + private val viewModel: PlanViewModel by activityViewModels() + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View { + _binding = PlanSubjectListBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + setupRecyclerView() + observeViewModel() + setupNavigation() + } + + private fun setupRecyclerView() { + val adapter = PlanRecyclerAdapter(emptyList(), onAddButtonClicked = { timeResult -> + + if (timeResult != null) { + viewModel.setSelectedTimeResult(timeResult) + } + + + }) + + binding.recyclerView.apply { + this.adapter = adapter + layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + } + } + + private fun observeViewModel() { + // 학기(hakki)와 트랙(trackId) 정보 변경 감지 + viewModel.hakki.observe(viewLifecycleOwner) { hakki -> + viewModel.track.value?.let { trackId -> + if (hakki.isNotEmpty() && trackId.isNotEmpty()) { + viewModel.getListTimeInfo(hakki, trackId) + } + } + } + + // listTimeInfo LiveData 관찰 + viewModel.listTimeInfo.observe(viewLifecycleOwner) { timeListResponse -> + (binding.recyclerView.adapter as PlanRecyclerAdapter).updateTimeList(timeListResponse?.result ?: emptyList()) + } + } + + private fun setupNavigation() { + binding.planTimeMoveTimetable.setOnClickListener { + navigate(R.id.action_planSettingFragment_to_planTimetableFragment) + } + + binding.planSubjectListSemester.setOnClickListener { + navigate(R.id.action_planSettingFragment_to_planSemesterFragment) + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimetableFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimetableFragment.kt new file mode 100644 index 00000000..ce079f10 --- /dev/null +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTimetableFragment.kt @@ -0,0 +1,95 @@ +package umc.com.mobile.project.ui.plan + +import PlanTimeAdapter +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import umc.com.mobile.project.databinding.PlanTimeMainBinding +import umc.com.mobile.project.data.model.plan.AddTimeRequest +import umc.com.mobile.project.data.model.plan.SemesterDto +import umc.com.mobile.project.data.model.plan.SubjectDtoList + +class PlanTimetableFragment : Fragment() { + + private var _binding: PlanTimeMainBinding? = null + private val binding get() = _binding!! + private val viewModel: PlanViewModel by activityViewModels() + private lateinit var adapter: PlanTimeAdapter + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = PlanTimeMainBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupRecyclerView() + setupSaveButton() + observeAddTimeResponse() + + binding.planTimetableBackButton.setOnClickListener { + findNavController().navigateUp() + } + } + + private fun setupRecyclerView() { + adapter = PlanTimeAdapter() + binding.recyclerView.layoutManager = LinearLayoutManager(context) + binding.recyclerView.adapter = adapter + + viewModel.selectedTimeResults.observe(viewLifecycleOwner) { results -> + adapter.submitList(results.toList()) + } + } + + private fun setupSaveButton() { + binding.timeStoreButton.setOnClickListener { + val currentDataList = adapter.getCurrentData() + + // 서버로 전송할 데이터 리스트를 기반으로 AddTimeRequest 객체를 생성합니다. + val subjectDtoList = currentDataList.map { + SubjectDtoList( + it.searchType, + it.searchName, + it.searchCredit + ) + } + val addTimeRequest = AddTimeRequest( + SemesterDto(grade = 1, semester = 1), + subjectDtoList + ) // 예시값을 사용한 SemesterDto + + // ViewModel의 addTime 메서드를 호출하여 서버로 데이터를 전송합니다. + viewModel.addTime(addTimeRequest) + } + } + + private fun observeAddTimeResponse() { + viewModel.addTimeResponse.observe(viewLifecycleOwner) { response -> + if (response != null && response.isSuccess) { + Toast.makeText(context, "Data saved successfully!", Toast.LENGTH_SHORT).show() + Log.d("PlanTimetableFragment", "Data saved successfully: ${response.message}") + } else { + Toast.makeText(context, "Failed to save data.", Toast.LENGTH_SHORT).show() + Log.e("PlanTimetableFragment", "Failed to save data") + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + } + diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTrackAdapter.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTrackAdapter.kt index 3bbc6ae5..36570244 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTrackAdapter.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanTrackAdapter.kt @@ -9,7 +9,8 @@ import umc.com.mobile.project.data.model.plan.semesterResult import umc.com.mobile.project.databinding.ItemChooseSemesterBinding import umc.com.mobile.project.databinding.ItemChooseTrackBinding -class PlanTrackAdapter( trackList: List): RecyclerView.Adapter(){ +class PlanTrackAdapter(trackList: List, private val onItemClick: (TrackResult) -> Unit) : RecyclerView.Adapter() { + var trackList: List = trackList set(value) { field = value @@ -18,6 +19,7 @@ class PlanTrackAdapter( trackList: List): RecyclerView.Adapter): RecyclerView.Adapter + if (hakkiValue.isNotEmpty()) { + Log.d("PlanTrackFragment", "Observed hakki value: $hakkiValue") + viewModel.getTrackInfo(hakkiValue) + } + } + // 클릭 리스너 정의 + val onItemClick: (TrackResult) -> Unit = { selectedItem -> + // 옵저빙된 'hakkiValue' 사용 + viewModel.hakki.value?.let { observedHakki -> + // 선택된 트랙 정보를 ViewModel에 저장 + viewModel.setHakkiAndTrack(observedHakki, selectedItem.trackCode) + // PlanSettingFragment로 화면 전환 + findNavController().navigate(R.id.action_planTrackFragment_to_planSettingFragment) + } + } - return binding.root - } - - + // Adapter 초기화 및 RecyclerView 설정 + val adapter = PlanTrackAdapter(emptyList(), onItemClick) + binding.recyclerViewPlanTrack.adapter = adapter + binding.recyclerViewPlanTrack.layoutManager = LinearLayoutManager(context) - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + // 트랙 정보 갱신 관찰 + viewModel.planTrackInfo.observe(viewLifecycleOwner) { trackInfo -> + adapter.trackList = trackInfo?.result ?: emptyList() + adapter.notifyDataSetChanged() + } + // 뒤로 가기 버튼 리스너 + binding.planTrackBackspace.setOnClickListener { + findNavController().navigateUp() + } } + override fun onDestroyView() { super.onDestroyView() _binding = null } } - - diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanViewModel.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanViewModel.kt index 268e5193..fba47fdc 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanViewModel.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanViewModel.kt @@ -8,12 +8,20 @@ import androidx.lifecycle.ViewModel import retrofit2.Call import retrofit2.Callback import retrofit2.Response +import umc.com.mobile.project.data.model.plan.AddTimeRequest +import umc.com.mobile.project.data.model.plan.AddTimeResponse import umc.com.mobile.project.data.model.plan.BringlicenseResponse +import umc.com.mobile.project.data.model.plan.EditMemoRequest import umc.com.mobile.project.data.model.plan.ListTimeResponse +import umc.com.mobile.project.data.model.plan.PlanFreeRequest +import umc.com.mobile.project.data.model.plan.PlanFreeResponse +import umc.com.mobile.project.data.model.plan.PlanTrackResponse import umc.com.mobile.project.data.model.plan.SaveInfo import umc.com.mobile.project.data.model.plan.SavelicenseRequest import umc.com.mobile.project.data.model.plan.SemesterTimeResponse +import umc.com.mobile.project.data.model.plan.SubjectDtoList +import umc.com.mobile.project.data.model.plan.TimeResult import umc.com.mobile.project.data.model.plan.UPlicenseResponse import umc.com.mobile.project.data.network.ApiClient @@ -25,6 +33,27 @@ class PlanViewModel : ViewModel() { //api private val planApiService = ApiClient.createService() + private val _selectedTimeResults = MutableLiveData>() + val selectedTimeResults: LiveData> = _selectedTimeResults + + fun setSelectedTimeResult(timeResult: TimeResult) { + val currentList = _selectedTimeResults.value ?: ArrayList() + currentList.add(timeResult) + _selectedTimeResults.value = currentList + Log.d("PlanTimetable", "setSelectedTimeResult: $timeResult") + } + + + + + private val _planFreeInfo: MutableLiveData = MutableLiveData() + val planFreeInfo: LiveData + get() = _planFreeInfo + + private val _postMemoResult = MutableLiveData() + val postMemoResult: LiveData + get() = _postMemoResult + private val _hakki: MutableLiveData = MutableLiveData() val hakki: LiveData get() = _hakki @@ -34,9 +63,16 @@ class PlanViewModel : ViewModel() { get() = _track - private val _planSemesterInfo : MutableLiveData = MutableLiveData() - val planSemesterInfo :LiveData - get()=_planSemesterInfo + private val _planSemesterInfo: MutableLiveData = MutableLiveData() + val planSemesterInfo: LiveData + get() = _planSemesterInfo + + private val _planTrackInfo: MutableLiveData = MutableLiveData() + val planTrackInfo: LiveData + get() = _planTrackInfo + + private val _timeTableInfo = MutableLiveData() + val timeTableInfo: LiveData = _timeTableInfo private val _planTimeStatus: MutableLiveData = MutableLiveData() @@ -55,9 +91,6 @@ class PlanViewModel : ViewModel() { get() = _bringLicenseInfo - - - private val _licenseInfo: MutableLiveData = MutableLiveData() val licenseInfo: LiveData get() = _licenseInfo @@ -68,9 +101,11 @@ class PlanViewModel : ViewModel() { get() = _error - private val _savelicenseInfo : MutableLiveData =MutableLiveData() - val savelicenseInfo : LiveData - get()=_savelicenseInfo + private val _savelicenseInfo: MutableLiveData = MutableLiveData() + val savelicenseInfo: LiveData + get() = _savelicenseInfo + + // 기존에 있던 text LiveData @@ -89,45 +124,136 @@ class PlanViewModel : ViewModel() { fun updateIsFilledAllOptions(isFilled: Boolean) { _isFilledAllOptions.value = isFilled } + fun resetSemesterSelection() { + // 학기 정보 관련 상태 초기화 + _planSemesterInfo.postValue(null) // 학기 정보 초기화 + _hakki.postValue("") // 학기 식별자 초기화 (또는 적절한 초기 값으로 설정) + } + fun resetTrackSelection() { + // 선택된 트랙 정보 초기화 + _track.postValue("") // 트랙 식별자 초기화 (또는 적절한 초기 값으로 설정) + } - fun getListTimeInfo() { - _hakki.value?.let { - _track.value?.let { it1 -> - planApiService.getListTime(it, it1).enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - if (response.isSuccessful) { - if (response.body() != null) { - _listTimeInfo.postValue(response.body()) - Log.d("Planlicense", "${response.body()}") - } else { - _error.postValue("서버 응답이 올바르지 않습니다.") - } - } else { - _error.postValue("사용자 정보를 가져오지 못했습니다.") - try { - throw response.errorBody()?.string()?.let { - RuntimeException(it) - } ?: RuntimeException("Unknown error") - } catch (e: Exception) { - Log.e("PlanInfo", "PlanResponse API 오류: ${e.message}") - } - } - } + fun setHakki(hakki: String) { + _hakki.value = hakki + Log.d("hakki value", "setHakki 호출됨: hakki=$hakki") + } + + + fun setHakkiAndTrack(hakki: String, trackId: String) { + Log.d("hakkitrackvalue", "setHakkiAndTrack 호출됨: hakki=$hakki, trackId=$trackId") + _hakki.value = hakki + _track.value = trackId + } + + private val _addTimeResponse = MutableLiveData() + val addTimeResponse: MutableLiveData = _addTimeResponse + + fun addTime(request: AddTimeRequest) { + planApiService.addTime(request).enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.isSuccessful) { + // 서버로부터 응답을 성공적으로 받았을 때 LiveData 업데이트 + Log.d("TimeTableApi", "getListTimeInfo 성공: ${response.body()}") + _addTimeResponse.postValue(response.body()) + } else { + // 에러 처리: 실패 응답 처리 + Log.e("TimeTableApi", "Error posting memo: ${response.errorBody()?.string()}") + _addTimeResponse.postValue(null) + } + } + + override fun onFailure(call: Call, t: Throwable) { + // 네트워크 에러 처리: LiveData 업데이트로 에러 상태 전달 가능 + _addTimeResponse.postValue(null) + } + }) + } - override fun onFailure(call: Call, t: Throwable) { - _error.postValue("네트워크 오류: ${t.message}") - Log.d("gradInfo", "completion: ${t.message}") + + + + + fun postMemo(memoRequest: PlanFreeRequest) { + planApiService.postFreeMemo(memoRequest).enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful) { + // API 호출 성공 시, 성공 LiveData 업데이트 + _postMemoResult.postValue(true) + } else { + // 실패 시, 실패 LiveData 업데이트 + Log.e("PlanViewModel", "Error posting memo: ${response.errorBody()?.string()}") + _postMemoResult.postValue(false) + } + } + + override fun onFailure(call: Call, t: Throwable) { + // 네트워크 오류 등으로 호출 실패 시, 실패 LiveData 업데이트 + _postMemoResult.postValue(false) + } + }) + } + + + fun getFreeInfo() { + planApiService.getFreeInfo().enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful) { + if (response.body() != null) { + _planFreeInfo.postValue(response.body()) + Log.d("PlanFree", "${response.body()}") + } else { + _error.postValue("서버 응답이 올바르지 않습니다.") + } + } else { + _error.postValue("사용자 정보를 가져오지 못했습니다.") + try { + throw response.errorBody()?.string()?.let { + RuntimeException(it) + } ?: RuntimeException("Unknown error") + } catch (e: Exception) { + Log.e("PlanInfo", "PlanResponse API 오류: ${e.message}") } - }) + } + } + + override fun onFailure(call: Call, t: Throwable) { + _error.postValue("네트워크 오류: ${t.message}") + Log.d("gradInfo", "completion: ${t.message}") + } + }) + } + + + fun getListTimeInfo(hakki: String, track: String) { + Log.d("PlanViewModel", "getListTimeInfo 호출됨: hakki=$hakki, track=$track") + planApiService.getListTime(hakki, track).enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.isSuccessful && response.body() != null) { + Log.d("PlanViewModel", "getListTimeInfo 성공: ${response.body()}") + _listTimeInfo.postValue(response.body()) + } else { + Log.e("PlanViewModel", "getListTimeInfo 실패: ${response.errorBody()?.string()}") + _error.postValue("리스트 정보를 가져오는데 실패했습니다.") + } } - } + + override fun onFailure(call: Call, t: Throwable) { + Log.e("PlanViewModel", "getListTimeInfo 네트워크 오류: ${t.message}") + _error.postValue("네트워크 오류: ${t.message}") + } + }) } + fun getLicenseInfo() { planApiService.getUPlicense().enqueue(object : Callback { override fun onResponse( @@ -164,7 +290,8 @@ class PlanViewModel : ViewModel() { fun saveLicense(request: List) { planApiService.saveLicense(request).enqueue(object : Callback { - override fun onResponse(call: Call, response: Response + override fun onResponse( + call: Call, response: Response ) { if (response.isSuccessful) { _bringLicenseInfo.postValue(response.body()) @@ -186,7 +313,6 @@ class PlanViewModel : ViewModel() { } - fun getSemesterInfo() { planApiService.getSemesterInfo().enqueue(object : Callback { override fun onResponse( @@ -218,6 +344,64 @@ class PlanViewModel : ViewModel() { } }) } + + + fun getTrackInfo(hakki: String) { + planApiService.getTrackInfo(hakki).enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful) { + if (response.body() != null) { + _planTrackInfo.postValue(response.body()) + Log.d("PlanTrackInfo", "${response.body()}") + } else { + _error.postValue("서버 응답이 올바르지 않습니다.") + } + } else { + _error.postValue("사용자 정보를 가져오지 못했습니다.") + try { + throw response.errorBody()?.string()?.let { + RuntimeException(it) + } ?: RuntimeException("Unknown error") + } catch (e: Exception) { + Log.e("PlanInfo", "PlanResponse API 오류: ${e.message}") + } + } + } + + override fun onFailure(call: Call, t: Throwable) { + _error.postValue("네트워크 오류: ${t.message}") + Log.d("gradInfo", "completion: ${t.message}") + } + }) + } + + + fun editMemo(memo: String) { + val editMemoRequest = EditMemoRequest(memo = memo) + planApiService.editMemo(editMemoRequest).enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful) { + Log.d("PlanMemoEdit", "Memo successfully edited: ${response.body()}") + // 필요한 경우, UI 업데이트를 위한 LiveData 업데이트 로직을 여기에 추가하세요. + } else { + Log.e("PlanMemoEdit", "Failed to edit memo: ${response.errorBody()?.string()}") + } + } + + override fun onFailure(call: Call, t: Throwable) { + Log.e("PlanMemoEdit", "Network error on edit memo: ${t.message}") + } + }) + } + + + } @@ -235,3 +419,5 @@ class PlanViewModel : ViewModel() { + + diff --git a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanlicenseFragment.kt b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanlicenseFragment.kt index 92f2d90e..d2f62494 100644 --- a/app/src/main/java/umc/com/mobile/project/ui/plan/PlanlicenseFragment.kt +++ b/app/src/main/java/umc/com/mobile/project/ui/plan/PlanlicenseFragment.kt @@ -10,13 +10,14 @@ import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels import umc.com.mobile.project.R import umc.com.mobile.project.databinding.FragmentPlanlicenseBinding class PlanlicenseFragment : Fragment() { private var _binding: FragmentPlanlicenseBinding? = null - private val viewModel: PlanViewModel by viewModels() + private val viewModel: PlanViewModel by activityViewModels() private val binding get() = _binding!! override fun onCreateView( diff --git a/app/src/main/res/drawable/plan_time_back.xml b/app/src/main/res/drawable/plan_time_back.xml new file mode 100644 index 00000000..b7400623 --- /dev/null +++ b/app/src/main/res/drawable/plan_time_back.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/plan_time_move_table.xml b/app/src/main/res/drawable/plan_time_move_table.xml new file mode 100644 index 00000000..b4740ef8 --- /dev/null +++ b/app/src/main/res/drawable/plan_time_move_table.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/layout/fragment_plan_free.xml b/app/src/main/res/layout/fragment_plan_free.xml index 6a51637c..f381ac74 100644 --- a/app/src/main/res/layout/fragment_plan_free.xml +++ b/app/src/main/res/layout/fragment_plan_free.xml @@ -1,11 +1,12 @@ + + app:columnCount="2" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:rowCount="5"> - - @@ -63,6 +63,16 @@ android:layout_marginTop="29dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/appCompatImageView4" /> + app:layout_constraintTop_toBottomOf="@id/appCompatImageView_memo" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_time_subject.xml b/app/src/main/res/layout/item_time_subject.xml index f80c954a..d5e2f376 100644 --- a/app/src/main/res/layout/item_time_subject.xml +++ b/app/src/main/res/layout/item_time_subject.xml @@ -29,17 +29,17 @@ + app:layout_constraintTop_toBottomOf="@id/time_item_semester" /> - + android:layout_marginBottom="60dp" + android:layout_marginRight="10dp" + android:background="@drawable/plan_time_move_table" + /> + - - - + /> + + /> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/plan_time_choose_track.xml b/app/src/main/res/layout/plan_time_choose_track.xml index 9f4d994d..2399f895 100644 --- a/app/src/main/res/layout/plan_time_choose_track.xml +++ b/app/src/main/res/layout/plan_time_choose_track.xml @@ -47,9 +47,10 @@ + + + + + + + > + \ No newline at end of file diff --git a/app/src/main/res/layout/semester_choose.xml b/app/src/main/res/layout/semester_choose.xml index 7a4ae24f..7b632b45 100644 --- a/app/src/main/res/layout/semester_choose.xml +++ b/app/src/main/res/layout/semester_choose.xml @@ -1,10 +1,17 @@ + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index 49a03376..760d2697 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -241,10 +241,43 @@ + + + + android:label="PlanSemesterFragment" > + + + + + + + + + \ No newline at end of file