Skip to content

Issue #12

dongk00 edited this page Feb 2, 2022 · 3 revisions

drawerlayout

오른쪽에서 메뉴를 꺼내기 위해서 drawerlayout의 layoutDirection을 rlt(right to left)로 설정하면 start가 오른쪽, end가 왼쪽이 된다. 하지만 이렇게 되면 하위에 있는 모든 뷰의 방향이 같이 바뀐다. 삽질 끝에,, drawerlayout을 rlt, 그 하위에 있는 content_main 내에 있는 navHostFragment인 FragmentContainView에 layoutDirection을 ltr로 바꿔주어서 navigation으로 조종되는 fragment들의 방향을 재정렬하였다.

safeArgs

project 수준의 gradle에 classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"를 추가해주면서 safe args를 도입. safe args는 fragment 간 데이터를 전달하기 위한 bundle과 비슷하지만 조금 더 유형 안정성을 갖췄다고 한다. 전체적인 방식은 activity간에 intent를 전달하는 것과 비슷하게 fragment간에 safe args를 전달한다.

navigation에서 데이터를 전달 '받고자 하는' fragment의 argument를 형식에 맞게 추가해준다. (Design 탭에서 해당 프래그먼트 클릭 후 오른쪽에서 추가 가능) 작업이 진행되면 발신 프래그먼트에는 프래그먼트이름+directions 이름의 클래스가, action에도 새로운 클래스가, 송신 프래그먼트에서는 프래그먼트이름+args 이름의 클래스가 생성되어 코드를 처리해준다.

<navigation.xml>
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/navigation"
    app:startDestination="@id/nav_daily_writing">
    <fragment
        android:id="@+id/nav_daily_writing"
        android:name="com.example.monthlywriting.daily.DailyWritingFragment"
        android:label="fragment_daily_writing"
        tools:layout="@layout/fragment_daily_writing" />
        tools:layout="@layout/fragment_daily_writing" >
        <action
            android:id="@+id/open_add"
            app:destination="@id/nav_daily_writing_add" />
    </fragment>
    <fragment
        android:id="@+id/nav_monthly_writing"
        android:name="com.example.monthlywriting.monthly.MonthlyWritingFragment"
        android:label="fragment_monthly_writing"
        tools:layout="@layout/fragment_monthly_writing" />
    <fragment
        android:id="@+id/nav_daily_writing_add"
        android:name="com.example.monthlywriting.daily.DailyWritingAdd"
        android:label="fragment_daily_writing_add"
        tools:layout="@layout/fragment_daily_writing_add" />
        tools:layout="@layout/fragment_daily_writing_add" >
        <action
            android:id="@+id/close_add"
            app:destination="@id/nav_daily_writing"
            app:popUpTo="@id/navigation"
            app:popUpToInclusive="true"/>
        <argument
            android:name="type"
            app:argType="string"
            app:nullable="true"
            android:defaultValue="@null" />
    </fragment>
</navigation>

추가로 navigate 하면서 fragment를 이동할 시 backstack에 fragment가 쌓여버리는 현상이 발생해서 popUpTo, popUpToInclusive 로 해결하였다. popUpto는 가르키는 navigation으로 이동하면서 쌓인 backstack을 제거하고, popUptoInclusive = true는 현재 이동한 fragment의 backstack까지 제거해서 해당 액션 이후 아무런 backstack이 남지 않게 된다.

<발신>
val action = DailyWritingFragmentDirections.openAdd("daily") //openAdd는 navigation에서 정의한 action(A fragment -> B fragment) + 타입에 맞게 전달
it.findNavController().navigate(action)

<송신>
val value = args.type (argument name)

numberpicker

다른 picker 종류와 비슷한 기능. 기본적인 사이즈가 있기 때문에 고려해서 만들어야 한다. xml attribute로 설정이 안되는, 코드 부분에서 minvalue와 maxvalue를 설정해줘야 작동하기 시작한다. value는,, xml attribute 중 value = "@={viewModel.~~~}" 로 양방향 databinding으로 받아주었다.

databinding

사용하는 fragment에서 viewmodel 선언 후 xml 에서 선언한 내의 뷰 모델과 연결

binding = DataBindingUtil.inflate(inflater, R.layout.fragment_daily_writing_add, container, false)
binding.viewModel = viewModel
binding.lifecycleOwner = this.viewLifecycleOwner

roommodule

roommodule 내에서 dao를 사용하기 위해 dao를 provide 하고 dao를 사용하기 위한 appdatabase 위해 appdatabase도 provide 한다 provide appdatabase -> dao -> repository가 @module에서 모두 일어남

setTextsize

아래 코드처럼 typedvalue 작성하지 않으면 sp의 3배 값이 출력된다.

setTextSize(
TypedValue.COMPLEX_UNIT_PX,
resources.getDimensionPixelSize(R.dimen.daily_writing_item_title_size).toFloat())

bottomsheet dialog

bottomsheet 밖에 클릭 시 bottomsheet close 하게 만듦. 이건 구글링 많이 해봤는데,, xml에 nestedscrollview를 써라 bottomsheetcallback으로 행동을 다시 정의하라 많았는데 isDraggable을 false로 두면 끝이다. 이것만이 bottomsheet의 drag를 막음과 동시에 안의 recyclerview가 움직일 수 있게 해주었다.

dialog.setCanceledOnTouchOutside(true)
dialog.behavior.isDraggable = false

그리고 bottomsheet의 외부를 투명하게 만들기 위해 구글링한 코드를 그대로 가져왔는데 나중에 다시 손보면서 공부 필요.

<style name="transparent_dialog">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowTitleStyle">@null</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
    <item name="android:background">@android:color/transparent</item>
</style>

Calendar

calender 사용이 처음인데 instance 받고 set으로 현재 날짜 지정해준 다음 그에 대한 정보를 가져올 수 있었다. 앞으로 더 사용하기 위해서는 공부해야 한다.

val cal = Calendar.getInstance()
cal.set( currentYear, currentMonth - 1, currentDay )
return cal.getActualMaximum(Calendar.DAY_OF_MONTH)

Type converter

결국 dailyitem에서 dailymemo 는 MutableList로 들어가게 되었는데, mutablelist의 type이 뭐든 간에 mutablelist -> json, json -> mutablelist로 변환해주는 typeconverter를 만들기만 하면 작동한다. 여기서 양방향의 typeconverter를 만들어야 한다. 아직 사용하지 않는다고 일단 하나만 만들었다가 앱이 계속 죽었다.

Clone this wiki locally