목차
처음으로 만들 것은 위 사진과 같이 홈화면과 햄버거메뉴다
안드로이드에서는 Navigation Drawer라고 부른다
아마 처음 안드로이드 스튜디오를 했을때 대충 넘어갔던 것 같은데....
https://lektion-von-erfolglosigkeit.tistory.com/122
젠장 과거의 나는 왜 그따구로 써놓은 거지
프로젝트 생성
홈화면의 베이스는 Navigation Drawer Activity로 진행
이번엔 패키지 이름도 정해주었다
보통 중간은 회사이름 같은거 넣던데 그런거 생각 안해봤기 때문에 일단 블로그 첫 단어로...
캘린더뷰
안드로이드 스튜디오에서는 자체적으로 캘린더를 위젯으로 제공하고 있다
content_main.xml에 CalendarView를 추가한 뒤 대충 위치를 맞춰주었다
당연한 거지만 실행해보면 날짜는 오늘 날짜로 나온다
그러나 문제가 발생했다
Home이 아닌 다른 화면으로 넘어가면 CalendarView가 없어져야하는데 그대로 남아있다...
찾아보니 Navigation Drawer의 기본 동작 방식을 알 수 있었다
먼저 content_main.xml은 실제로 보여지는 화면으로 이 화면을 Fragment들이 서로 바꿔가며 사용한다
즉 번갈아 가면서 사용하는 부분에다가 HomeFragment만 가져야하는 CalendarView를 넣어놓 것
content_main.xml의 CalendarView를 지우고 fragment_home.xml에 넣어주었다
위쪽 여백 없이 위치시켜야 content_main.xml에서 딱 맞게 나온다
ListView
그러면 이제 이걸 추가해보자
ListView를 사용하면 될 것 같긴 한데...
생각보다 잘 안된다
그냥 Activity에 추가하는 것과 다르게 뭔가 좀 안되네
일단 binding이 계속 헷갈리게 하니까 없애버리고 찾은 정보를 바탕으로 HomeFragment.java를 수정해주엇다
package com.lektion.gympartner.ui.home;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.lektion.gympartner.R;
public class HomeFragment extends Fragment {
// private HomeViewModel homeViewModel;
// private FragmentHomeBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// homeViewModel =
// new ViewModelProvider(this).get(HomeViewModel.class);
//
// binding = FragmentHomeBinding.inflate(inflater, container, false);
// View root = binding.getRoot();
View view = inflater.inflate(R.layout.fragment_home, container, false);
final String[] LIST = {"List1", "List2", "List3"};
ListView listView = (ListView) view.findViewById(R.id.listview1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, LIST);
listView.setAdapter(adapter);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
//binding = null;
}
}
기존의 root와 binding 대신에 view를 하나 만들어서 fragment_home을 보여주게 하고
ListView에 보여질 내용인 LIST
layout에 있는 Listview를 할당하는 listview
listview에 LIST를 넣어주는 ArrayAdapter를 선언
리스트가 나오게 되긴 했는데 위치가 참 애매하다
LIST에 몇개 더 추가하고 여러가지 조정해보자
대체 기준이 뭔지 감이 안잡힌다...
여러번의 시행착오 끝에 적당한 위치를 찾았다
그리고 테두리, 버튼, 텍스트를 추가한 listview로 만들었다!
일단 구조는 아래와 같이 listview자체와 그 안에 들어가는 listitem들도 구성되어 있다.
background_listview.xml
drawable에 추가
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<stroke android:width = "5dp" android:color = "#000000"/>
<solid android:color="#ffffff"/>
<corners android:radius="20dp"/>
</shape>
</item>
</layer-list>
모양은 rectangle
테두리는 검은색 5dp
배경은 흰색
둥글게 만들었다
background_listitem.xml
drawable에 추가
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<stroke android:width = "5dp" android:color="#ffffff"/>
<padding android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
<solid android:color="#DFE0E0"/>
<corners android:radius="10dp"/>
</shape>
</item>
</layer-list>
모양은 rectangle
테두리는 흰색 5dp
padding은 상하좌우 5dp
배경은 figma에서 만든 색
조금 둥근 테두리
listitem.xml
layout에 추가
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
android:background="@drawable/background_listitem">
<Button
android:id="@+id/button"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="10dp"
android:background="@drawable/roundbutton" />
<TextView
android:id="@+id/textList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="adsfsadfsaf"
android:layout_marginLeft="10dp"
android:layout_marginRight="20dp"
android:textSize="70px" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
LinearLayout를 기반으로
Button과 Textview를 각각 추가
다른 속성들은 많은 실패 끝에 도달한 것들...
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<CalendarView
android:id="@+id/calendarView2"
android:layout_width="414dp"
android:layout_height="407dp"
android:clickable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.491"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.155" />
<ListView
android:id="@+id/listview1"
android:layout_width="333dp"
android:layout_height="152dp"
android:background="@drawable/background_listview"
android:padding="20dp"
android:dividerHeight="0px"
android:divider="#ffffff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.929" />
</androidx.constraintlayout.widget.ConstraintLayout>
ListView의 background를 만들었던 background_listview.xml로 설정
divider(구분 가로줄) 안보이게 설정
padding을 안넣으면 listitem들이 말 그대로 선넘는다...
HomeFragment
package com.lektion.gympartner.ui.home;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.lektion.gympartner.R;
public class HomeFragment extends Fragment {
// private HomeViewModel homeViewModel;
// private FragmentHomeBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// homeViewModel =
// new ViewModelProvider(this).get(HomeViewModel.class);
//
// binding = FragmentHomeBinding.inflate(inflater, container, false);
// View root = binding.getRoot();
View view = inflater.inflate(R.layout.fragment_home, container, false);
final String[] LIST = {"List1", "List2", "List3", "List4", "List5", "List6", "List7"};
ListView listView = (ListView) view.findViewById(R.id.listview1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.listitem, R.id.textList, LIST);
listView.setAdapter(adapter);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
//binding = null;
}
}
ArrayAdapter 선언 부분에서 (getActivity(), [리스트에 보여지는 layout], [LIST값이 할당될 textView], LIST)로 변경
Header 추가하기
이제 listview 위쪽에 위치할 날짜와 추가버튼을 만들어두자
listview_header.xml로 새로운 layout을 만들고 TextView와 버튼을 추가했다
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="날짜"
android:textSize="20dp"
android:layout_weight="4" />
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="10dp"
android:background="@drawable/plus"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
적당히 추가는 된 것 같은데 스크롤할 때 같이 움직이고 있다...
Header는 포기하고 따로 추가하기로 했다
fragment_home.xml에 TextView를 추가
id는 date로 정해줬다
위치는 언제나 그렇듯이 대충...
이후 HomeFragment.java에 관련 코드 추가
TextView dateText;
CalendarView calendarView;
Calendar calendar;
...
calendar = Calendar.getInstance();
dateText = (TextView)view.findViewById(R.id.date);
calendarView = (CalendarView) view.findViewById(R.id.calendar);
String date = calendar.get(Calendar.YEAR) + "년 " + (calendar.get(Calendar.MONTH)+1) + "월 " + calendar.get(Calendar.DAY_OF_MONTH) + "일";
dateText.setText(date);
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth) {
String date = year + "년 " + (month+1) + "월 " + dayOfMonth + "일";
dateText.setText(date);
}
});
...
첫 실행에는 Calendar를 이용해서 오늘 날짜로 TextView를 설정
이후 클릭으로 날짜가 바뀌면 그 날짜로 변경
이제 플러스 버튼 추가
drawable 폴더에 사용할 이미지를 추가하고 background로 설정해준다
<Button
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/plus"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.859"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.718" />
그리고 확인을 위해 Toast를 하나 달아줬다
plusButton = (Button) view.findViewById(R.id.plus);
plusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(),"루틴 추가창으로", Toast.LENGTH_SHORT).show();
}
});
제목 변경
마지막으로 제목에 날짜를 적어두자
아래 코드를 추가
getActivity().setTitle(calendar.get(Calendar.YEAR) + "." + (calendar.get(Calendar.MONTH)+1));
사진과 같이 Fragment의 제목이 날짜로 변경되었다
여기서 끝인줄 알았으나...
다른 Fragment에 갔다오면 제목이 그대로인 경우가 발생했다
해결을 위해 MainActivity에서 새 함수를 작성
public void setActionBarTitle(String title)
{
ActionBar actionBar = getSupportActionBar();
if(actionBar != null)
{
actionBar.setTitle(title);
}
}
그리고 이 함수를 Fragment의 onResume에다 추가하면 된다
@Override
public void onResume() {
super.onResume();
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM", Locale.KOREA);
FragmentActivity activity = getActivity();
if(activity != null)
{
((MainActivity) activity).setActionBarTitle(format.format(calendar.getTime()));
}
}
이왕하는 거 format도 맞춰봤다
이제 홈화면이 대충 완성되었다
다음에는 메뉴를 Navigation Bar쪽을 좀 수정하면서 Fragment들을 만들 예정이다
'중단된 프로젝트 > GYM Partner' 카테고리의 다른 글
헬스 루틴 기록용 앱 만들기 - 햄버거 버튼 전환 (0) | 2021.08.11 |
---|---|
헬스 루틴 기록용 앱 만들기#3 - 화면전환 (0) | 2021.08.11 |
헬스 루틴 기록용 앱 만들기 - 프로젝트 리팩토링 (0) | 2021.08.09 |
헬스 루틴 기록용 앱 만들기#1 - UI 초안 (0) | 2021.07.30 |
헬스 루틴 기록용 앱 만들기#0 - 프로젝트 개요 (0) | 2021.07.28 |