SPECIALIZED/Android

12. 머터리얼 라이브러리

Tiny Commit 2025. 5. 7. 14:41

 

 

 

 

0. 머터리얼 라이브러리란?

  • 구글에서 지원
  • 모바일과 데스크롭, 그 밖에 다양한 장치를 아우르는 일관된 애플리케이션
  • 빌드 글레드에 포한되어 있어야 한다.

 

 

 

 

 

 

1. 확장된 프로팅 액션 버튼

1. 화면에 떠 있는 듯한 버튼

  • 버튼을 클릭하면 무언가 더해진다.
  • ExtendedFloatingActionButton
  • 클릭 리스너로 핸들러 추가 가능

2. 버튼 배치 - fragment_one.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recyclerView" />
    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/fab"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_margin="10dp"
        app:icon="@android:drawable/ic_input_add"
        android:text = "Extended FAB" />

</RelativeLayout>

 

 

 

 

 

 

 

3. 버튼 기능 처리 - neFragment

// 프레그먼트가 구성하는 화면
    override fun onCreateView(
        (...)


        // 이벤트처리
        binding.fab.setOnClickListener {
            datas.add("Item 100")
            // 아답터에서 바뀐 데이터를 다시 반영해줘
            radapter.notifyDataSetChanged()
        }

        //return inflater.inflate(R.layout.fragment_one, container, false)
        return binding.root
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

2. 실습 - 할 일 목록 앱 만들기

1. 모듈 생성과 빌드 글래들 설정하기

 

 

 

 

 

 

 

 

2. 할일 등록 액티비티 생성하기

  • 사용자에게 todo입력을 받을 activity 생성하기

 

 

 

 

 

 

 

 

3. 리소스 & 소스 파일 복사하기

4. 레이아웃 XML 파일 작성하기

  • AddActivity 파일 불러오기

activity_add.xml
0.00MB

 

 

  • 이미지 파일 불러오기 - item_recycleview.xml
<ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="30dp"
        android:src="@drawable/todo" />

 

 

 

 

 

 

 

5. 메인 액티비티 파일 작성하기

  • OneFragment.kt에서 받아올 데이터 처리 준비하기
// 프레그먼트가 구성하는 화면
    override fun onCreateView(
        (...)
        // add_activity로 데이터를 받아서 반영
        val requestLauncher: ActivityResultLauncher<Intent> =
            registerForActivityResult (ActivityResultContracts.StartActivityForResult()) {
                
            }

        // 이벤트처리
        binding.fab.setOnClickListener {
            //datas.add("Item 100")
            // 아답터에서 바뀐 데이터를 다시 반영해줘
            //radapter.notifyDataSetChanged()



            // add_activity로 데이터를 받아서 반영
            val intent = Intent(it.context, AddActivity::class.java)
            //startActivity(intent)
            requestLauncher.launch(intent)
        }

        //return inflater.inflate(R.layout.fragment_one, container, false)
        return binding.root
    }

 

 

 

 

 

 

  • 데이터 처리하기 - AddActivity.kt
package com.example.myproject

import android.app.Activity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.myproject.databinding.ActivityAddBinding

class AddActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding = ActivityAddBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 저장 버튼을 둘렀을 떄 입력값을 반환하다.
        binding.btnSave.setOnClickListener {
            val intent = intent.putExtra("result", binding.addEditView.text.toString())
            setResult(Activity.RESULT_OK, intent)

            finish()
            true
        }
    }
}

 

 

 

 

  • OneFragment.kt에 돌아오고
  • 전달 받은 값을 데이터값에 넣고 리사이클을 변경한다.
// 프레그먼트가 구성하는 화면
    (...)
        // add_activity로 데이터를 받아서 반영
        val requestLauncher: ActivityResultLauncher<Intent> =
            registerForActivityResult (ActivityResultContracts.StartActivityForResult()) {
                val todo = it.data!!.getStringExtra("result")
                if(todo != ""){
                    datas.add(todo!!)
                    // 아답터에서 바뀐 데이터를 다시 반영해줘
                    radapter.notifyDataSetChanged()
                }
            }

        // 이벤트처리
        binding.fab.setOnClickListener {
            //datas.add("Item 100")
            // 아답터에서 바뀐 데이터를 다시 반영해줘
            //radapter.notifyDataSetChanged()



            // add_activity로 데이터를 받아서 반영
            val intent = Intent(it.context, AddActivity::class.java)
            //startActivity(intent)
            requestLauncher.launch(intent)
        }

        //return inflater.inflate(R.layout.fragment_one, container, false)
        return binding.root
    }

 

 

 

 

 

  • 날짜 전달하기
