hyeon-z / Seminar27th_1

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

๐ŸŒŸ27th Sopt Android ๐ŸŒŸ

๋ชฉ์ฐจ

๐ŸŒธ Seminar1 - View์™€ViewGroup

๐Ÿ”ถ ์‹คํ–‰ ๋ชจ์Šต

signup1 signup2

๊ณผ์ œ์™„๋ฃŒ: 20.10.25, ๋ฆฌ๋“œ๋ฏธ ์ž‘์„ฑ: 20.10.30

โœ… ํ•„์ˆ˜๊ณผ์ œ: SignUpActivity ๋งŒ๋“ค๊ธฐ

setOnClickListener, Intent

signup_btn.setOnClickListener {  
	val intent = Intent(this, SignUpActivity::class.java)  
	startActivity(intent)  
}
  • setOnClickListener๋Š” ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ๋กœ signup_btn(ํšŒ์›๊ฐ€์ž…) button์„ ๋ˆ„๋ฅด๋ฉด { }์•ˆ์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

  • Intent ์ƒ์„ฑ - Intent( context, ํ˜ธ์ถœํ•  ์•กํ‹ฐ๋น„ํ‹ฐ :: class.java ) startActivity( )์— ์ƒ์„ฑํ•œ Intent๊ฐ์ฒด๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์œผ๋กœ ๋„ฃ์–ด์„œ ํ˜ธ์ถœํ•˜๋ฉด ํ˜ธ์ถœํ•œ
    ์•กํ‹ฐ๋น„ํ‹ฐ๋กœ ํ™”๋ฉด์ด ์ „ํ™˜๋œ๋‹ค.

๋ชจ๋“  EditTextView์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”๊ฒฝ์šฐ / ํ•˜๋‚˜๋ผ๋„ ์—†์„ ๊ฒฝ์šฐ

 fun signUp(){  
        signup_btn.setOnClickListener {  
	        if(et_name_signup.text.isNullOrBlank() || et_id_signup.text.isNullOrBlank() || et_pwd_signup.text.isNullOrBlank() || et_pwdcheck_signup.text.isNullOrBlank()){  
                Toast.makeText(this, "๋นˆ ์นธ์ด ์žˆ์Šต๋‹ˆ๋‹ค.", Toast.LENGTH_SHORT).show()  
	        }  
            else{  
                if(et_pwd_signup.text.toString().equals(et_pwdcheck_signup.text.toString())){  
                    Toast.makeText(this, "ํšŒ์›๊ฐ€์ž…์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.", Toast.LENGTH_SHORT).show()       
                }  
                else{  
                    Toast.makeText(this, "๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.", Toast.LENGTH_SHORT).show()  
                }  
            }  
        }  
  }
  • isNullOrBlank( )๋ฅผ ์ด์šฉํ•ด EditTextView์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ ํ•˜๋‚˜๋ผ๋„ ์—†๋Š”๊ฒฝ์šฐ : ๋นˆ์นธ์ด ์žˆ๋‹ค๋Š” ToastMessage ์ถœ๋ ฅ ๋ชจ๋‘ ์žˆ๋Š” ๊ฒฝ์šฐ: ํšŒ์›๊ฐ€์ž…์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋Š” ToastMessage ์ถœ๋ ฅ

โœ… ์„ฑ์žฅ๊ณผ์ œ1 : ํ™”๋ฉด์ด๋™ + @

  1. ํšŒ์›๊ฐ€์ž…์— ์„ฑ๊ณตํ•˜๋ฉด ์ด์ „ ๋กœ๊ทธ์ธ ํ™”๋ฉด์œผ๋กœ ๋Œ์•„์˜ค๊ธฐ
  2. ํšŒ์›๊ฐ€์ž… ํ›„ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ž…๋ ฅ๋˜์–ด ์žˆ๊ธฐ

startActivityForResult( )

