안드로이드 UI를 개발할때 Activity 기반에서 Fragment기반으로 개발한지도 상당한 시간이 흘렀습니다..

지금까진 Fragment를 Activity에 붙이기 위해선 FragmentManager 를 이용하여 replace 또는 add를 해야만 했습니다.

예를 들면 아래와 같습니다.

FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_id, CustomFragment(), "tag_name");
ft.commitAllowingStateLoss();
fm.executePendingTransactions();

시간이 흐르면서 안드로이드도 많은 발전을 했는데, 그중 하나가 NavHostFragment를 통한 네비게이션 입니다.

 

안드로이드 스튜디오를 통해서 NavHostFragment 코드를 보면 Fragment를 상속하고 있고 NavHost 인터페이스를 구현하고 있습니다.

NavHost 는 내부적으로 아래와 같은 인터페이스 함수를 가지고 있습니다.

public interface NavHost {

    /**
     * Returns the {@link NavController navigation controller} for this navigation host.
     *
     * @return this host's navigation controller
     */
    @NonNull
    NavController getNavController();
}

그럼 실전에서 어떻게 구현이 가능한지 확인해 보겠습니다.

자세한 사항은 아래 링크를 통해서 확인하시면 됩니다.

developer.android.com/guide/navigation/navigation-getting-started?hl=ko

 

1. xml을 통하여 fragment 또는 FragmentContainerView 선언

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />
</FrameLayout>

fragment와 FragmentContainerView 의 차이는 z-ordering를 처리할수 있느냐에 있습니다.

자세한 내용은 아래 링크를 통해서 확인하시면 됩니다.

developer.android.com/reference/androidx/fragment/app/FragmentContainerView

 

FragmentContainerView  |  Android 개발자  |  Android Developers

From class android.view.ViewGroup void addChildrenForAccessibility(ArrayList arg0) void addExtraDataToAccessibilityNodeInfo(AccessibilityNodeInfo arg0, String arg1, Bundle arg2) void addFocusables(ArrayList arg0, int arg1, int arg2) void addKeyboardNavigat

developer.android.com

2. FragmentContainerView 에서 선언한 nav_graph 작성

<?xml version="1.0" encoding="utf-8"?>
<navigation android:id="@+id/nav_graph"
    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"
    app:startDestination="@+id/nav_xxx_start">

    <fragment
        android:id="@+id/nav_xxx_start"
        android:name="com.aaa.bbb.ccc.CustomFragment"
        android:label="main fragment"
        tools:layout="@layout/fragment_start_layout" />

    <fragment
        android:id="@+id/nav_webview"
        android:name="com.aaa.bbb.ccc..WebViewFragment"
        android:label="webview fragment"
        tools:layout="@layout/fragment_webview" />
</navigation>

위에서 보면 navigation tag의 app:startDestination 속성이 있는데 이걸 처음 실행할 fragment id로 설정해 줍니다.

각 fragment에는 name속성에 : Fragment 이름, layout속성에는 해당 프레그먼트의 layout id를 넣어줍니다.

 

3. 실제 네비게이션

findNavController(R.id.nav_host_fragment).navigate(R.id.nav_xxx_start)

findNavController의 id는 NavHostFragment 의 id를 사용하고 뒤의 navigate에서는 실제로 움직일 프레그먼트의 id를 넣어줍니다.

만약 argument를 같이 넣어줄 필요가 있으면 아래와 같이 Bundle을 추가해 줍니다.

val bundle = Bundle().apply {
	putInt(EXTRA_TYPE, position)
}

findNavController(R.id.nav_host_fragment).navigate(R.id.id_want_to_go, bundle)

findNavController 를 사용하면 기본적으로 fragment가 중복 적재됩니다. 다시 말하면 같은 프레그먼트를 호출하면 같은 프레그먼트가 적재되고, backkey를 통해서 하나씩 빠지게 됩니다. 만약 이런 처리를 방어하기 위해서는 아래와 같이 navigation option 처리를 하면 됩니다.

val bundle = Bundle().apply {
	putInt(EXTRA_TYPE, position)
}
val navOption = NavOptions.Builder().setLaunchSingleTop(true).build()
findNavController(R.id.nav_host_fragment).navigate(R.id.id_want_to_go, bundle, navOption)

 잘만 활용하면 기존 방식보다 훨씬 짧은 코드로 쉽게 앱개발을 할수 있을것 같습니다.

'프로그래밍 > 안드로이드' 카테고리의 다른 글

app-ads.txt 처리하는 방법  (0) 2020.02.13
Custom view cycle.  (0) 2016.12.14
Stop watch  (0) 2016.11.29
안드로이드 광고 모듈  (0) 2016.11.25
Glide에서 디스크 캐쉬 사용하지 않게 하는 방법  (0) 2016.09.28
by Invincible Cooler 2020. 12. 1. 11:38
class CircleColorImageView : AppCompatImageView {

    private lateinit var paint: Paint

    constructor(context: Context) : super(context) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init()
    }

    private fun init() {
        paint = Paint(Paint.ANTI_ALIAS_FLAG)
        paint.run {
            style = Paint.Style.FILL
            color = Color.TRANSPARENT
        }
    }

    fun setColor(resId: Int) {
        paint.run {
            color = resId
        }
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)

        val x = canvas?.width ?: 0
        val y = canvas?.height ?: 0

        if (x == 0 || y == 0) {
            return
        }

        val half = (x / 2).toFloat() // 정확한 원이기 때문에 x/2, y/2, radius 값이 같아서 이렇게 처리해도 무방함

        canvas?.drawCircle(half, half, half, paint)
    }
}
by Invincible Cooler 2020. 3. 6. 17:16

안녕하세요. 오늘은 app-ads.txt를 처리하는 방법에 대해서 적어 볼까 합니다.

 

개인 개발자 기준이며, Website를 운영하는 단체 및 회사와는 관련이 없습니다.

 

- 접속 : admob.com

1. 좌측 메뉴의 앱 -> 모든 앱 보기 -> APP-ADS.TXT 탭 누름 

이렇게 하면 상태가 회색이고 app-ads.txt URL에 아무것도 안나옵니다.

 

그러면 약간 오른쪽의 APP-ADS.TXT설정 방법을 눌러서 설정방법을 참고 합니다.

개인 개발자들은 보통 개인 Website를 구축하고 있지 않기 때문에 

https://www.app-ads-txt.com/ 의 도움을 받아 처리하면 됩니다. 로그인을 하고 하라는 대로 하면

 

오른쪽 Copy to clipboard위에 https url이 나옵니다.

그러면 이 url을 복사해서 구글 콘솔의 해당앱 선택 좌측 메뉴의 앱정보 -> 스토어 등록정보 -> 연락처 세부정보의 웹사이트에 해당 url을 넣어주시면 1~2일 후 admob에 가보면 녹색으로 변화된걸 볼 수 있을겁니다.

 

이런건 티스토리나 Naver블로그에서 지원해 주면 좋은데 아직은 안해주네요.

 

by Invincible Cooler 2020. 2. 13. 09:53