// 프레그먼트가 구성하는 화면 - OneFragment.kt
    (...)

        // 이벤트처리
        binding.fab.setOnClickListener {
            (...)
            // add_activity로 데이터를 받아서 반영
            val intent = Intent(it.context, AddActivity::class.java)
            //날짜 추가하기
            val dateFormat = SimpleDateFormat("yyyy-MM-dd")
            intent.putExtra("today", dateFormat.format(System.currentTimeMillis().toString()))
            //startActivity(intent)
            requestLauncher.launch(intent)
	(...)
    }

 

// AddActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
        (...)

        val date = intent.getStringExtra("today")
        binding.date.text = date

        (...)
    }

 

 

 

 

 

 

6. 툴바에 뒤로가기 기능 만들기

  • 자리 만들기
// AddActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
        (...)

        // 툴바에 뒤로가기 기능 구현
        setSupportActionBar(binding.addToolbar)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)

        (...)
    }

 

 

  • 기능 구현하기
// AddActivity.kt

override fun onSupportNavigateUp(): Boolean {
        val intent = intent
        intent.putExtra("result", " ")
        setResult(Activity.RESULT_OK, intent)

        finish()
        true
        return super.onSupportNavigateUp()
    }

 

 

 

 

 

 

 

3. 내비게이션 뷰 - 드로어 

  • activity_main.xml 에 구현되어 있다.

1. 파일 가져오기

navigation_header.xml
0.00MB
menu_navigation.xml
0.00MB

 

2. activity_main.xml파일에서 위에 두 파일을 연결한다.

<com.google.android.material.navigation.NavigationView
        (...)
        app:headerLayout="@layout/navigation_header"
        app:menu="@menu/menu_navigation"/>

 

 

 

 

  • 이미지 연동 - navigation_header.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:background="#FF0000">
    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/kbo"
        android:layout_marginTop="30dp"
        android:layout_centerHorizontal="true"/>
    (...)

</RelativeLayout>

 

 

 

3. menu 클릭시 동작

  • 리스너를 상속받는다. - MainActivity.kt
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
	(...)

    override fun onCreate(savedInstanceState: Bundle?) {
        (...)

        // 네비게이션 연동
        binding.drawer.setNavigationItemSelectedListener (this)
    }

    (...)

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        when(item.itemId){
            R.id.nav_item_call -> {
                var intent = Intent(Intent.ACTION_DIAL)
                intent.data = Uri.parse("tel:02-901-111")
                startActivity(intent)
                true
            }
        }
        return  false
    }
}

 

 

 

 

 

4. menu 클릭시 동작이후 main메뉴로 (네비게이션바 닫히기)

  • 바인딩 변수를 전역변수로 선언하기
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    val TAG = "25android"
    lateinit var toggle: ActionBarDrawerToggle
    lateinit var  binding : ActivityMainBinding

    (...)

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
	(...)
        binding.main.closeDrawers()
        return  false
    }
}

 

 

 

 

 

4. 탭 레이아웃 - 탭 버튼 구성

  • 화면에서 탭 버튼을 배치하는 레이아웃

 

1. 탭 레이아웃 만들기

// activity_main.xml

<androidx.drawerlayout.widget.DrawerLayout
    (...)

    <LinearLayout
        (...)

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

        <com.google.android.material.tabs.TabLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/tabs"
            android:contentDescription="앱의 주요 탭"
            app:tabMode="scrollable" />
	(...)
</androidx.drawerlayout.widget.DrawerLayout>

 

 

 

 

 


 

/// MainActivity.kt

(...)
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    (...)

        //탭 레이아웃 프레그먼트 연결하는 Viewpager과 연결
        TabLayoutMediator(binding.tabs, binding.viewpager) { tab, position ->
            tab.text = "TAB ${position + 1}"
        }.attach() //
    }
 (...)