fun gotoSignUp() {  
    signup_btn.setOnClickListener {  
    val intent = Intent(this, SignUpActivity::class.java)  
        startActivityForResult(intent, REQUEST_SIGNUP)  
    }  
}
  • startActivity : ์ƒˆ ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ์—ด์–ด์ค€๋‹ค. (๋‹จ๋ฐฉํ–ฅ)
  • startActivityForResult : ์ƒˆ ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ์—ด์–ด์ฃผ๊ณ  ๊ฒฐ๊ณผ๊ฐ’์„ ์ „๋‹ฌํ•œ๋‹ค.(์Œ๋ฐฉํ–ฅ)
  • RequestCode: ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ’

< SignUpActivity>

intent.putExtra("id", et_id_signup.text.toString())  
intent.putExtra("pwd", et_pwd_signup.text.toString())  
setResult(Activity.RESULT_OK, intent)  
finish()
  • putExtra( ): ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์Œ ์•กํ‹ฐ๋น„ํ‹ฐ์— ์ „๋‹ฌํ•œ๋‹ค.
  • setResult( ): ํšŒ์›๊ฐ€์ž…์„ ์™„๋ฃŒํ•œ ๊ฒฝ์šฐ resultCode๋ฅผ Activity.RESULT_OK๋กœ ์„ค์ •ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด ์„ฑ๊ณต์ ์œผ๋กœ ํšŒ์›๊ฐ€์ž…์ด ๋˜์—ˆ์Œ์„ ๋ณด์—ฌ์ค€๋‹ค.

< MainActivity>

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {  
	 super.onActivityResult(requestCode, resultCode, data)  
     if (resultCode == Activity.RESULT_OK) {  
	     when (requestCode) {  
                   REQUEST_SIGNUP -> {  
                       et_id_login.setText(data!!.getStringExtra("id").toString())  
                       et_pwd_login.setText(data!!.getStringExtra("pwd").toString())  
			}  
		}  
	}  
}
  • OnActivityResult( ) ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœ๋œ Activity์—์„œ ์ €์žฅํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๋Š”๋‹ค.
  • resultCode๊ฐ€ Activity.RESULT_OK์ด๊ณ  requestCode๊ฐ€ REQUEST_SIGNUP์ธ ๊ฒฝ์šฐ ์ฆ‰ ํšŒ์›๊ฐ€์ž…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ ์ด์ „ ๋กœ๊ทธ์ธ ํ™”๋ฉด์— ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ž…๋ ฅ๋˜์–ด์žˆ๊ฒŒ ํ•œ๋‹ค.

โœ… ์„ฑ์žฅ๊ณผ์ œ2 : ์ž๋™๋กœ๊ทธ์ธ

  1. ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด HomeActivity๋กœ ์ด๋™
  2. ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•˜๋Š” ์ˆœ๊ฐ„ id์™€ password๋ฅผ ๊ธฐ์–ตํ•ด์„œ ๋‹ค์Œ ๋กœ๊ทธ์ธ ๋•Œ ์ž๋™๋กœ๊ทธ์ธ
  3. ์ž๋™๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•  ๊ฒฝ์šฐ ์ž๋™๋กœ๊ทธ์ธ์ด ๋๋‹ค๋Š” ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ

SharedPreferences( )

     sharedPreferences = getSharedPreferences("SHARED_PREF", Context.MODE_PRIVATE)  
     editor = sharedPreferences.edit()
  • getSharedPreferences( )๋ฅผ ์ด์šฉํ•ด SharedPreferences๊ฐ์ฒด ์ƒ์„ฑ
  • SharedPreferences๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด Editor ์ธํ„ฐํŽ˜์ด์Šค ์‚ฌ์šฉ

