Skip to content
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
7 changes: 6 additions & 1 deletion .idea/codeStyles/Project.xml

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

1 change: 1 addition & 0 deletions .idea/codeStyles/codeStyleConfig.xml

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

3 changes: 3 additions & 0 deletions app/.idea/.gitignore

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

17 changes: 17 additions & 0 deletions app/.idea/gradle.xml

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

9 changes: 9 additions & 0 deletions app/.idea/misc.xml

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

8 changes: 8 additions & 0 deletions app/.idea/modules.xml

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

27 changes: 26 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}

android {
Expand Down Expand Up @@ -29,15 +30,39 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}

dataBinding {
enabled = true
}
}

dependencies {

implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
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'
}
11 changes: 10 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="place.pic.android.plus">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
Expand All @@ -10,7 +13,13 @@
android:supportsRtl="true"
android:theme="@style/Theme.AssignmentMVVM">
<activity
android:name=".MainActivity"
android:name=".view.UserDetailActivity"
android:exported="false" />
<activity
android:name=".view.MainActivity"
android:exported="false" />
<activity
android:name=".view.UserSearchActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package place.pic.android.plus.adapter

import android.widget.ImageView
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide

/**
* Created By kimdahyee
* on 11월 04일, 2020
*/

class UserDetailBindingAdapter {
companion object {
@JvmStatic
@BindingAdapter("detailImageUrl")
fun loadDetailImage(imageView: ImageView, url: String?) {
Glide.with(imageView.context).load(url).into(imageView)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package place.pic.android.plus.adapter

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import place.pic.android.plus.databinding.ItemUserSearchBinding
import place.pic.android.plus.model.User

/**
* Created By kimdahyee
* on 11월 02일, 2020
*/

class UserSearchAdapter : RecyclerView.Adapter<UserSearchAdapter.UserViewHolder>() {

private var data: MutableList<User> = 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<User>) {
data = users as MutableList<User>
notifyDataSetChanged()
}

fun setItemClickListener(itemClickListener: ((user: User) -> Unit)?) {
this.itemClickListener = itemClickListener
}

fun createUserItemClickListener(user: User) = View.OnClickListener {
itemClickListener?.invoke(user)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package place.pic.android.plus.adapter

import android.widget.ImageView
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide

/**
* Created By kimdahyee
* on 11월 03일, 2020
*/

class UserSearchBindingAdapter {
companion object {
@JvmStatic
@BindingAdapter("imageUrl")
fun loadImage(imageView: ImageView, url: String) {
Glide.with(imageView.context).load(url).into(imageView)
}
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/place/pic/android/plus/model/User.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package place.pic.android.plus.model

/**
* Created By kimdahyee
* on 11월 02일, 2020
*/

data class User(
val imageUrl: String,
val name: String,
val id: Long
)
25 changes: 25 additions & 0 deletions app/src/main/java/place/pic/android/plus/model/UserDetail.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package place.pic.android.plus.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
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package place.pic.android.plus.remote

import place.pic.android.plus.model.UserDetail
import place.pic.android.plus.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<UserSearchResponse>

@GET("users/{username}")
fun requestUserDetail(
@Header("accept") token: String,
@Path("username") login: String
): Call<UserDetail>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package place.pic.android.plus.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)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package place.pic.android.plus.remote.response

/**
* Created By kimdahyee
* on 11월 02일, 2020
*/

data class UserSearchResponse(
val total_count: Int,
val incomplete_results: Boolean,
val items: List<Data>
) {
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
)
}
Original file line number Diff line number Diff line change
@@ -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.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)
}
}
Loading