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

Seminar 7_hw #4

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/runConfigurations.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

210 changes: 140 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,152 @@
#### 1. 구현방법
- 2차 세미나에서 배운 내용을 바탕으로 FollowingRepo.kt, FollowingRepoAdapter.kt, FollowingRepoFragment.kt, RepoInfoActivity.kt 등의 파일들을
만들어 코드를 작성하였다.
- 먼저 부분 화면 Fragment를 만들어 ist로 구현해 화면으로 보여주기 위해 item_repo.xml을 만들어
# ![마크업 이미지3](https://user-images.githubusercontent.com/80473521/118394517-1e93bd80-b680-11eb-9fb1-a14cb453e3ba.jpg) Seventh Seminar Assignment ![마크업 이미지3](https://user-images.githubusercontent.com/80473521/118394517-1e93bd80-b680-11eb-9fb1-a14cb453e3ba.jpg)


## ![마크업 이미지1](https://user-images.githubusercontent.com/80473521/118394520-1fc4ea80-b680-11eb-9641-df4063f3f257.jpg) 자동 로그인 구현하기

1) SignInActivity로 처음 들어왔을 때 SharedPreference에서 ID/PW가 있다면? 로그인 과정을 건너뛴다.
2) 로그인할 때 성공하면 SharedPreference에 집어 넣는다.
3) 서비스에서 로그아웃하면 SharedPreference를 clear한다.

result => 위와 같은 과정으로 자동 로그인처럼 구현할 수 있다.

### 1. Lv1-1 Activity에서 어떻게 처리했는지 정리
< SignInActivity 코드 정리 >
```kotlin
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textStyle="bold"
android:ellipsize="end"
android:layout_marginHorizontal="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="레포지터리 이름" />
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
searchUserAuthStorage()
loginButtonEvent()
signUpResult()
}
private fun searchUserAuthStorage() {
with(SoptUserAuthStorage.getInstance(this)) {
if (hasUserData()) {
requestLogin(getUserData().let { RequestLoginData(it.id, it.password) })
}
}
}

private fun loginButtonEvent() {
binding.button.setOnClickListener{
val requestLoginData = RequestLoginData(
id = binding.idedit.text.toString(),
password = binding.passedit.text.toString()
)
requestLogin(requestLoginData)
}
}
private fun signUpResult() {
binding.signup.setOnClickListener {
signUpActivityLauncher.launch(
Intent(this, SignUpActivity::class.java)
)
}
}
```
이와 같은 3개의 TextView를 생성하였다. 레포지터리 이름과 레포지터리 설명이 너무 긴경우 ...이 나오도록
- SignInActivity가 onCreate일 때 이전에 작성한 ID/PW가 있으면 바로 로그인 시키고 없으면 원래 과정으로 진행
- 전의 세미나에서 만든 것 그대로
'button' 버튼을 누르면 id, password 데이터를 전달,
'signup' 텍스트를 누르면 SignUpActivity로 이동

```kotlin
android:ellipsize="end"
private fun requestLogin(requestLoginData: RequestLoginData) {
val call: Call<ResponseLoginData> = ServiceCreator.soptService
.postLogin(requestLoginData)
call.enqueueUtil(
onSuccess = { response ->
val data = response.data
showToast(data?.user_nickname.toString())
with(SoptUserAuthStorage.getInstance(this)) {
saveUserData(requestLoginData.let { SoptUserInfo(it.id, it.password) })
}
startHomeActivity()
}
)
}
```
코드도 추가해주었다.
* RecyclerView를 이용해 HomeActivity에 해당 Fragment를 보여주기 위해 fragment_following_repo.xml에
- 확장함수를 이용하여 requestLogin 간단하게 구현