๋ฐ์ดํ„ฐ ์ถ”๊ฐ€

      editor.putString("ID_REM", et_id_login.toString())  
      editor.putString("PWD_REM", et_pwd_login.toString())  
      editor.apply()
  • Editor ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์›ํ•˜๋Š” ๊ฐ’์„ key, value ํ˜•ํƒœ๋กœ ์ž…๋ ฅํ•˜๊ณ  apply( )๋ฅผ ํ•ด์ฃผ๋ฉด ๋ฐ์ดํ„ฐ ์ €์žฅ์ด ์™„๋ฃŒ๋œ๋‹ค. (ํ•„์ˆ˜!)

๋ฐ์ดํ„ฐ ์‚ญ์ œ

    editor.clear()  
    editor.commit()
  • clear()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด SharedPreferences์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๋˜๊ณ  ๋ณ€๊ฒฝ ํ›„์—๋Š” commit์„ ํ•ด์ค€๋‹ค.

๐ŸŒป Seminar2 - RecyclerView

๐Ÿ”ถ ์‹คํ–‰ ๋ชจ์Šต

ezgif com-gif-maker (5) seminar2-22


โœ… ํ•„์ˆ˜๊ณผ์ œ: RecyclerView๋งŒ๋“ค๊ธฐ, ์ƒ์„ธ๋ณด๊ธฐ ํ™”๋ฉด ๊ตฌ์„ฑ (20.10.25 ์™„๋ฃŒ)

  • RecyclerView์—์„œ ๋ณด์—ฌ์ค„ item Layout
  • ๊ฐ ์•„์ดํ…œ์— ๋“ค์–ด๊ฐˆ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์€ Data Class
  • ๋ฐ์ดํ„ฐ๋ฅผ ๋ทฐ์— ๋ฟŒ๋ ค์ฃผ๋Š” ์—ญํ• ์˜ ViewHolder
  • ์•„์ดํ…œ๋งˆ๋‹ค ๋ทฐํ™€๋”๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ทธ์— ๋งž๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” Adapter

Item Layout

image ์ด๋ฏธ์ง€์™€ Title๊ณผ Subtitle ํ˜•์‹์ด ๋ณด์—ฌ์ง€๋Š” sample_item_list.xml์„ ๋งŒ๋“ ๋‹ค.

โ€‹

Data Class

data class SampleData(  
    val title : String,  
    val subTitle : String,  
    val date : String,  
    val detail : String  
)

RecyclerView์—์„œ ์‚ฌ์šฉ๋  title๋ณ€์ˆ˜, subTitle ๋ณ€์ˆ˜, date๋ณ€์ˆ˜, detail๋ณ€์ˆ˜๋ฅผ ๋‹ด์€ ๋ฐ์ดํ„ฐ์˜ ํ‹€์„ ๋งŒ๋“ ๋‹ค.

ViewHolder

class SampleViewHolder (iTemView : View) : RecyclerView.ViewHolder(iTemView){  
   private val title: TextView = iTemView.findViewById(R.id.item_title)  
   private val subtitle: TextView = iTemView.findViewById(R.id.item_subtitle)  
  
   fun onBind(data : SampleData){  
		title.text = data.title  
		subtitle.text = data.subTitle  
	}  
}

findViewById( ) ๋ฅผ ์‚ฌ์šฉํ•ด์„œ item Layout์—์„œ ์ •์˜ํ•œ item_title๊ณผ item_subtitle์„ ์š”์†Œ๋กœ ๊ฐ€์ง„๋‹ค. onBind( ) ๋Š” View์— Data Class์—์„œ ์ƒ์„ฑํ–ˆ๋˜ title, subTitile์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.

Adapter

๋ฐ˜๋“œ์‹œ ์˜ค๋ฒ„๋ผ์ด๋“œ๋ฅผ ํ•ด์ค˜์•ผ ํ•˜๋Š” 3๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ

  1. onCreateViewHolder
  2. onBindViewHolder
  3. getItemCount
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SampleViewHolder {  
  val view = LayoutInflater.from(context).inflate(R.layout.sample_item_list,parent, false)
  return SampleViewHolder(view)  
}

๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ์•„์ดํ…œ์— ๊ด€๋ จ๋œ ์ž๋ฃŒ๋ฅผ ๋‹ด์„ ๋ทฐ ํ™€๋”๋ฅผ ๋งŒ๋“ ๋‹ค.

override fun getItemCount(): Int = data.size

๋ฆฌ์ŠคํŠธ์— ํ‘œ์‹œ๋  ์•„์ดํ…œ์˜ ๊ฐœ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.

override fun onBindViewHolder(holder: SampleViewHolder, position: Int) {  
    holder.onBind(data[position])  
  
    holder.itemView.setOnClickListener {  
		val model = data.get(position)  
	  
		var gTitle: String = model.title  
		var gSubTitle: String = model.subTitle  
		var gDate: String = model.date  
		var gDetail: String = model.detail  
	  
		val intent = Intent(context, DetailActivity::class.java)  
	  
	    intent.putExtra("iTitle", gTitle)  
	    intent.putExtra("iSubTitle", gSubTitle)  
	    intent.putExtra("iDate", gDate)  
	    intent.putExtra("iDetail", gDetail)  
	    
	    context.startActivity(intent)  
	 }  
} 

๋ทฐ ํ™€๋”๊ฐ€ ์‹ค์ œ๋กœ ์—ฐ๊ฒฐ(bind)๋  ๋•Œ ํ˜ธ์ถœ๋˜๋ฉฐ ๊ฐ ์•„์ดํ…œ์„ ๋ˆ„๋ฅด๋ฉด ํ•ด๋‹น ์•„์ดํ…œ์˜ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” DetailActivity๋กœ ๋ฐ์ดํ„ฐ๋“ค์„ ๋„˜๊ฒจ์ค€๋‹ค.

RecyclerActivity

class RecyclerActivity : AppCompatActivity() {
	private lateinit var sampleAdapter: SampleAdapter

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_recycler)
		
		sampleAdapter = SampleAdapter(this)
		
		main_rcv.adapter = sampleAdapter
		main_rcv.layoutManager = LinearLayoutManager(this)
		
		sampleAdapter.data = mutableListOf(  
		    SampleData("์ด๋ฆ„", "๋ฐ•ํ˜„์ง€", "์ƒ๋…„์›”์ผ: 1999.09.21", "์ฃผ์†Œ: ์ผ์‚ฐ๋™๊ตฌ ๋ฐฑ์„๋™ ์–ด๋”˜๊ฐ€")
		)
		sampleAdapter.notifyDataSetChanged()
	}
}

RecycleView์˜ adapter์— sampleAdapter๋กœ ์ ์šฉํ•˜๊ณ  RecyclerView๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฐ์น˜๋˜๋„๋ก LinearLayoutManager๋กœ ์„ค์ •ํ•œ๋‹ค. SampleAdapter์— ๋ฆฌ์ŠคํŠธ๋กœ ๋ณด์—ฌ์ค„ ๋ฐ์ดํ„ฐ(ํƒ€์ดํ‹€, ์„œ๋ธŒํƒ€์ดํ‹€, ๋‚ ์งœ, ์„ธ๋ถ€์ •๋ณด)๋“ค์„ ๋„ฃ์–ด์ฃผ๊ณ  Adapter์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์กŒ์Œ์„ ์•Œ๋ ค์ค€๋‹ค.


โœ… ์„ฑ์žฅ๊ณผ์ œ1 : GridLayout ๋งŒ๋“ค๊ธฐ (20.11.05 ์™„๋ฃŒ)

< SampleAdapter >

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SampleViewHolder {  
  
    val view = when(viewType){  
        1 -> LayoutInflater.from(context).inflate(R.layout.sample_item_list, parent,false)  
        2 -> LayoutInflater.from(context).inflate(R.layout.grid_item_list, parent,false)  
        else -> LayoutInflater.from(context).inflate(R.layout.sample_item_list, parent,false)  
    }  
    return SampleViewHolder(view)  
}

