Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Week1 필수과제 #1

Merged
merged 28 commits into from
Apr 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
212e418
add : binding true
SeonHwan-Kim Apr 5, 2023
43959eb
feat : login page
SeonHwan-Kim Apr 5, 2023
81002a4
feat : sign up page
SeonHwan-Kim Apr 5, 2023
7c6868b
feat : main page
SeonHwan-Kim Apr 5, 2023
8e78bad
add : manifest activity
SeonHwan-Kim Apr 5, 2023
72ac3b0
fix : snackbar 위치 수정
SeonHwan-Kim Apr 5, 2023
22487c2
fix : add string #2
SeonHwan-Kim Apr 7, 2023
c4f0cea
feat : screenOrientation portrait로 고정
SeonHwan-Kim Apr 7, 2023
854e225
fix : ScrollView 삭제, string 변경
SeonHwan-Kim Apr 7, 2023
99a9542
fix : string 변경, context 변경
SeonHwan-Kim Apr 7, 2023
ae16b9d
fix : 키보드 숨기기, toast, snackbar 변경
SeonHwan-Kim Apr 7, 2023
24a8556
fix : 필요없는 import 삭제
SeonHwan-Kim Apr 7, 2023
be5017b
add : extension 분리
SeonHwan-Kim Apr 7, 2023
a2ceb46
fix : 마지막 editText imeOptions Done으로 바꿈 #2
SeonHwan-Kim Apr 7, 2023
645105c
feat : Main 뒤로가기 시 앱 종료 #2
SeonHwan-Kim Apr 7, 2023
ee567c9
fix : 사용하지 않는 import 삭제 #2
SeonHwan-Kim Apr 7, 2023
4f26bc8
fix : 파일 분리 #2
SeonHwan-Kim Apr 10, 2023
c9d8f14
fix : 파일 분리 #2
SeonHwan-Kim Apr 10, 2023
4b18255
add : user data class 생성 #2
SeonHwan-Kim Apr 12, 2023
531c845
add : data class parcelize #2
SeonHwan-Kim Apr 12, 2023
cb037d2
fix : getParcelableExtra #2
SeonHwan-Kim Apr 13, 2023
91e724a
fix : user data class 변경 #2
SeonHwan-Kim Apr 13, 2023
5ad8160
fix : user data class 변경 #2
SeonHwan-Kim Apr 13, 2023
c2639b8
fix : user 값 빈 경우 예외처리 #2
SeonHwan-Kim Apr 13, 2023
f2a8a64
fix : 파일 분리 #2
SeonHwan-Kim Apr 13, 2023
e583d0b
fix : getParcelable 분리 #2
SeonHwan-Kim Apr 13, 2023
0ca773b
add : IntentKey 분리 #2
SeonHwan-Kim Apr 13, 2023
f8070e3
feat : 자동로그인 구현 #2
SeonHwan-Kim Apr 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-parcelize'
}

