728x90
반응형

 

목차

    처음으로 만들 것은 위 사진과 같이 홈화면과 햄버거메뉴

    안드로이드에서는 Navigation Drawer라고 부른다

    아마 처음 안드로이드 스튜디오를 했을때 대충 넘어갔던 것 같은데....

    https://lektion-von-erfolglosigkeit.tistory.com/122

     

    Android Studio(4) - 내비게이션 메뉴 바 만들기

    ※이 글은 강좌가 아니라 필자가 유튜브로 들은 강의 내용을 이해한대로, 정리되지 않은 채 적는 글입니다 www.youtube.com/playlist?list=PLRx0vPvlEmdB6sCgj_jubp8KPb1ni0VOC 이번엔 Empty Activity가 아니라 Na..

    lektion-von-erfolglosigkeit.tistory.com

    젠장 과거의 나는 왜 그따구로 써놓은 거지

     

    프로젝트 생성

    홈화면의 베이스는 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들을 만들 예정이다