override fun getItemViewType(position: Int): Int {  
    return num  
}

** 3์ฃผ์ฐจ ํ•„์ˆ˜๊ณผ์ œ ์ดํ›„ ์‹คํ–‰ํ•ด ์ฝ”๋“œ๊ฐ€ Fragment์— ์žˆ๋‹ค.
< SecondFragment>

override fun onCreateView(  
	...
    setHasOptionsMenu(true)  
	...
}
 override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {  
        super.onCreateOptionsMenu(menu, inflater)  
        
		var sub: Menu? = menu?.addSubMenu("sort")  
        sub?.add(Menu.NONE, Menu.FIRST + 3, Menu.NONE, "linear")  
        sub?.add(Menu.NONE, Menu.FIRST + 4, Menu.NONE, "grid")  
 }  
  
 override fun onOptionsItemSelected(item: MenuItem): Boolean {  
	 when(item?.itemId){  
		  Menu.FIRST + 3 -> {  
			  sampleAdapter.num = 1  
			  main_rcv.layoutManager = LinearLayoutManager(context)  
		  }  
		  Menu.FIRST + 4 ->{  
			  sampleAdapter.num = 2  
			  main_rcv.layoutManager = GridLayoutManager(context, 2)  
		  }  
	}  
	return super.onOptionsItemSelected(item)  
}

onCreateView์—์„œ ๊ผญ setHasOptionsMenu(true) ๋ฅผ ์จ์•ผ fragment์—์„œ menu๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. onCreateOptionsMenu์—์„œ submenu๋ฅผ ์ƒ์„ฑํ•ด linear์™€ grid menu๋ฅผ ๋งŒ๋“ค๊ณ  onCreateViewHolder์—์„œ num์„ ๋„˜๊ฒจ๋ฐ›์•„ ๊ทธ์— ๋”ฐ๋ฅธ linear, GridLayoutManager๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ํ•œ๋‹ค.

๐ŸŒท Seminar3 - Fragment, ViewPager, BottomNavigation, TabLayout

๐Ÿ”ถ ์‹คํ–‰ ๋ชจ์Šต

ezgif com-gif-maker (9)


โœ… ํ•„์ˆ˜๊ณผ์ œ: ํ”„๋กœํ•„ ํ™”๋ฉด - ๋ฆฌ์‚ฌ์ดํด๋Ÿฌ๋ทฐ ํ™”๋ฉด - ๋น„์–ด์žˆ๋Š” ํ™”๋ฉด 3๊ฐœ๋กœ ๊ตฌ์„ฑ(20.11.02 ์™„๋ฃŒ)

Fragment

  • ํ•˜๋‚˜์˜ ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ™”๋ฉด์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.
  • ํ™”๋ฉด์˜ ๋ถ€์œ„๋ณ„๋กœ ๋”ฐ๋กœ ๋™์ž‘์„ ์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ ๊ฐ๊ฐ์˜ ํ™”๋ฉด์„ ๋ถ„ํ• ํ•ด์„œ ๋…๋ฆฝ์ ์ธ ์ฝ”๋“œ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.
  • Activity์™€์˜ ์ฐจ์ด: Activity๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ์‹œ์Šคํ…œ์ด ๊ด€๋ฆฌํ•˜๊ณ  Fragment๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ๊ด€๋ฆฌํ•œ๋‹ค.

ViewPager

  • ํ•˜๋‚˜์˜ ํ™”๋ฉด ์•ˆ์—์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ™”๋ฉด์„ ์Šฌ๋ผ์ด๋“œ ํ˜•์‹์œผ๋กœ ๋ณด์—ฌ์ค„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
  • ํ•˜๋‹จ ํƒญ, ์ƒ๋‹จ ํƒญ๊ณผ ์—ฐ๋™ํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