android {
namespace 'org.android.go.sopt'
compileSdk 33

buildFeatures {
viewBinding = true
}

defaultConfig {
applicationId "org.android.go.sopt"
minSdk 28
minSdk 24
targetSdk 32
versionCode 1
versionName "1.0"
Expand Down
14 changes: 12 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,24 @@
android:theme="@style/Theme.GOSOPTAndroid"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
android:name=".presentation.signup.SignUpActivity"
android:exported="false"
android:screenOrientation="portrait"/>
<activity
android:name=".presentation.login.LoginActivity"
android:exported="true"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".presentation.main.MainActivity"
android:exported="false"
android:screenOrientation="portrait"/>
</application>

</manifest>
11 changes: 0 additions & 11 deletions app/src/main/java/org/android/go/sopt/MainActivity.kt

This file was deleted.

12 changes: 12 additions & 0 deletions app/src/main/java/org/android/go/sopt/data/User.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.android.go.sopt.data

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class User(
val id: String? = "",
val password: String? = "",
val name: String? = "",
val specialty: String? = "",
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package org.android.go.sopt.presentation.login

import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import org.android.go.sopt.R
import org.android.go.sopt.data.User
import org.android.go.sopt.presentation.main.MainActivity
import org.android.go.sopt.presentation.signup.SignUpActivity
import org.android.go.sopt.databinding.ActivityLoginBinding
import org.android.go.sopt.util.*


class LoginActivity : AppCompatActivity() {

private lateinit var binding: ActivityLoginBinding
private var user: User? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)

binding.root.setOnClickListener {
hideKeyboard(binding.root)
}

this.autoLogin()
this.onClickLogin()
this.onCLickSignUp()
}

private fun onClickLogin() {
with(binding) {
btMainLogin.setOnClickListener {
if (user !== null && user?.id == etMainId.text.toString() && user?.password == etMainPassword.text.toString()) {
val intent = Intent(this@LoginActivity, MainActivity::class.java)
intent.putExtra(IntentKey.USER_DATA, user)
saveUserInformation()
startActivity(intent)
showShortToast(getString(R.string.login_success_login_msg))
if (!isFinishing) finish()
} else {
showShortToast(getString(R.string.login_fail_login_msg))
}
}
}
}


private val getResultSignUp = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: ActivityResult ->
if (result.resultCode == RESULT_OK) {
user = result.data?.getParcelable(IntentKey.USER_DATA, User::class.java)
Log.d("user", "---------\n$user")
showShortSnackbar(binding.root, getString(R.string.login_success_sign_up_msg))
}
}

private fun onCLickSignUp() {
binding.btMainSignUp.setOnClickListener {
val intent = Intent(this, SignUpActivity::class.java)
getResultSignUp.launch(intent)
}
}

private fun saveUserInformation() {
val sharedPreference = getSharedPreferences(KEY_PREFS, 0)
val editor = sharedPreference.edit()
editor.putString(KEY_ID, user?.id)
editor.putString(KEY_PASSWORD, user?.password)
editor.putString(KEY_NAME, user?.name)
editor.putString(KEY_SPECIALTY, user?.specialty)
editor.apply()
}

private fun autoLogin() {
val sharedPreferences = getSharedPreferences(KEY_PREFS, 0)

if (sharedPreferences.contains(KEY_ID) || sharedPreferences.contains(KEY_PASSWORD)) {
user = User(
sharedPreferences.getString(KEY_ID, ""),
sharedPreferences.getString(KEY_PASSWORD, ""),
sharedPreferences.getString(KEY_NAME, ""),
sharedPreferences.getString(KEY_SPECIALTY, "")
)
val intent = Intent(this, MainActivity::class.java)
intent.putExtra(IntentKey.USER_DATA, user)
startActivity(intent)
showShortToast(getString(R.string.login_success_login_msg))
if (!isFinishing) finish()
}
}

companion object {
private const val KEY_PREFS = "autoLogin"
private const val KEY_ID = "id"
private const val KEY_PASSWORD = "password"
private const val KEY_NAME = "name"
private const val KEY_SPECIALTY = "specialty"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.android.go.sopt.presentation.main

import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.fragment.app.Fragment
import org.android.go.sopt.GalleryFragment
import org.android.go.sopt.HomeFragment
import org.android.go.sopt.R
import org.android.go.sopt.SearchFragment
import org.android.go.sopt.data.User
import org.android.go.sopt.databinding.ActivityMainBinding
import org.android.go.sopt.util.IntentKey
import org.android.go.sopt.util.getParcelable


class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

// val currentFragment = supportFragmentManager.findFragmentById(R.id.fcv_main)
// if (currentFragment == null) {
// supportFragmentManager.beginTransaction().add(R.id.fcv_main, HomeFragment()).commit()
// }
// binding.bnvMain.setOnItemSelectedListener { item ->
// when (item.itemId) {
// R.id.menu_home -> {
// HomeFragment()
// return@setOnItemSelectedListener true
// }
// R.id.menu_search -> {
// SearchFragment()
// return@setOnItemSelectedListener true
// }
// else -> {
// GalleryFragment()
// return@setOnItemSelectedListener true
//
// }
// }
// }

this.getUserData()
}

private fun getUserData() {
val user: User? = intent.getParcelable(IntentKey.USER_DATA, User::class.java)
binding.tvMainName.text = "이름 : ${user?.name}"
binding.tvMainSpecialty.text = "특기 : ${user?.specialty}"
}

// private fun changeFragment(fragment: Fragment) {
// supportFragmentManager
// .beginTransaction()
// .replace(R.id.fcv_main, fragment)
// .commit()
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.android.go.sopt.presentation.signup

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import org.android.go.sopt.R
import org.android.go.sopt.data.User
import org.android.go.sopt.databinding.ActivitySignUpBinding
import org.android.go.sopt.presentation.login.LoginActivity
import org.android.go.sopt.util.IntentKey
import org.android.go.sopt.util.hideKeyboard
import org.android.go.sopt.util.showShortToast

class SignUpActivity : AppCompatActivity() {

private lateinit var binding: ActivitySignUpBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySignUpBinding.inflate(layoutInflater)
setContentView(binding.root)

binding.root.setOnClickListener {
hideKeyboard(binding.root)
}

this.onClickComplete()
}

private fun onClickComplete() {
with(binding) {
btSignupComplete.setOnClickListener {
val id = etSignupId.text
val password = etSignupPassword.text
val name = etSignupName.text
val specialty = etSignupSpecialty.text

if (id.length !in 6..10) {
showShortToast(getString(R.string.sign_up_id_err_msg))
} else if (password.length !in 8..12) {
showShortToast(getString(R.string.sign_up_password_err_msg))
} else if (name.isEmpty()) {
showShortToast(getString(R.string.sign_up_name_err_msg))
} else if (specialty.isEmpty()) {
showShortToast(getString(R.string.sign_up_specialty_err_msg))
} else {
val intent = Intent(this@SignUpActivity, LoginActivity::class.java)
intent.putExtra(
IntentKey.USER_DATA, User(
id.toString(),
password.toString(),
name.toString(),
specialty.toString()
)
)
setResult(RESULT_OK, intent)
// 만약 종료가 되지 않았다면 종료시키기
if (!isFinishing) finish()
}
}
}
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/org/android/go/sopt/util/ContextExtension.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.android.go.sopt.util

import android.content.Context
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import com.google.android.material.snackbar.Snackbar

fun Context.showShortToast(message: String){
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}

fun Context.hideKeyboard(view: View){
val inputManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
// hideSoftInputFromWindow는 첫번째 인자로 windowToken을 받아야함. windowToken은 View에서 사용?
inputManager.hideSoftInputFromWindow(view.windowToken, 0)
}

fun Context.showShortSnackbar(view: View, message: String){
// Snackbar.make는 첫번째 인자로 View를 받아야한다. 그래서 this(context)를 쓰면 에러남
Snackbar.make(view, message, Snackbar.LENGTH_SHORT).show()
}
11 changes: 11 additions & 0 deletions app/src/main/java/org/android/go/sopt/util/IntentExtension.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.android.go.sopt.util

import android.content.Intent
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.TIRAMISU
import android.os.Parcelable

fun <T : Parcelable?> Intent.getParcelable(key: String, clazz: Class<T>): T? = when {
SDK_INT >= TIRAMISU -> getParcelableExtra(key, clazz)
else -> getParcelableExtra(key) as? T
}
5 changes: 5 additions & 0 deletions app/src/main/java/org/android/go/sopt/util/IntentKey.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.android.go.sopt.util

object IntentKey {
const val USER_DATA = "USER_DATA"
}
9 changes: 9 additions & 0 deletions app/src/main/java/org/android/go/sopt/util/ViewExtension.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.android.go.sopt.util

import android.view.View
import com.google.android.material.snackbar.Snackbar

// View 객체를 상속받는 곳에서만 사용 가능~
//fun View.showShortSnackBar(message: String){
// Snackbar.make(this, message, Snackbar.LENGTH_SHORT).show()
//}
Binary file added app/src/main/res/drawable/img_introduce.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading