diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index ea4e5d0..a8fce2b 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,7 +1,9 @@
+
+
+
-
@@ -113,5 +115,8 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
index df5f35d..a01a3e5 100644
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 0000000..1a44a9c
--- /dev/null
+++ b/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/.gitignore b/app/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/app/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/app/.idea/gradle.xml b/app/.idea/gradle.xml
new file mode 100644
index 0000000..91f278a
--- /dev/null
+++ b/app/.idea/gradle.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/misc.xml b/app/.idea/misc.xml
new file mode 100644
index 0000000..f845854
--- /dev/null
+++ b/app/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/modules.xml b/app/.idea/modules.xml
new file mode 100644
index 0000000..e1f9e1c
--- /dev/null
+++ b/app/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 71490b5..3785980 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,6 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
+ id 'kotlin-kapt'
}
android {
@@ -29,10 +30,15 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
+
+ dataBinding {
+ enabled = true
+ }
}
dependencies {
-
+ implementation 'androidx.activity:activity-ktx:1.2.2'
+ implementation 'androidx.fragment:fragment-ktx:1.3.3'
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
@@ -40,4 +46,25 @@ dependencies {
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+
+ //view
+ implementation 'androidx.recyclerview:recyclerview:1.1.0'
+
+ //livedata
+ def lifecycle_version = "2.2.0"
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
+ implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
+
+ //glide
+ implementation "com.github.bumptech.glide:glide:4.11.0"
+ compileOnly 'com.google.android.wearable:wearable:2.8.1'
+ kapt "com.github.bumptech.glide:compiler:4.11.0"
+
+ //retrofit
+ implementation 'com.squareup.retrofit2:retrofit:2.7.2'
+ implementation 'com.squareup.retrofit2:converter-gson:2.7.1'
+ implementation 'com.squareup.okhttp3:logging-interceptor:4.2.1'
+
+ // Gson
+ implementation 'com.google.code.gson:gson:2.8.6'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8508fca..4d173d9 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,9 @@
+
+
+
+
+
diff --git a/app/src/main/java/place/pic/android/plus/data/model/User.kt b/app/src/main/java/place/pic/android/plus/data/model/User.kt
new file mode 100644
index 0000000..83b32c8
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/data/model/User.kt
@@ -0,0 +1,12 @@
+package place.pic.android.plus.data.model
+
+/**
+ * Created By kimdahyee
+ * on 11월 02일, 2020
+ */
+
+data class User(
+ val imageUrl: String,
+ val name: String,
+ val id: Long
+)
diff --git a/app/src/main/java/place/pic/android/plus/data/model/UserDetail.kt b/app/src/main/java/place/pic/android/plus/data/model/UserDetail.kt
new file mode 100644
index 0000000..5929597
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/data/model/UserDetail.kt
@@ -0,0 +1,25 @@
+package place.pic.android.plus.data.model
+
+import com.google.gson.annotations.SerializedName
+
+/**
+ * Created By kimdahyee
+ * on 11월 03일, 2020
+ */
+
+data class UserDetail(
+ @SerializedName("avatar_url")
+ val imageUrl: String?,
+
+ @SerializedName("login")
+ val name: String,
+
+ @SerializedName("bio")
+ val bio: String?,
+
+ @SerializedName("followers")
+ val followers: Int,
+
+ @SerializedName("html_url")
+ val htmlUrl: String
+)
diff --git a/app/src/main/java/place/pic/android/plus/data/remote/GithubApiService.kt b/app/src/main/java/place/pic/android/plus/data/remote/GithubApiService.kt
new file mode 100644
index 0000000..7e2ab04
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/data/remote/GithubApiService.kt
@@ -0,0 +1,27 @@
+package place.pic.android.plus.data.remote
+
+import place.pic.android.plus.data.model.UserDetail
+import place.pic.android.plus.data.remote.response.UserSearchResponse
+import retrofit2.Call
+import retrofit2.http.GET
+import retrofit2.http.Header
+import retrofit2.http.Path
+import retrofit2.http.Query
+
+/**
+ * Created By kimdahyee
+ * on 11월 02일, 2020
+ */
+
+interface GithubApiService {
+ @GET("search/users")
+ fun requestUserSearch(
+ @Query("q") param: String?
+ ): Call
+
+ @GET("users/{username}")
+ fun requestUserDetail(
+ @Header("accept") token: String,
+ @Path("username") login: String
+ ): Call
+}
diff --git a/app/src/main/java/place/pic/android/plus/data/remote/GithubApiServiceImpl.kt b/app/src/main/java/place/pic/android/plus/data/remote/GithubApiServiceImpl.kt
new file mode 100644
index 0000000..eb6897c
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/data/remote/GithubApiServiceImpl.kt
@@ -0,0 +1,19 @@
+package place.pic.android.plus.data.remote
+
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+
+/**
+ * Created By kimdahyee
+ * on 11월 02일, 2020
+ */
+
+object GithubApiServiceImpl {
+ private val retrofit: Retrofit
+ get() = Retrofit.Builder()
+ .baseUrl("https://api.github.com/")
+ .addConverterFactory(GsonConverterFactory.create())
+ .build()
+
+ val service: GithubApiService = retrofit.create(GithubApiService::class.java)
+}
diff --git a/app/src/main/java/place/pic/android/plus/data/remote/response/UserSearchResponse.kt b/app/src/main/java/place/pic/android/plus/data/remote/response/UserSearchResponse.kt
new file mode 100644
index 0000000..b0cba54
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/data/remote/response/UserSearchResponse.kt
@@ -0,0 +1,33 @@
+package place.pic.android.plus.data.remote.response
+
+/**
+ * Created By kimdahyee
+ * on 11월 02일, 2020
+ */
+
+data class UserSearchResponse(
+ val total_count: Int,
+ val incomplete_results: Boolean,
+ val items: List
+) {
+ data class Data(
+ val login: String,
+ val id: Long,
+ val node_id: String,
+ val avatar_url: String,
+ val url: String,
+ val html_url: String,
+ val followers_url: String,
+ val following_url: String,
+ val gists_url: String,
+ val starred_url: String,
+ val subscriptions_url: String,
+ val organizations_url: String,
+ val repos_url: String,
+ val events_url: String,
+ val received_events_url: String,
+ val type: String,
+ val site_admin: Boolean,
+ val score: Double
+ )
+}
diff --git a/app/src/main/java/place/pic/android/plus/ui/Event.kt b/app/src/main/java/place/pic/android/plus/ui/Event.kt
new file mode 100644
index 0000000..cc11604
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/ui/Event.kt
@@ -0,0 +1,29 @@
+package place.pic.android.plus.ui
+
+/**
+ * Created By kimdahyee
+ * on 11월 23일, 2020
+ */
+
+open class Event(private val content: T) {
+
+ var hasBeenHandled = false
+ private set // Allow external read but not write
+
+ /**
+ * Returns the content and prevents its use again.
+ */
+ fun getContentIfNotHandled(): T? {
+ return if (hasBeenHandled) {
+ null
+ } else {
+ hasBeenHandled = true
+ content
+ }
+ }
+
+ /**
+ * Returns the content, even if it's already been handled.
+ */
+ fun peekContent(): T = content
+}
diff --git a/app/src/main/java/place/pic/android/plus/ui/SingleLiveEvent.kt b/app/src/main/java/place/pic/android/plus/ui/SingleLiveEvent.kt
new file mode 100644
index 0000000..074a418
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/ui/SingleLiveEvent.kt
@@ -0,0 +1,54 @@
+package place.pic.android.plus.ui
+
+import android.util.Log
+import androidx.annotation.MainThread
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.Observer
+import java.util.concurrent.atomic.AtomicBoolean
+
+/**
+ * Created By kimdahyee
+ * on 11월 23일, 2020
+ */
+
+class SingleLiveEvent : MutableLiveData() {
+
+ // AtomicBoolean - multiThread 환경에서 동시성 보장
+ private val pending = AtomicBoolean(false)
+
+ // view가 활성화 상태가 되거나 setValue를 통해 값이 바뀌었을 때 호출되는 함수
+ @MainThread
+ override fun observe(owner: LifecycleOwner, observer: Observer) {
+ if (hasActiveObservers()) {
+ Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
+ }
+ // Observe the internal MutableLiveData
+ super.observe(
+ owner,
+ { t ->
+ if (pending.compareAndSet(true, false)) {
+ observer.onChanged(t)
+ }
+ }
+ )
+ }
+
+ @MainThread
+ override fun setValue(t: T?) {
+ pending.set(true)
+ super.setValue(t)
+ }
+
+ /**
+ * Used for cases where T is Void, to make calls cleaner.
+ */
+ @MainThread
+ fun call() {
+ value = null
+ }
+
+ companion object {
+ private const val TAG = "SingleLiveEvent"
+ }
+}
diff --git a/app/src/main/java/place/pic/android/plus/ui/adapter/BindingAdapter.kt b/app/src/main/java/place/pic/android/plus/ui/adapter/BindingAdapter.kt
new file mode 100644
index 0000000..dea7115
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/ui/adapter/BindingAdapter.kt
@@ -0,0 +1,26 @@
+package place.pic.android.plus.ui.adapter
+
+import android.widget.ImageView
+import androidx.databinding.BindingAdapter
+import com.bumptech.glide.Glide
+
+/**
+ * Created By kimdahyee
+ * on 11월 17일, 2020
+ */
+
+class BindingAdapter {
+ companion object {
+ @JvmStatic
+ @BindingAdapter("imageUrl")
+ fun loadImage(imageView: ImageView, url: String) {
+ Glide.with(imageView.context).load(url).into(imageView)
+ }
+
+ @JvmStatic
+ @BindingAdapter("detailImageUrl")
+ fun loadDetailImage(imageView: ImageView, url: String?) {
+ Glide.with(imageView.context).load(url).into(imageView)
+ }
+ }
+}
diff --git a/app/src/main/java/place/pic/android/plus/ui/adapter/UserSearchAdapter.kt b/app/src/main/java/place/pic/android/plus/ui/adapter/UserSearchAdapter.kt
new file mode 100644
index 0000000..1b415a3
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/ui/adapter/UserSearchAdapter.kt
@@ -0,0 +1,56 @@
+package place.pic.android.plus.ui.adapter
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import place.pic.android.plus.data.model.User
+import place.pic.android.plus.databinding.ItemUserSearchBinding
+
+/**
+ * Created By kimdahyee
+ * on 11월 02일, 2020
+ */
+
+class UserSearchAdapter : RecyclerView.Adapter() {
+
+ private var data: MutableList = mutableListOf()
+ private var itemClickListener: ((user: User) -> Unit) ? = null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = ItemUserSearchBinding.inflate(layoutInflater, parent, false)
+ return UserViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
+ holder.bind(data[position])
+ }
+
+ override fun getItemCount(): Int {
+ return data.size
+ }
+
+ inner class UserViewHolder(
+ private val binding: ItemUserSearchBinding
+ ) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(user: User) {
+ binding.user = user
+ binding.clickListener = createUserItemClickListener(user)
+ }
+ }
+
+ fun setItem(users: List) {
+ data = users as MutableList
+ notifyDataSetChanged()
+ }
+
+ fun setItemClickListener(itemClickListener: ((user: User) -> Unit)?) {
+ this.itemClickListener = itemClickListener
+ }
+
+ fun createUserItemClickListener(user: User) = View.OnClickListener {
+ itemClickListener?.invoke(user)
+ }
+}
diff --git a/app/src/main/java/place/pic/android/plus/MainActivity.kt b/app/src/main/java/place/pic/android/plus/ui/view/MainActivity.kt
similarity index 79%
rename from app/src/main/java/place/pic/android/plus/MainActivity.kt
rename to app/src/main/java/place/pic/android/plus/ui/view/MainActivity.kt
index b8670ea..ce7e4a5 100644
--- a/app/src/main/java/place/pic/android/plus/MainActivity.kt
+++ b/app/src/main/java/place/pic/android/plus/ui/view/MainActivity.kt
@@ -1,11 +1,12 @@
-package place.pic.android.plus
-
-import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
-
-class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- }
-}
+package place.pic.android.plus.ui.view
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import place.pic.android.plus.R
+
+class MainActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+ }
+}
diff --git a/app/src/main/java/place/pic/android/plus/ui/view/UserDetailActivity.kt b/app/src/main/java/place/pic/android/plus/ui/view/UserDetailActivity.kt
new file mode 100644
index 0000000..93bc42e
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/ui/view/UserDetailActivity.kt
@@ -0,0 +1,28 @@
+package place.pic.android.plus.ui.view
+
+import android.os.Bundle
+import android.util.Log
+import androidx.activity.viewModels
+import androidx.appcompat.app.AppCompatActivity
+import place.pic.android.plus.databinding.ActivityUserDatailBinding
+import place.pic.android.plus.ui.viewmodel.UserDetailViewModel
+
+class UserDetailActivity : AppCompatActivity() {
+
+ private val userDetailViewModel: UserDetailViewModel by viewModels()
+ private var username: String = ""
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ username = intent.getStringExtra("username").toString()
+ Log.d("디테일액티비티", username)
+ init()
+ }
+
+ private fun init() {
+ val binding = ActivityUserDatailBinding.inflate(layoutInflater)
+ binding.viewModel = userDetailViewModel
+ userDetailViewModel.requestUserDetail(username)
+ setContentView(binding.root)
+ }
+}
diff --git a/app/src/main/java/place/pic/android/plus/ui/view/UserSearchActivity.kt b/app/src/main/java/place/pic/android/plus/ui/view/UserSearchActivity.kt
new file mode 100644
index 0000000..5fe02f8
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/ui/view/UserSearchActivity.kt
@@ -0,0 +1,72 @@
+package place.pic.android.plus.ui.view
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import android.view.inputmethod.InputMethodManager
+import android.widget.EditText
+import android.widget.Toast
+import androidx.activity.viewModels
+import androidx.appcompat.app.AppCompatActivity
+import androidx.databinding.DataBindingUtil
+import place.pic.android.plus.R
+import place.pic.android.plus.data.model.User
+import place.pic.android.plus.databinding.ActivitySearchBinding
+import place.pic.android.plus.ui.adapter.UserSearchAdapter
+import place.pic.android.plus.ui.viewmodel.UserSearchViewModel
+
+class UserSearchActivity : AppCompatActivity() {
+
+ private val userSearchViewModel: UserSearchViewModel by viewModels()
+ private val userSearchAdapter by lazy { UserSearchAdapter() }
+ private lateinit var binding: ActivitySearchBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_search)
+ binding.rcvUserSearch.adapter = userSearchAdapter
+ binding.viewModel = userSearchViewModel
+ binding.lifecycleOwner = this
+
+ searchUser()
+ userItemClick()
+ }
+
+ private fun searchUser() {
+ binding.btUserSearch.setOnClickListener { onSearchClick() }
+ userSearchViewModel.users.observe(this) {
+ userSearchAdapter.setItem(it)
+ }
+ }
+
+ private fun userItemClick() {
+ userSearchAdapter.setItemClickListener { onUserItemClick(it) }
+ }
+
+ private fun onUserItemClick(user: User) {
+ val intent = Intent(this, UserDetailActivity::class.java)
+ Log.d("온유저아이템클릭", user.name)
+ intent.putExtra("username", user.name)
+ startActivity(intent)
+ }
+
+ private fun onSearchClick() {
+ var input = findViewById(R.id.et_user_search)
+ if (input == null) {
+ Toast.makeText(this, "검색어를 입력하세요.", Toast.LENGTH_SHORT).show()
+ } else {
+ input.run {
+ userSearchViewModel.requestUserSearch(input.text.toString())
+ hideKeyboard()
+ }
+ }
+ }
+
+ private fun hideKeyboard() {
+ currentFocus?.run {
+ val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
+ imm?.hideSoftInputFromWindow(windowToken, 0)
+ }
+ }
+}
diff --git a/app/src/main/java/place/pic/android/plus/ui/viewmodel/UserDetailViewModel.kt b/app/src/main/java/place/pic/android/plus/ui/viewmodel/UserDetailViewModel.kt
new file mode 100644
index 0000000..3746daa
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/ui/viewmodel/UserDetailViewModel.kt
@@ -0,0 +1,55 @@
+package place.pic.android.plus.ui.viewmodel
+
+import android.util.Log
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import place.pic.android.plus.data.model.UserDetail
+import place.pic.android.plus.data.remote.GithubApiServiceImpl
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+/**
+ * Created By kimdahyee
+ * on 11월 03일, 2020
+ */
+
+class UserDetailViewModel : ViewModel() {
+
+ private val token = "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"
+
+ private lateinit var user: UserDetail
+ private val _userDetail = MutableLiveData()
+ val userDetail: LiveData
+ get() = _userDetail
+
+ fun setUserDetail() {
+ _userDetail.value = user
+ Log.d("디테일세터확인", _userDetail.value!!.name)
+ }
+
+ fun requestUserDetail(login: String) {
+ GithubApiServiceImpl.service.requestUserDetail(
+ token = token,
+ login = login
+ ).enqueue(object : Callback {
+ override fun onResponse(call: Call, response: Response) {
+ if (response.isSuccessful) {
+ user = UserDetail(
+ imageUrl = response.body()?.imageUrl,
+ name = response.body()!!.name,
+ bio = response.body()?.bio,
+ followers = response.body()!!.followers,
+ htmlUrl = response.body()!!.htmlUrl
+ )
+ }
+ setUserDetail()
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ t.message?.let { Log.d("fail", it) }
+ }
+ })
+ }
+}
diff --git a/app/src/main/java/place/pic/android/plus/ui/viewmodel/UserSearchViewModel.kt b/app/src/main/java/place/pic/android/plus/ui/viewmodel/UserSearchViewModel.kt
new file mode 100644
index 0000000..d0d0e5c
--- /dev/null
+++ b/app/src/main/java/place/pic/android/plus/ui/viewmodel/UserSearchViewModel.kt
@@ -0,0 +1,71 @@
+package place.pic.android.plus.ui.viewmodel
+
+import android.util.Log
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import place.pic.android.plus.data.model.User
+import place.pic.android.plus.data.remote.GithubApiServiceImpl
+import place.pic.android.plus.data.remote.response.UserSearchResponse
+import place.pic.android.plus.ui.Event
+import place.pic.android.plus.ui.SingleLiveEvent
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+/**
+ * Created By kimdahyee
+ * on 11월 02일, 2020
+ */
+
+class UserSearchViewModel : ViewModel() {
+
+ private val list = mutableListOf()
+
+ private val _users = MutableLiveData>()
+ val users: LiveData>
+ get() = _users
+
+ fun addUser(user: User) {
+ list.add(user)
+ _users.value = list
+ }
+
+ private val _searchItemClickEvent = SingleLiveEvent>()
+ val searchItemClickEvent: SingleLiveEvent>
+ get() = _searchItemClickEvent
+
+ fun setSearchItemClickEvent() { // itemId: String
+ _searchItemClickEvent.call()
+ // _searchItemClickEvent.value = Event(itemId)
+ }
+
+ fun requestUserSearch(query: String) {
+ GithubApiServiceImpl.service.requestUserSearch(
+ param = query
+ ).enqueue(object : Callback {
+ override fun onResponse(
+ call: Call,
+ response: Response
+ ) {
+ if (response.isSuccessful) {
+ Log.d("server check", "통신 성공")
+ list.clear()
+ for (i in response.body()!!.items.indices) {
+ addUser(
+ User(
+ imageUrl = response.body()!!.items[i].avatar_url,
+ name = response.body()!!.items[i].login,
+ id = response.body()!!.items[i].id
+ )
+ )
+ }
+ }
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ t.message?.let { Log.d("fail", it) }
+ }
+ })
+ }
+}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index ca0c0de..19e79c9 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".MainActivity">
+ tools:context=".ui.view.MainActivity">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_user_datail.xml b/app/src/main/res/layout/activity_user_datail.xml
new file mode 100644
index 0000000..b2505e4
--- /dev/null
+++ b/app/src/main/res/layout/activity_user_datail.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_user_search.xml b/app/src/main/res/layout/item_user_search.xml
new file mode 100644
index 0000000..a9167bf
--- /dev/null
+++ b/app/src/main/res/layout/item_user_search.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index 703940f..5ad164d 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -1,6 +1,6 @@
-