BottomNavigation

  • ํ•˜๋‹จ ํƒญ์„ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
  • ViewPager์™€ ์—ฐ๋™ํ•˜์—ฌ ํ™”๋ฉด๋“ค์„ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ™”๋ฉด์ด 3๊ฐœ ์ด์ƒ์ผ ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

TabLayout

  • ์ƒ๋‹จ ํƒญ์„ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
  • ViewPager์™€ ์—ฐ๋™ํ•˜์—ฌ ํ™”๋ฉด๋“ค์„ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • BottomNavigationView์— ๋น„ํ•ด์„œ ์œ„์น˜ ์ด๋™์ด ์ž์œ ๋กญ๋‹ค. ViewPager์™€ ์—ฐ๋™ํ•˜์—ฌ ํ™”๋ฉด๋“ค์„ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

First Fragment (ํ”„๋กœํ•„ ํ™”๋ฉด)

- SampleViewPagerAdapter2.kt

override fun getItem(position: Int): Fragment = when (position) {  
	0 -> Me_FirstFragment()  
	1 -> Me_SecondFragment()  
	else -> throw IllegalStateException("Unexpected position $position")  
}	
override fun getCount(): Int = 3

ViewPager Adapter๋Š” ๋‘๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ๋ฅผ ๋ฐ˜๋“œ์‹œ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•ด์•ผ ํ•œ๋‹ค.

  1. getItem() First Fragment ์ƒ๋‹จ ํƒญ์— ๋“ค์–ด๊ฐˆ ๋‘๊ฐœ์˜ ํ”„๋ž˜๊ทธ๋จผํŠธ์˜ position์„ ์ง€์ •ํ•œ๋‹ค.
  2. getCount() Adapter์—์„œ ๋งŒ๋“ค ํŽ˜์ด์ง€ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

- FirstFragment.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {  
	super.onViewCreated(view, savedInstanceState)  
	sharedPreferences = view.context.getSharedPreferences("SHARED_PREF", Context.MODE_PRIVATE)  
	viewPagerAdapter2 = SampleViewPagerAdapter2(childFragmentManager)  
  
	sample_viewpager_2.adapter = viewPagerAdapter2  
	me_name.text = sharedPreferences.getString("USER_NAME", "")  
  
	sample_tab.setupWithViewPager(sample_viewpager_2)  
	sample_tab.apply {  
		  getTabAt(0)?.text = "INFO"  
		  getTabAt(1)?.text = "OTHER"  
	}  
}  
  • supportFragmentManager : Activity์—์„œ ViewPager๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
  • childFragmentManager: Fragment์—์„œ ViewPager๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

ViewPagerAdapter๋ฅผ ํ†ตํ•ด ํ•˜์œ„ ๋‘ ํ”„๋ž˜๊ทธ๋จผํŠธ๋“ค์„ FirstFragment์˜ ์ƒ๋‹จ ํƒญ๊ณผ ์—ฐ๋™์‹œ์ผœ ํ”„๋กœํ•„ ํ™”๋ฉด์„ ์™„์„ฑํ–ˆ๋‹ค.


BottomNavigation ๊ณผ 3๊ฐœ์˜ Fragment ์—ฐ๋™

- bottom_menu.xml

<item  
  android:id="@+id/menu_me"  
  android:icon="@drawable/ic_me"  
  android:title="Me"/>  
  
  
<item  
  android:id="@+id/menu_portfolio"  
  android:icon="@drawable/ic_portfolio"  
  android:title="PortFolio"/>  
  
<item  
  android:id="@+id/menu_setting"  
  android:icon="@drawable/ic_setting"  
  android:title="Setting"/>

BottomNavigation์— ๋“ค์–ด๊ฐˆ icon์„ ๊ฐ€์ ธ์˜จ ํ›„ id๋ฅผ ์ง€์ •ํ•ด์ค€๋‹ค.