< 코틀린 확장 함수>
- ToastUtil.kt
```kotlin
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/repo_list"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text"
tools:listitem="@layout/item_repo"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
fun Context.showToast(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT)
.show()
}
```
위와 같은 코드를 작성하고 화면에 보여주기 위해 HomeActivity에
- RetrofitEnqueueUtil.kt
```kotlin
val repoFragment = FollowingRepoFragment()
val manager = supportFragmentManager
val transaction = manager.beginTransaction()
transaction.replace(R.id.fragment_container,repoFragment)
transaction.addToBackStack(null)
transaction.commit()
fun <ResponseType> Call<ResponseType>.enqueueUtil(
onSuccess: (ResponseType) -> Unit,
onError: ((stateCode: Int) -> Unit)? = null
) {
this.enqueue(object : Callback<ResponseType> {
override fun onResponse(call: Call<ResponseType>, response: Response<ResponseType>) {
if (response.isSuccessful) {
onSuccess.invoke(response.body() ?: return)
} else {
onError?.invoke(response.code())
}
}

override fun onFailure(call: Call<ResponseType>, t: Throwable) {
Log.d("NetworkTest", "error:$t")
}
})
}
```
위와 같은 코드를 추가해주었다. 이 코드를 통해 Fragment가 HomeActivity의 화면에 뜨게 된다.
* HomeActivity화면에 MORE 버튼을 추가하여 2차 세미나 시간에 만든 Fragment를 가진 Activity를 띄워주기 위해 먼저
### 2. Lv1-2 SharedPreference 어떻게 코드를 정리했는지 코드 첨부
- SharedPreference를 계속 만들면 비효율적이므로 object을 이용해 한 번만 만들기
```kotlin
<Button
android:id="@+id/btn_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="300dp"
app:layout_constraintBottom_toBottomOf="@id/text"
app:layout_constraintEnd_toEndOf="parent"
android:text="MORE" />
class SoptUserAuthStorage private constructor(context: Context) {

private val sharedPreferences = context.getSharedPreferences(
"${context.packageName}.$STORAGE_KEY",
Context.MODE_PRIVATE
)

<LinearLayout
android:id="@+id/fragment_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="600dp"
app:layout_constraintTop_toBottomOf="@+id/btn_more"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent">
</LinearLayout>
```
activity_home.xml파일에 MORE button과 Fragment를 가진 Activity가 띄워질 위치 선정을 위해 LinearLayout을 생성했다.
(앞서 직접 만든 레포지터리 이름, 설명 등의 Fragment를 가진 Activity도 해당 위치에 띄워질 수 있도록 위의 LinearLayout을 이용했다.)
* 그리고 MORE button을 눌렀을 경우 2차 세미나에서 만든 Fragment를 가진 Activity가 띄워질 수 있도록
```kotlin
binding.btnMore.setOnClickListener(){
val infoFragment = FollowingListFragment()
val manager = supportFragmentManager
val transaction = manager.beginTransaction()
transaction.replace(R.id.fragment_container,infoFragment)
transaction.addToBackStack(null)
transaction.commit()
```
위와 같은 코드를 HomeActivity에 추가하였다.
private val editor = sharedPreferences.edit()

![Screenshot_20210425-135256_Se1_hw](https://user-images.githubusercontent.com/80473521/115981424-99604000-a5ce-11eb-8ff4-1dabe69c326f.jpg)
![Screenshot_20210425-135312_Se1_hw](https://user-images.githubusercontent.com/80473521/115981442-c57bc100-a5ce-11eb-94a5-64c47e17c7bd.jpg)
companion object {
private const val STORAGE_KEY = "user_auth"
private const val USER_ID_KEY = "user_id"
private const val USER_PW_KEY = "user_pw"

@Volatile
private var instance: SoptUserAuthStorage? = null

@JvmStatic
fun getInstance(context: Context) = instance ?: synchronized(this) {
instance ?: SoptUserAuthStorage(context).apply {
instance = this
}
}
}
fun getUserData(): SoptUserInfo = SoptUserInfo(
id = sharedPreferences.getString(USER_ID_KEY, "") ?: "",
password = sharedPreferences.getString(USER_PW_KEY, "") ?: ""
)
fun saveUserData(userData: SoptUserInfo) {
editor.putString(USER_ID_KEY, userData.id)
.putString(USER_PW_KEY, userData.password)
.apply()
}
fun hasUserData(): Boolean {
with(getUserData()) {
return id.isNotEmpty() && password.isNotEmpty()
}
}
fun clearAuthStorage() {
sharedPreferences.edit()
.clear()
.apply()
}
}
```
### 3. 과제를 통해 배운 내용 or 개발자로 성장한 내용
- 이번 과제를 하면서 처음 SharedPreference를 만들어보았습니다. 처음이라 굉장히 어렵다고 생각이 들었고 열심히 세미나 복습을 하면서 과제를 진행해나갔습니다.
어려운 부분은 파트장님의 코드를 보면서 이렇게 만들 수 있구나 생각하고 배울 점은 코드에 반영해가며 과제를 해나간 것 같습니다.
꽤 오랜 시간동안 세미나를 듣고 과제를 해나가면서 그 전보다 한층 더 성장할 수 있었다고 생각이 듭니다. sopt를 들어와 활동한 것은 제가 개발자로 성장할 수 있는 좋은 기회였다고 생각합니다.
감사합니다!
6 changes: 6 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,10 @@ dependencies {
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

implementation 'com.squareup.retrofit2:retrofit:2.9.0'

implementation 'com.google.code.gson:gson:2.8.6'

implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}
12 changes: 7 additions & 5 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.se1_hw">

<uses-permission android:name="android.permission.INTERNET"/>
<application
android:usesCleartextTraffic="true"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Se1_hw">
<activity android:name=".SignUpActivity"></activity>
<activity android:name=".HomeActivity" />
<activity android:name=".RepoInfoActivity">
<activity android:name=".ui.activity.SignUpActivity"></activity>
<activity android:name=".ui.activity.HomeActivity" />
<activity android:name=".ui.activity.RepoInfoActivity">

</activity>
<activity android:name=".UserInfoActivity">
<activity android:name=".ui.activity.UserInfoActivity">

</activity>

<activity android:name=".SignInActivity">
<activity android:name=".ui.activity.SignInActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
88 changes: 0 additions & 88 deletions app/src/main/java/com/example/se1_hw/SignInActivity.kt

This file was deleted.

Loading