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 16 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
6 changes: 5 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ 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=".signup.SignUpActivity"
android:exported="false"
android:screenOrientation="portrait"/>
<activity
android:name=".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=".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.

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

import android.content.Intent
import android.os.Bundle
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.main.MainActivity
import org.android.go.sopt.signup.SignUpActivity
import org.android.go.sopt.databinding.ActivityLoginBinding
import org.android.go.sopt.util.hideKeyboard
import org.android.go.sopt.util.showShortSnackbar
import org.android.go.sopt.util.showShortToast


class LoginActivity : AppCompatActivity() {

private lateinit var binding: ActivityLoginBinding
private lateinit var id: String
private lateinit var password: String
private lateinit var name: String
private lateinit var specialty: String

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

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

this.onClickLogin()
this.onCLickSignUp()
}

private fun onClickLogin() {
binding.btMainLogin.setOnClickListener {
if (id == binding.etMainId.text.toString() && password == binding.etMainPassword.text.toString()) {
SeonHwan-Kim marked this conversation as resolved.
Show resolved Hide resolved
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("name", name)
intent.putExtra("specialty", specialty)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 "name", "specialty" 와 같은 부분은 매직리터럴이라고 합니다~
만약 MainActivity 에서 intent 로 부터 담긴 value 를 꺼내올때 key 에 오타가 있으면 컴파일 시점에는 잡히지 않는데,
런타임 시점에서는 버그로 발생되어지겠죵?

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent)
showShortToast(getString(R.string.login_success_login_msg))
SeonHwan-Kim marked this conversation as resolved.
Show resolved Hide resolved
} else {
showShortToast(getString(R.string.login_fail_login_msg))
}
}
}

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

private val getResultSignUp = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: ActivityResult ->
if (result.resultCode == RESULT_OK) {
id = result.data?.getStringExtra("id") ?: ""
password = result.data?.getStringExtra("password") ?: ""
name = result.data?.getStringExtra("name") ?: ""
specialty = result.data?.getStringExtra("specialty") ?: ""
SeonHwan-Kim marked this conversation as resolved.
Show resolved Hide resolved
showShortSnackbar(binding.root, getString(R.string.login_success_sign_up_msg))
}
}
}
27 changes: 27 additions & 0 deletions app/src/main/java/org/android/go/sopt/main/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.android.go.sopt.main

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import org.android.go.sopt.databinding.ActivityMainBinding


class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var name: String
private lateinit var specialty: String

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

this.getMyData()
SeonHwan-Kim marked this conversation as resolved.
Show resolved Hide resolved
}

private fun getMyData() {
name = intent.getStringExtra("name").toString()
specialty = intent.getStringExtra("specialty").toString()
binding.tvMainName.text = "이름 : $name"
binding.tvMainSpecialty.text = "특기 : $specialty"
}
}
55 changes: 55 additions & 0 deletions app/src/main/java/org/android/go/sopt/signup/SignUpActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.android.go.sopt.signup

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import org.android.go.sopt.R
import org.android.go.sopt.databinding.ActivitySignUpBinding
import org.android.go.sopt.login.LoginActivity
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(){
binding.btSignupComplete.setOnClickListener{
val id = binding.etSignupId.text
val password = binding.etSignupPassword.text
val name = binding.etSignupName.text
val specialty = binding.etSignupSpecialty.text

if(id.length !in 6..10){

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 if, else 처리는 개인적으로 코틀린 스럽지 않다고 생각되어지고요..
이런거 해결하는 방법들을 코틀린스럽게 에서 알려줄게요~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵!!

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, LoginActivity::class.java)
intent.putExtra("id", id.toString())
intent.putExtra("password", password.toString())
intent.putExtra("name", name.toString())
intent.putExtra("specialty", specialty.toString())
setResult(RESULT_OK, intent)
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()
}
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.
96 changes: 96 additions & 0 deletions app/src/main/res/layout/activity_login.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:paddingHorizontal="30dp"
tools:context=".login.LoginActivity">

<TextView
android:id="@+id/tv_main_welcome"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="@string/login_welcome"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/tv_main_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="@string/id_title"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_main_welcome" />

<EditText
android:id="@+id/et_main_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:hint="@string/id_hint"
android:imeOptions="actionNext"
android:inputType="text"
android:padding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_main_id" />

<TextView
android:id="@+id/tv_main_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="@string/password_title"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_main_id" />

<EditText
android:id="@+id/et_main_password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:hint="@string/password_hint"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:padding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_main_password" />

<Button
android:id="@+id/bt_main_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:padding="10dp"
android:text="@string/login_btn"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_main_password" />

<Button
android:id="@+id/bt_main_sign_up"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:padding="10dp"
android:text="@string/sign_up_btn"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_main_login" />


</androidx.constraintlayout.widget.ConstraintLayout>
30 changes: 26 additions & 4 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,37 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
android:paddingTop="30dp"
tools:context=".main.MainActivity">

<ImageView
android:id="@+id/iv_main_image"
android:layout_width="100dp"
android:layout_height="0dp"
android:src="@drawable/img_introduce"
app:layout_constraintDimensionRatio="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/tv_main_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toBottomOf="@id/iv_main_image" />

<TextView
android:id="@+id/tv_main_specialty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_main_name" />

</androidx.constraintlayout.widget.ConstraintLayout>
Loading