- bottom_navi_color.xml

<item android:color="#86C3BA" android:state_checked="true"/>  
<item android:color="#9E9E9E" android:state_checked="false"/>

ํ˜„์žฌ ๋ณด์—ฌ์ฃผ๋Š” ํ™”๋ฉด์— ๋”ฐ๋ผ item์˜ ์ƒํƒœ์™€ ์ƒ‰์„ ์ง€์ •ํ•œ๋‹ค.

- RecyclerActivity.kt

 //๋ทฐํŽ˜์ด์ง€๋ฅผ ์Šฌ๋ผ์ด๋“œ ํ–ˆ์„ ๋•Œ ๊ทธ์— ๋Œ€์‘๋˜๋Š” ํ•˜๋‹จ ํƒญ ๋ณ€๊ฒฝ  
  sample_viewpager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {  
            override fun onPageScrollStateChanged(state: Int) {}    
            override fun onPageScrolled(  
                position: Int,  
                positionOffset: Float,  
                positionOffsetPixels: Int  
			) {  
            }  
            override fun onPageSelected(position: Int) {  
                sample_bottom_navi.menu.getItem(position).isChecked = true  
			}    
  })  

ViewPager์˜ ํ™”๋ฉด์ „ํ™˜์„ ๊ฐ์ง€ํ•˜๋Š” ๋ฆฌ์Šค๋„ˆ ์„ ์–ธํ•˜๊ณ  ViewPager์˜ ํŽ˜์ด์ง€ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์„ ํƒ๋œ ๊ฒฝ์šฐ ๊ทธ์— ๋Œ€์‘๋˜๋Š” ํ•˜๋‹จ ํƒญ์˜ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚จ๋‹ค.

  // ํ•˜๋‹จ ํƒญ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋ทฐํŽ˜์ด์ง€ ํ™”๋ฉด ๋ณ€๊ฒฝ  
  sample_bottom_navi.setOnNavigationItemSelectedListener {  
	  var index by Delegates.notNull<Int>() 
	            when (it.itemId) {  
	                R.id.menu_me -> index = 0  
					R.id.menu_portfolio -> index = 1  
				    R.id.menu_setting -> index = 2  
				}  
	            sample_viewpager.currentItem = index  
				true  
  }  

๊ฐ ํƒญ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ Listener ์„ค์ •ํ•˜๊ณ  bottom_menu.xml์—์„œ ์ง€์ •ํ•œ Item id๊ฐ’์„ ๊ฐ€์ ธ์™€ viewpager์˜ currentItem์— ๋„ฃ๋Š”๋‹ค.

๐ŸŒน Seminar6 - Server

๐Ÿ”ถ ์‹คํ–‰ ๋ชจ์Šต

ezgif com-gif-maker (7) imageimage


โœ… ํ•„์ˆ˜๊ณผ์ œ: ๋กœ๊ทธ์ธ ํšŒ์›๊ฐ€์ž… ์„œ๋ฒ„ ํ†ต์‹  ์ˆ˜ํ˜„ (20.11.29 ์™„๋ฃŒ)

  1. Retrofit Interface ์„ค๊ณ„

  2. ์„œ๋ฒ„ Request / Response ๊ฐ์ฒด ์„ค๊ณ„

  3. Retrofit Interface ์‹ค์ œ ๊ตฌํ˜„์ฒด ๋งŒ๋“ค๊ธฐ

  4. Callback ๋“ฑ๋กํ•˜์—ฌ ํ†ต์‹  ์š”์ฒญ

Retrofit Interface ์„ค๊ณ„

 interface SampleService {  
    @Headers("Content-Type:application/json")  
    @POST("/users/signup")  
    fun postSignup(  
        @Body body: RequestSignupData  
  ):Call<ResponseSignupData>  
  
    @Headers("Content-Type:application/json")  
    @POST("/users/signin")  
  
    fun postLogin(  
        @Body body: RequestLoginData  
  ): Call<ResponseLoginData>  
}

์‹๋ณ„ URL์„ Interface๋กœ ์„ค๊ณ„


์„œ๋ฒ„ Request / Response ๊ฐ์ฒด ์„ค๊ณ„

  • RequestSignupData
data class RequestSignupData(  
    val email : String,  
    val password : String,  
    val userName : String  
)
  • ResponseSignupData
data class ResponseSignupData(  
    val data: Data,  
    val message: String,  
    val status: Int,  
    val success: Boolean  
) {  
    data class Data(  
        val email: String,  
        val password: String,  
        val userName: String  
  )  
}
  • RequestLoginData
data class RequestLoginData(  
    val email : String,  
    val password : String  
)
  • ResponseLoginData
data class ResponseLoginData(  
    val data: Data,  
    val message: String,  
    val status: Int,  
    val success: Boolean  
) {  
    data class Data(  
        val email: String,  
        val password: String,  
        val userName: String  
  )  
}

Retrofit Interface ์‹ค์ œ ๊ตฌํ˜„์ฒด ๋งŒ๋“ค๊ธฐ

object SampleServiceImpl {  
    private const val BASE_URL = "http://15.164.83.210:3000"  
  
  private val retrofit : Retrofit = Retrofit.Builder()  
        .baseUrl(BASE_URL)  
        .addConverterFactory(GsonConverterFactory.create())  
        .build()  
  
    val service : SampleService = retrofit.create(SampleService::class.java)  
}

์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๋งŒ๋“œ๋Š” ์‹ค์ œ ๊ตฌํ˜„์ฒด : ๊ฐ์ฒด๋Š” ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•˜๊ณ  ํ”„๋กœ์ ํŠธ ์–ด๋””์„œ๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.


Callback ๋“ฑ๋กํ•˜์—ฌ ํ†ต์‹  ์š”์ฒญ

  • Call < Type> : ๋น„๋™๊ธฐ์ ์œผ๋กœ Type์„ ๋ฐ›์•„์˜ค๋Š” ๊ฐ์ฒด
  • Callback < Type > : Type ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์™”์„ ๋•Œ ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ํ–‰๋™
val email = et_id_login.text.toString()  
val password = et_pwd_login.text.toString()  
  
val call: Call<ResponseLoginData> = SampleServiceImpl.service.postLogin(  
    RequestLoginData(email = email, password = password)  
)  
  
call.enqueue(object : Callback<ResponseLoginData> {  
    override fun onFailure(call: Call<ResponseLoginData>, t: Throwable) {  
        // ํ†ต์‹  ์‹คํŒจ ๋กœ์ง  
  }  
  
    // ํ†ต์‹  ์„ฑ๊ณต ๋กœ์ง  
  override fun onResponse(  
        call: Call<ResponseLoginData>,  
        response: Response<ResponseLoginData>  
    ) {  
        response.takeIf { it.isSuccessful }  
  ?.body()  
            ?.let {  
 it.data.let { data ->  
  Toast.makeText(  
                        this@MainActivity, "${data.userName}๋‹˜",  
                        Toast.LENGTH_SHORT  
  ).show()  
                    editor.putString("USER_NAME", data.userName)  
                    editor.putString("ID_REM", et_id_login.toString())  
                    editor.putString("PWD_REM", et_pwd_login.toString())  
                    editor.apply()  
  
                }  
  val intent = Intent(this@MainActivity, RecyclerActivity::class.java)  
                startActivity(intent)  
            } ?: showError(response.errorBody())  
    }  
}  
)

์•ž์—์„œ ๋งŒ๋“  ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ Call ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์˜จ ํ›„ enqueue๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‹ค์ œ ์„œ๋ฒ„ ํ†ต์‹ ์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์š”์ฒญํ•œ๋‹ค.

About


Languages

Language:Kotlin 100.0%