From b09f37f33712c950647f4619dc96d128ece0c876 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 13:17:53 +0900 Subject: [PATCH 01/35] =?UTF-8?q?build.gradle=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d97147a..c398242 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,10 +1,10 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-kapt' android { compileSdkVersion 30 - buildToolsVersion "30.0.0" defaultConfig { applicationId "com.studyfork.sfoide" @@ -22,16 +22,50 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + + // Configure only for each module that uses Java 8 + // language features (either in its source code or + // through dependencies). + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + // For Kotlin projects + kotlinOptions { + jvmTarget = "1.8" + } + + dataBinding { + enabled = true + } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.0' implementation 'androidx.appcompat:appcompat:1.1.0' + + implementation 'androidx.core:core-ktx:1.3.0' + implementation 'androidx.activity:activity-ktx:1.1.0' + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0" + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.recyclerview:recyclerview:1.1.0' + implementation 'com.google.android.material:material:1.1.0' + + // test testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + // networking + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.okhttp3:logging-interceptor:4.8.0' + + // log + implementation 'com.jakewharton.timber:timber:4.7.1' + + // image + implementation 'com.github.bumptech.glide:glide:4.11.0' + kapt 'com.github.bumptech.glide:compiler:4.11.0' } \ No newline at end of file From 2eea69dabaf955ec27ff7346e9880f60f270b3e5 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 13:38:16 +0900 Subject: [PATCH 02/35] =?UTF-8?q?=EC=B9=9C=EA=B5=AC=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sfoide/ui/widget/FriendInfoView.kt | 35 ++++++++++++ app/src/main/res/layout/view_friend_info.xml | 56 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt create mode 100644 app/src/main/res/layout/view_friend_info.xml diff --git a/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt b/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt new file mode 100644 index 0000000..c655704 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt @@ -0,0 +1,35 @@ +package com.studyfork.sfoide.ui.widget + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.widget.FrameLayout +import androidx.databinding.DataBindingUtil +import com.studyfork.sfoide.R +import com.studyfork.sfoide.databinding.ViewFriendInfoBinding + +class FriendInfoView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, + defStyleRes: Int = 0 +) : FrameLayout(context, attrs, defStyleAttr, defStyleRes) { + + private lateinit var binding: ViewFriendInfoBinding + + private val layoutId = R.layout.view_friend_info + + init { + initBinding() + } + + private fun initBinding() { + binding = DataBindingUtil.inflate( + LayoutInflater.from(context), + layoutId, + this, + false + ) + addView(binding.root) + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/view_friend_info.xml b/app/src/main/res/layout/view_friend_info.xml new file mode 100644 index 0000000..87e359e --- /dev/null +++ b/app/src/main/res/layout/view_friend_info.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + \ No newline at end of file From ca8aee1e600fdfa985f580c1785bb9e0ebddf6a6 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 13:56:39 +0900 Subject: [PATCH 03/35] =?UTF-8?q?Friends=20=ED=99=94=EB=A9=B4=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 1 + app/src/main/res/layout/activity_main.xml | 43 +++++++++++++++-------- app/src/main/res/layout/item_friend.xml | 40 +++++++++++++++++++++ 3 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 app/src/main/res/layout/item_friend.xml diff --git a/app/build.gradle b/app/build.gradle index c398242..0e7206e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -52,6 +52,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'com.google.android.material:material:1.1.0' + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" // test testImplementation 'junit:junit:4.12' diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4fc2444..642bf6b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,18 +1,33 @@ - + xmlns:tools="http://schemas.android.com/tools"> - + - \ No newline at end of file + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_friend.xml b/app/src/main/res/layout/item_friend.xml new file mode 100644 index 0000000..25278ef --- /dev/null +++ b/app/src/main/res/layout/item_friend.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file From 486037694aa084cdd4c8283d900b6a23c0c8c051 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 14:19:24 +0900 Subject: [PATCH 04/35] =?UTF-8?q?friendActivity=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 2 +- .../java/com/studyfork/sfoide/MainActivity.kt | 11 ---- .../com/studyfork/sfoide/data/model/Friend.kt | 19 +++++++ .../sfoide/ui/friend/FriendActivity.kt | 38 ++++++++++++++ .../sfoide/ui/friend/FriendAdapter.kt | 52 +++++++++++++++++++ .../sfoide/ui/friend/FriendViewModel.kt | 31 +++++++++++ ...{activity_main.xml => activity_friend.xml} | 10 +++- app/src/main/res/layout/item_friend.xml | 4 +- 8 files changed, 152 insertions(+), 15 deletions(-) delete mode 100644 app/src/main/java/com/studyfork/sfoide/MainActivity.kt create mode 100644 app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/friend/FriendAdapter.kt create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt rename app/src/main/res/layout/{activity_main.xml => activity_friend.xml} (73%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d17cca5..dc07e56 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,7 +9,7 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> - + diff --git a/app/src/main/java/com/studyfork/sfoide/MainActivity.kt b/app/src/main/java/com/studyfork/sfoide/MainActivity.kt deleted file mode 100644 index af5f449..0000000 --- a/app/src/main/java/com/studyfork/sfoide/MainActivity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.studyfork.sfoide - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt b/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt new file mode 100644 index 0000000..3789a70 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt @@ -0,0 +1,19 @@ +package com.studyfork.sfoide.data.model + +data class Friend( + val id: String, + val thumbnail: String, + val name: String, + val age: Int, + val gender: String, + val country: String, + val email: String, + val telephone: String, + val mobilePhone: String, + val coordinates: Coordinates +) + +class Coordinates( + val latitude: String, + val longitude: String +) \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt new file mode 100644 index 0000000..4091841 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt @@ -0,0 +1,38 @@ +package com.studyfork.sfoide.ui.friend + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import androidx.activity.viewModels +import androidx.databinding.DataBindingUtil +import androidx.lifecycle.Observer +import com.studyfork.sfoide.R +import com.studyfork.sfoide.databinding.ActivityFriendBinding + +class FriendActivity : AppCompatActivity() { + + private lateinit var binding: ActivityFriendBinding + + private val viewModel: FriendViewModel by viewModels() + + private lateinit var friendAdapter: FriendAdapter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = DataBindingUtil.setContentView(this, R.layout.activity_friend) + binding.lifecycleOwner = this + + initRecyclerView() + observeViewModel() + } + + private fun initRecyclerView() { + friendAdapter = FriendAdapter(viewModel) + binding.rvMain.adapter = friendAdapter + } + + private fun observeViewModel() { + viewModel.friendList.observe(this, Observer { friends -> + friendAdapter.submitList(friends) + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendAdapter.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendAdapter.kt new file mode 100644 index 0000000..68ab008 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendAdapter.kt @@ -0,0 +1,52 @@ +package com.studyfork.sfoide.ui.friend + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.studyfork.sfoide.R +import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.databinding.ItemFriendBinding + +class FriendAdapter( + val viewModel: FriendViewModel +) : ListAdapter(object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: Friend, newItem: Friend): Boolean { + return oldItem.id == newItem.id + } + + override fun areContentsTheSame(oldItem: Friend, newItem: Friend): Boolean { + return oldItem == newItem + } +}) { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FriendViewHolder { + val binding: ItemFriendBinding = DataBindingUtil.inflate( + LayoutInflater.from(parent.context), + R.layout.item_friend, + parent, + false + ) + + val holder = FriendViewHolder(binding) + + binding.root.setOnClickListener { + viewModel.navigateFriendDetail(getItem(holder.adapterPosition)) + } + + return holder + } + + override fun onBindViewHolder(holder: FriendViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + class FriendViewHolder(private val binding: ItemFriendBinding) : RecyclerView.ViewHolder(binding.root) { + + fun bind(friend: Friend) { + binding.friend = friend + binding.executePendingBindings() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt new file mode 100644 index 0000000..657e448 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt @@ -0,0 +1,31 @@ +package com.studyfork.sfoide.ui.friend + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.studyfork.sfoide.data.model.Friend + +class FriendViewModel : ViewModel() { + + private val _friendList = MutableLiveData>() + val friendList: LiveData> = _friendList + + private val _loading = MutableLiveData(false) + val loading: LiveData = _loading + + init { + fetchFriends() + } + + private fun fetchFriends() { + // todo + } + + fun onRefresh() { + // todo + } + + fun navigateFriendDetail(friend: Friend) { + // todo + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_friend.xml similarity index 73% rename from app/src/main/res/layout/activity_main.xml rename to app/src/main/res/layout/activity_friend.xml index 642bf6b..df5867f 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_friend.xml @@ -5,12 +5,15 @@ + + tools:context=".ui.friend.FriendActivity"> + app:layout_constraintTop_toTopOf="parent" + app:onRefreshListener="@{() -> vm.onRefresh()}" + app:refreshing="@{vm.loading}"> diff --git a/app/src/main/res/layout/item_friend.xml b/app/src/main/res/layout/item_friend.xml index 25278ef..7d17321 100644 --- a/app/src/main/res/layout/item_friend.xml +++ b/app/src/main/res/layout/item_friend.xml @@ -4,7 +4,9 @@ xmlns:tools="http://schemas.android.com/tools"> - + Date: Sun, 12 Jul 2020 14:40:07 +0900 Subject: [PATCH 05/35] =?UTF-8?q?FriendApi=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 1 + .../sfoide/data/remote/api/FriendApi.kt | 15 ++ .../data/remote/response/FriendsResponse.kt | 146 ++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/data/remote/api/FriendApi.kt create mode 100644 app/src/main/java/com/studyfork/sfoide/data/remote/response/FriendsResponse.kt diff --git a/app/build.gradle b/app/build.gradle index 0e7206e..1072dcb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -61,6 +61,7 @@ dependencies { // networking implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.8.0' // log diff --git a/app/src/main/java/com/studyfork/sfoide/data/remote/api/FriendApi.kt b/app/src/main/java/com/studyfork/sfoide/data/remote/api/FriendApi.kt new file mode 100644 index 0000000..4380cdd --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/data/remote/api/FriendApi.kt @@ -0,0 +1,15 @@ +package com.studyfork.sfoide.data.remote.api + +import com.studyfork.sfoide.data.remote.response.FriendsResponse +import retrofit2.Call +import retrofit2.http.GET +import retrofit2.http.Query + +interface FriendApi { + + @GET("/") + fun getFriends( + @Query("page") page: Int, + @Query("results") results: Int + ): Call +} \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/data/remote/response/FriendsResponse.kt b/app/src/main/java/com/studyfork/sfoide/data/remote/response/FriendsResponse.kt new file mode 100644 index 0000000..77f3dad --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/data/remote/response/FriendsResponse.kt @@ -0,0 +1,146 @@ +package com.studyfork.sfoide.data.remote.response + +import com.google.gson.annotations.SerializedName + +data class FriendsResponse( + @SerializedName("results") + val results: List?, + @SerializedName("info") + val info: Info? +) { + data class Result( + @SerializedName("gender") + val gender: String?, + @SerializedName("name") + val name: Name?, + @SerializedName("location") + val location: Location?, + @SerializedName("email") + val email: String?, + @SerializedName("login") + val login: Login?, + @SerializedName("dob") + val dob: Dob?, + @SerializedName("registered") + val registered: Registered?, + @SerializedName("phone") + val phone: String?, + @SerializedName("cell") + val cell: String?, + @SerializedName("id") + val id: Id?, + @SerializedName("picture") + val picture: Picture?, + @SerializedName("nat") + val nat: String? + ) { + data class Name( + @SerializedName("title") + val title: String?, + @SerializedName("first") + val first: String?, + @SerializedName("last") + val last: String? + ) { + override fun toString(): String { + return first + last + } + } + + data class Location( + @SerializedName("street") + val street: Street?, + @SerializedName("city") + val city: String?, + @SerializedName("state") + val state: String?, + @SerializedName("country") + val country: String?, + @SerializedName("postcode") + val postcode: Any?, + @SerializedName("coordinates") + val coordinates: Coordinates?, + @SerializedName("timezone") + val timezone: Timezone? + ) { + data class Street( + @SerializedName("number") + val number: Int?, + @SerializedName("name") + val name: String? + ) + + data class Coordinates( + @SerializedName("latitude") + val latitude: String?, + @SerializedName("longitude") + val longitude: String? + ) + + data class Timezone( + @SerializedName("offset") + val offset: String?, + @SerializedName("description") + val description: String? + ) + } + + data class Login( + @SerializedName("uuid") + val uuid: String?, + @SerializedName("username") + val username: String?, + @SerializedName("password") + val password: String?, + @SerializedName("salt") + val salt: String?, + @SerializedName("md5") + val md5: String?, + @SerializedName("sha1") + val sha1: String?, + @SerializedName("sha256") + val sha256: String? + ) + + data class Dob( + @SerializedName("date") + val date: String?, + @SerializedName("age") + val age: Int? + ) + + data class Registered( + @SerializedName("date") + val date: String?, + @SerializedName("age") + val age: Int? + ) + + data class Id( + @SerializedName("name") + val name: String?, + @SerializedName("value") + val value: String? + ) + + data class Picture( + @SerializedName("large") + val large: String?, + @SerializedName("medium") + val medium: String?, + @SerializedName("thumbnail") + val thumbnail: String? + ) + } + + data class Info( + @SerializedName("seed") + val seed: String?, + @SerializedName("results") + val results: Int?, + @SerializedName("page") + val page: Int?, + @SerializedName("version") + val version: String? + ) +} \ No newline at end of file From 13a76f61a35948c893b965eaae7c257904e6f103 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 14:40:25 +0900 Subject: [PATCH 06/35] =?UTF-8?q?RemoteFriendDataSource=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datasource/RemoteFriendDataSourceImpl.kt | 46 +++++++++++++++++++ .../sfoide/data/mapper/FriendMapper.kt | 23 ++++++++++ .../datasource/RemoteFriendDataSource.kt | 13 ++++++ .../sfoide/ui/friend/FriendViewModel.kt | 16 ++++++- 4 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt create mode 100644 app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt create mode 100644 app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt diff --git a/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt b/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt new file mode 100644 index 0000000..c9b9de9 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt @@ -0,0 +1,46 @@ +package com.studyfork.sfoide.data.datasource + +import com.studyfork.sfoide.data.mapper.toEntity +import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.data.remote.api.FriendApi +import com.studyfork.sfoide.data.remote.datasource.RemoteFriendDataSource +import com.studyfork.sfoide.data.remote.response.FriendsResponse +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +class RemoteFriendDataSourceImpl( + private val friendApi: FriendApi +) : RemoteFriendDataSource { + + override fun getFriends( + pageNumber: Int, + itemCount: Int, + onSuccess: (friends: List) -> Unit, + onError: (error: Throwable) -> Unit + ) { + friendApi.getFriends( + page = pageNumber, + results = itemCount + ) + .enqueue(object : Callback { + override fun onFailure(call: Call, t: Throwable) { + onError(t) + } + + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful) { + val friends = + response.body()?.results?.map { FriendResponse -> FriendResponse.toEntity() } + ?: emptyList() + onSuccess(friends) + } else { + onError(Throwable("network error")) + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt new file mode 100644 index 0000000..b5ee56a --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt @@ -0,0 +1,23 @@ +package com.studyfork.sfoide.data.mapper + +import com.studyfork.sfoide.data.model.Coordinates +import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.data.remote.response.FriendsResponse + +fun FriendsResponse.Result.toEntity(): Friend { + return Friend( + id = this.login?.uuid ?: "", + thumbnail = this.picture?.thumbnail ?: "", + name = this.name.toString(), + age = this.dob?.age ?: 0, + gender = this.gender ?: "", + country = this.location?.country ?: "'", + email = this.email ?: "", + telephone = this.phone ?: "", + mobilePhone = this.cell ?: "", + coordinates = Coordinates( + latitude = this.location?.coordinates?.latitude ?: "", + longitude = this.location?.coordinates?.longitude ?: "" + ) + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt b/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt new file mode 100644 index 0000000..dc2356a --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt @@ -0,0 +1,13 @@ +package com.studyfork.sfoide.data.remote.datasource + +import com.studyfork.sfoide.data.model.Friend + +interface RemoteFriendDataSource { + + fun getFriends( + pageNumber: Int, + itemCount: Int, + onSuccess: (friends: List) -> Unit, + onError: (error: Throwable) -> Unit + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt index 657e448..8f8c58f 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt @@ -4,8 +4,11 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.data.remote.datasource.RemoteFriendDataSource -class FriendViewModel : ViewModel() { +class FriendViewModel( + private val remoteFriendDataSource: RemoteFriendDataSource +) : ViewModel() { private val _friendList = MutableLiveData>() val friendList: LiveData> = _friendList @@ -18,7 +21,16 @@ class FriendViewModel : ViewModel() { } private fun fetchFriends() { - // todo + remoteFriendDataSource.getFriends( + pageNumber = 1, + itemCount = 20, + onSuccess = { friends -> + _friendList.value = friends + }, + onError = { + // todo + } + ) } fun onRefresh() { From 757ed7da87a6d365ad7f9c30ef27bfd808710f17 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 14:47:13 +0900 Subject: [PATCH 07/35] =?UTF-8?q?RetrofitService=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sfoide/data/remote/RetrofitService.kt | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/data/remote/RetrofitService.kt diff --git a/app/src/main/java/com/studyfork/sfoide/data/remote/RetrofitService.kt b/app/src/main/java/com/studyfork/sfoide/data/remote/RetrofitService.kt new file mode 100644 index 0000000..34c785e --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/data/remote/RetrofitService.kt @@ -0,0 +1,33 @@ +package com.studyfork.sfoide.data.remote + +import com.studyfork.sfoide.BuildConfig +import com.studyfork.sfoide.data.remote.api.FriendApi +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +object RetrofitService { + + private val retrofit = Retrofit.Builder() + .baseUrl("https://randomuser.me/api") + .client(createOkHttpClient()) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + private fun createOkHttpClient(): OkHttpClient { + return OkHttpClient.Builder().addInterceptor(createHttpLoggingInterceptor()).build() + } + + private fun createHttpLoggingInterceptor(): HttpLoggingInterceptor { + return HttpLoggingInterceptor().apply { + level = if (BuildConfig.DEBUG) { + HttpLoggingInterceptor.Level.BODY + } else { + HttpLoggingInterceptor.Level.NONE + } + } + } + + val friendApi = retrofit.create(FriendApi::class.java) +} \ No newline at end of file From 5b7ee24445ac2b9133cda8cf011a4d75e8b47da1 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 14:48:31 +0900 Subject: [PATCH 08/35] =?UTF-8?q?FriendApp=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 1 + .../main/java/com/studyfork/sfoide/FriendApp.kt | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/FriendApp.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dc07e56..3f1c3a3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ package="com.studyfork.sfoide"> Date: Sun, 12 Jul 2020 14:52:24 +0900 Subject: [PATCH 09/35] =?UTF-8?q?=EC=9D=B8=ED=84=B0=EB=84=B7=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3f1c3a3..ab43f7d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + Date: Sun, 12 Jul 2020 14:52:41 +0900 Subject: [PATCH 10/35] =?UTF-8?q?FriendViewModel=20Factory=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sfoide/ui/friend/FriendActivity.kt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt index 4091841..cdcb380 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt @@ -1,18 +1,29 @@ package com.studyfork.sfoide.ui.friend -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity import androidx.databinding.DataBindingUtil import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import com.studyfork.sfoide.R +import com.studyfork.sfoide.data.datasource.RemoteFriendDataSourceImpl +import com.studyfork.sfoide.data.remote.RetrofitService import com.studyfork.sfoide.databinding.ActivityFriendBinding class FriendActivity : AppCompatActivity() { private lateinit var binding: ActivityFriendBinding - private val viewModel: FriendViewModel by viewModels() + private val viewModel: FriendViewModel by viewModels { + object : ViewModelProvider.Factory { + @Suppress("UNCHECKED_CAST") + override fun create(modelClass: Class): T { + return FriendViewModel(RemoteFriendDataSourceImpl(RetrofitService.friendApi)) as T + } + } + } private lateinit var friendAdapter: FriendAdapter @@ -27,7 +38,7 @@ class FriendActivity : AppCompatActivity() { private fun initRecyclerView() { friendAdapter = FriendAdapter(viewModel) - binding.rvMain.adapter = friendAdapter + binding.rvMain.adapter = friendAdapter } private fun observeViewModel() { From 4c6a70ace92ac002bbc3fca5a560598247a7bea4 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 14:53:20 +0900 Subject: [PATCH 11/35] =?UTF-8?q?url=20=EC=97=90=EB=9F=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit retrofit baseUrl 이 / 로 끝나야 함 --- .../java/com/studyfork/sfoide/data/remote/RetrofitService.kt | 2 +- .../main/java/com/studyfork/sfoide/data/remote/api/FriendApi.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/studyfork/sfoide/data/remote/RetrofitService.kt b/app/src/main/java/com/studyfork/sfoide/data/remote/RetrofitService.kt index 34c785e..3ba319b 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/remote/RetrofitService.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/remote/RetrofitService.kt @@ -10,7 +10,7 @@ import retrofit2.converter.gson.GsonConverterFactory object RetrofitService { private val retrofit = Retrofit.Builder() - .baseUrl("https://randomuser.me/api") + .baseUrl("https://randomuser.me/") .client(createOkHttpClient()) .addConverterFactory(GsonConverterFactory.create()) .build() diff --git a/app/src/main/java/com/studyfork/sfoide/data/remote/api/FriendApi.kt b/app/src/main/java/com/studyfork/sfoide/data/remote/api/FriendApi.kt index 4380cdd..5395807 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/remote/api/FriendApi.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/remote/api/FriendApi.kt @@ -7,7 +7,7 @@ import retrofit2.http.Query interface FriendApi { - @GET("/") + @GET("api/") fun getFriends( @Query("page") page: Int, @Query("results") results: Int From 750a104315e2f2846c7339ab0f39326414876293 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 14:59:16 +0900 Subject: [PATCH 12/35] =?UTF-8?q?MyGlideModule=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/studyfork/sfoide/ui/utils/MyGlideModule.kt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/utils/MyGlideModule.kt diff --git a/app/src/main/java/com/studyfork/sfoide/ui/utils/MyGlideModule.kt b/app/src/main/java/com/studyfork/sfoide/ui/utils/MyGlideModule.kt new file mode 100644 index 0000000..7701792 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/utils/MyGlideModule.kt @@ -0,0 +1,8 @@ +package com.studyfork.sfoide.ui.utils + +import com.bumptech.glide.annotation.GlideModule +import com.bumptech.glide.module.AppGlideModule + + +@GlideModule +class MyGlideModule : AppGlideModule() {} \ No newline at end of file From 7cd87a5e5e5a5edf82c8769bb09531cdd428cf4d Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 14:59:23 +0900 Subject: [PATCH 13/35] =?UTF-8?q?ImageViewExt=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/studyfork/sfoide/ui/ext/ImageViewExt.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/ext/ImageViewExt.kt diff --git a/app/src/main/java/com/studyfork/sfoide/ui/ext/ImageViewExt.kt b/app/src/main/java/com/studyfork/sfoide/ui/ext/ImageViewExt.kt new file mode 100644 index 0000000..63ce6f8 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/ext/ImageViewExt.kt @@ -0,0 +1,15 @@ +package com.studyfork.sfoide.ui.ext + +import android.widget.ImageView +import androidx.databinding.BindingAdapter +import com.bumptech.glide.Glide + +@BindingAdapter("app:loadUrl") +fun ImageView.loadUrl(url: String) { + Glide.with(this) + .load(url) + .fitCenter() + .centerCrop() + .circleCrop() + .into(this) +} \ No newline at end of file From fcfdd38225b420952ebca7ab3e7c79ab40fa78ed Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 15:05:16 +0900 Subject: [PATCH 14/35] =?UTF-8?q?FriendItem=20=EC=97=90=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EB=B0=94=EC=9D=B8=EB=94=A9=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../studyfork/sfoide/ui/widget/FriendInfoView.kt | 13 +++++++++++++ app/src/main/res/layout/item_friend.xml | 7 +++++-- app/src/main/res/layout/view_friend_info.xml | 11 +++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt b/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt index c655704..81b6802 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt @@ -6,6 +6,7 @@ import android.view.LayoutInflater import android.widget.FrameLayout import androidx.databinding.DataBindingUtil import com.studyfork.sfoide.R +import com.studyfork.sfoide.data.model.Friend import com.studyfork.sfoide.databinding.ViewFriendInfoBinding class FriendInfoView @JvmOverloads constructor( @@ -23,6 +24,18 @@ class FriendInfoView @JvmOverloads constructor( initBinding() } + var friend: Friend? = null + set(value) { + field = value + value?.let { + fetchFriend(value) + } + } + + private fun fetchFriend(value: Friend) { + binding.friend = value + } + private fun initBinding() { binding = DataBindingUtil.inflate( LayoutInflater.from(context), diff --git a/app/src/main/res/layout/item_friend.xml b/app/src/main/res/layout/item_friend.xml index 7d17321..f38160e 100644 --- a/app/src/main/res/layout/item_friend.xml +++ b/app/src/main/res/layout/item_friend.xml @@ -4,6 +4,7 @@ xmlns:tools="http://schemas.android.com/tools"> + @@ -19,19 +20,21 @@ + + + + + Date: Sun, 12 Jul 2020 15:18:08 +0900 Subject: [PATCH 15/35] =?UTF-8?q?Event=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/studyfork/sfoide/ui/utils/Event.kt | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/utils/Event.kt diff --git a/app/src/main/java/com/studyfork/sfoide/ui/utils/Event.kt b/app/src/main/java/com/studyfork/sfoide/ui/utils/Event.kt new file mode 100644 index 0000000..40c3642 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/utils/Event.kt @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.studyfork.sfoide.ui.utils + +import androidx.lifecycle.Observer + +/** + * Used as a wrapper for data that is exposed via a LiveData that represents an event. + */ +open class Event(private val content: T) { + + @Suppress("MemberVisibilityCanBePrivate") + 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 +} + +/** + * An [Observer] for [Event]s, simplifying the pattern of checking if the [Event]'s content has + * already been handled. + * + * [onEventUnhandledContent] is *only* called if the [Event]'s contents has not been handled. + */ +class EventObserver(private val onEventUnhandledContent: (T) -> Unit) : Observer> { + override fun onChanged(event: Event?) { + event?.getContentIfNotHandled()?.let { + onEventUnhandledContent(it) + } + } +} \ No newline at end of file From 5ef29f9ae40adb63ab0ac3514012a0fb9cd55ae3 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 15:22:12 +0900 Subject: [PATCH 16/35] =?UTF-8?q?Friend=20=EB=AA=A8=EB=8D=B8=20Parcelable?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/studyfork/sfoide/data/model/Friend.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt b/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt index 3789a70..88a9ecb 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt @@ -1,5 +1,9 @@ package com.studyfork.sfoide.data.model +import android.os.Parcelable +import kotlinx.android.parcel.Parcelize + +@Parcelize data class Friend( val id: String, val thumbnail: String, @@ -11,9 +15,10 @@ data class Friend( val telephone: String, val mobilePhone: String, val coordinates: Coordinates -) +) : Parcelable +@Parcelize class Coordinates( val latitude: String, val longitude: String -) \ No newline at end of file +) : Parcelable \ No newline at end of file From 4189633c98b4f3ae1fb33ec921d0a1ec4e3154dd Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 15:22:30 +0900 Subject: [PATCH 17/35] =?UTF-8?q?FriendDetailActivity=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 2 + .../ui/friend/detail/FriendDetailActivity.kt | 34 +++++++++++++++ .../res/layout/activity_friend_detail.xml | 41 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt create mode 100644 app/src/main/res/layout/activity_friend_detail.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ab43f7d..c9d7916 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,6 +19,8 @@ + + \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt new file mode 100644 index 0000000..c50c724 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt @@ -0,0 +1,34 @@ +package com.studyfork.sfoide.ui.friend.detail + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.databinding.DataBindingUtil +import com.studyfork.sfoide.R +import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.databinding.ActivityFriendDetailBinding + +class FriendDetailActivity : AppCompatActivity() { + + private lateinit var binding: ActivityFriendDetailBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = DataBindingUtil.setContentView(this, R.layout.activity_friend_detail) + binding.lifecycleOwner = this + + val friend = intent.getParcelableExtra(EXTRA_FRIEND) + binding.friend = friend + } + + companion object { + const val EXTRA_FRIEND = "EXTRA_FRIEND" + + fun createIntent(context: Context, friend: Friend): Intent { + return Intent(context, FriendDetailActivity::class.java).apply { + putExtra(EXTRA_FRIEND, friend) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_friend_detail.xml b/app/src/main/res/layout/activity_friend_detail.xml new file mode 100644 index 0000000..3259358 --- /dev/null +++ b/app/src/main/res/layout/activity_friend_detail.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file From 11d23b79234bed2b676345357706bfe3f3ed544b Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 15:22:42 +0900 Subject: [PATCH 18/35] =?UTF-8?q?FriendDetailActivity=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=20=ED=95=A8=EC=88=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sfoide/ui/friend/FriendActivity.kt | 20 ++++++++++++++++--- .../sfoide/ui/friend/FriendViewModel.kt | 6 +++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt index cdcb380..04004ea 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt @@ -9,8 +9,11 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.studyfork.sfoide.R import com.studyfork.sfoide.data.datasource.RemoteFriendDataSourceImpl +import com.studyfork.sfoide.data.model.Friend import com.studyfork.sfoide.data.remote.RetrofitService import com.studyfork.sfoide.databinding.ActivityFriendBinding +import com.studyfork.sfoide.ui.friend.detail.FriendDetailActivity +import com.studyfork.sfoide.ui.utils.EventObserver class FriendActivity : AppCompatActivity() { @@ -42,8 +45,19 @@ class FriendActivity : AppCompatActivity() { } private fun observeViewModel() { - viewModel.friendList.observe(this, Observer { friends -> - friendAdapter.submitList(friends) - }) + with(viewModel) { + friendList.observe(this@FriendActivity, Observer { friends -> + friendAdapter.submitList(friends) + }) + + navigateDetailEvent.observe( + this@FriendActivity, + EventObserver(this@FriendActivity::navigateFriendDetailActivity) + ) + } + } + + private fun navigateFriendDetailActivity(friend: Friend) { + startActivity(FriendDetailActivity.createIntent(this, friend)) } } \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt index 8f8c58f..18b11d4 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import com.studyfork.sfoide.data.model.Friend import com.studyfork.sfoide.data.remote.datasource.RemoteFriendDataSource +import com.studyfork.sfoide.ui.utils.Event class FriendViewModel( private val remoteFriendDataSource: RemoteFriendDataSource @@ -16,6 +17,9 @@ class FriendViewModel( private val _loading = MutableLiveData(false) val loading: LiveData = _loading + private val _navigateDetailEvent = MutableLiveData>() + val navigateDetailEvent: LiveData> = _navigateDetailEvent + init { fetchFriends() } @@ -38,6 +42,6 @@ class FriendViewModel( } fun navigateFriendDetail(friend: Friend) { - // todo + _navigateDetailEvent.value = Event(friend) } } \ No newline at end of file From 4af0f8e0363f0f06df9b01325e59abda80393888 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 15:56:00 +0900 Subject: [PATCH 19/35] =?UTF-8?q?=EA=B5=AC=EA=B8=80=EB=A7=B5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 6 ++++++ app/src/main/AndroidManifest.xml | 5 +++++ app/src/main/res/layout/activity_friend_detail.xml | 13 +++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1072dcb..c130b6e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,6 +14,8 @@ android { versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "") } buildTypes { @@ -70,4 +72,8 @@ dependencies { // image implementation 'com.github.bumptech.glide:glide:4.11.0' kapt 'com.github.bumptech.glide:compiler:4.11.0' + + // google map + implementation 'com.google.android.gms:play-services-maps:17.0.0' + implementation "com.google.android.gms:play-services-location:17.0.0" } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c9d7916..050bc06 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,11 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> + + + diff --git a/app/src/main/res/layout/activity_friend_detail.xml b/app/src/main/res/layout/activity_friend_detail.xml index 3259358..923a1c2 100644 --- a/app/src/main/res/layout/activity_friend_detail.xml +++ b/app/src/main/res/layout/activity_friend_detail.xml @@ -28,14 +28,23 @@ + + \ No newline at end of file From 4574b6ea2ff4c551de16b44d49dd1592634d3641 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 15:56:21 +0900 Subject: [PATCH 20/35] =?UTF-8?q?Coordinates=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/studyfork/sfoide/data/mapper/FriendMapper.kt | 4 ++-- app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt index b5ee56a..b7d93d0 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt @@ -16,8 +16,8 @@ fun FriendsResponse.Result.toEntity(): Friend { telephone = this.phone ?: "", mobilePhone = this.cell ?: "", coordinates = Coordinates( - latitude = this.location?.coordinates?.latitude ?: "", - longitude = this.location?.coordinates?.longitude ?: "" + latitude = this.location?.coordinates?.latitude?.toDouble() ?: 0.0, + longitude = this.location?.coordinates?.longitude?.toDouble() ?: 0.0 ) ) } \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt b/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt index 88a9ecb..594b19f 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt @@ -19,6 +19,6 @@ data class Friend( @Parcelize class Coordinates( - val latitude: String, - val longitude: String + val latitude: Double, + val longitude: Double ) : Parcelable \ No newline at end of file From afb04f4c379d1e66ce03c610ca59cbeb66217102 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 15:56:54 +0900 Subject: [PATCH 21/35] =?UTF-8?q?FriendDetailActivity=20=EC=97=90=20?= =?UTF-8?q?=EA=B5=AC=EA=B8=80=EB=A7=B5=20api=20=EC=97=B0=EB=8F=99=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=A2=8C=ED=91=9C=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/friend/detail/FriendDetailActivity.kt | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt index c50c724..5c849bf 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt @@ -5,26 +5,54 @@ import android.content.Intent import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.databinding.DataBindingUtil +import com.google.android.gms.maps.CameraUpdateFactory +import com.google.android.gms.maps.GoogleMap +import com.google.android.gms.maps.OnMapReadyCallback +import com.google.android.gms.maps.SupportMapFragment +import com.google.android.gms.maps.model.LatLng +import com.google.android.gms.maps.model.MarkerOptions import com.studyfork.sfoide.R import com.studyfork.sfoide.data.model.Friend import com.studyfork.sfoide.databinding.ActivityFriendDetailBinding -class FriendDetailActivity : AppCompatActivity() { +class FriendDetailActivity : AppCompatActivity(), OnMapReadyCallback { private lateinit var binding: ActivityFriendDetailBinding + private var friend: Friend? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_friend_detail) binding.lifecycleOwner = this - val friend = intent.getParcelableExtra(EXTRA_FRIEND) - binding.friend = friend + initMap() + + friend = intent.getParcelableExtra(EXTRA_FRIEND) + binding.friend = this.friend + } + + private fun initMap() { + val mapFragment = + (supportFragmentManager.findFragmentById(R.id.map_friend_detail) as? SupportMapFragment) + mapFragment?.getMapAsync(this) + } + + override fun onMapReady(map: GoogleMap?) { + friend?.coordinates?.let { + val coordinates = LatLng(it.latitude, it.longitude) + map?.addMarker( + MarkerOptions() + .position(coordinates) + ) + + map?.moveCamera(CameraUpdateFactory.newLatLng(coordinates)) + } } companion object { - const val EXTRA_FRIEND = "EXTRA_FRIEND" + const val EXTRA_FRIEND = "EXTRA_FRIEND" fun createIntent(context: Context, friend: Friend): Intent { return Intent(context, FriendDetailActivity::class.java).apply { putExtra(EXTRA_FRIEND, friend) From d9c04dbfd1e811b8cdb6a8ed8328f63cdaa4dbca Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 16:07:14 +0900 Subject: [PATCH 22/35] =?UTF-8?q?EndlessRecyclerViewScrollListener=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EndlessRecyclerViewScrollListener.kt | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/utils/EndlessRecyclerViewScrollListener.kt diff --git a/app/src/main/java/com/studyfork/sfoide/ui/utils/EndlessRecyclerViewScrollListener.kt b/app/src/main/java/com/studyfork/sfoide/ui/utils/EndlessRecyclerViewScrollListener.kt new file mode 100644 index 0000000..70a6fd2 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/utils/EndlessRecyclerViewScrollListener.kt @@ -0,0 +1,115 @@ +package com.studyfork.sfoide.ui.utils + +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.StaggeredGridLayoutManager + +/** + * 원본 코드 주소 + * https://gist.github.com/nesquena/d09dc68ff07e845cc622 + * https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView + */ +abstract class EndlessRecyclerViewScrollListener(private val layoutManager: RecyclerView.LayoutManager) : + RecyclerView.OnScrollListener() { + // The minimum amount of items to have below your current scroll position + // before loading more. + private var visibleThreshold = 5 + + // The current offset index of data you have loaded + private var currentPage = 0 + + // The total number of items in the dataset after the last load + private var previousTotalItemCount = 0 + + // True if we are still waiting for the last set of data to load. + private var loading = true + + // Sets the starting page index + private val startingPageIndex = 0 + + + init { + visibleThreshold = when (layoutManager) { + is GridLayoutManager -> visibleThreshold * layoutManager.spanCount + is StaggeredGridLayoutManager -> visibleThreshold * layoutManager.spanCount + else -> visibleThreshold + } + + } + + private fun getLastVisibleItem(lastVisibleItemPositions: IntArray): Int { + var maxSize = 0 + for (i in lastVisibleItemPositions.indices) { + if (i == 0) { + maxSize = lastVisibleItemPositions[i] + } else if (lastVisibleItemPositions[i] > maxSize) { + maxSize = lastVisibleItemPositions[i] + } + } + return maxSize + } + + // This happens many times a second during a scroll, so be wary of the code you place here. + // We are given a few useful parameters to help us work out if we need to load some more data, + // but first we check if we are waiting for the previous load to finish. + override fun onScrolled(view: RecyclerView, dx: Int, dy: Int) { + val totalItemCount = layoutManager.itemCount + + val lastVisibleItemPosition = when (layoutManager) { + is StaggeredGridLayoutManager -> // get maximum element within the list + getLastVisibleItem(layoutManager.findLastVisibleItemPositions(null)) + is GridLayoutManager -> layoutManager.findLastVisibleItemPosition() + is LinearLayoutManager -> layoutManager.findLastVisibleItemPosition() + else -> 0 + } + + // If the total item count is zero and the previous isn't, assume the + // list is invalidated and should be reset back to initial state + // If it’s still loading, we check to see if the dataset count has + // changed, if so we conclude it has finished loading and update the current page + // number and total item count. + + // If it isn’t currently loading, we check to see if we have breached + // the visibleThreshold and need to reload more data. + // If we do need to reload some more data, we execute onLoadMore to fetch the data. + // threshold should reflect how many total columns there are too + + // If the total item count is zero and the previous isn't, assume the + // list is invalidated and should be reset back to initial state + if (totalItemCount < previousTotalItemCount) { + this.currentPage = this.startingPageIndex + this.previousTotalItemCount = totalItemCount + if (totalItemCount == 0) { + this.loading = true + } + } + // If it’s still loading, we check to see if the dataset count has + // changed, if so we conclude it has finished loading and update the current page + // number and total item count. + if (loading && totalItemCount > previousTotalItemCount) { + loading = false + previousTotalItemCount = totalItemCount + } + + // If it isn’t currently loading, we check to see if we have breached + // the visibleThreshold and need to reload more data. + // If we do need to reload some more data, we execute onLoadMore to fetch the data. + // threshold should reflect how many total columns there are too + if (!loading && lastVisibleItemPosition + visibleThreshold > totalItemCount) { + currentPage++ + onLoadMore(currentPage, totalItemCount, view) + loading = true + } + } + + // Call this method whenever performing new searches + fun resetState() { + this.currentPage = this.startingPageIndex + this.previousTotalItemCount = 0 + this.loading = true + } + + // Defines the process for actually loading more data based on page + abstract fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView) +} \ No newline at end of file From 5c9f8436aeba6160a6eb6e81a925ca749fef2aad Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 16:08:16 +0900 Subject: [PATCH 23/35] =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=95=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sfoide/ui/friend/FriendActivity.kt | 7 +++++ .../sfoide/ui/friend/FriendViewModel.kt | 27 ++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt index 04004ea..20244f8 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt @@ -7,12 +7,14 @@ import androidx.databinding.DataBindingUtil import androidx.lifecycle.Observer import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.RecyclerView import com.studyfork.sfoide.R import com.studyfork.sfoide.data.datasource.RemoteFriendDataSourceImpl import com.studyfork.sfoide.data.model.Friend import com.studyfork.sfoide.data.remote.RetrofitService import com.studyfork.sfoide.databinding.ActivityFriendBinding import com.studyfork.sfoide.ui.friend.detail.FriendDetailActivity +import com.studyfork.sfoide.ui.utils.EndlessRecyclerViewScrollListener import com.studyfork.sfoide.ui.utils.EventObserver class FriendActivity : AppCompatActivity() { @@ -42,6 +44,11 @@ class FriendActivity : AppCompatActivity() { private fun initRecyclerView() { friendAdapter = FriendAdapter(viewModel) binding.rvMain.adapter = friendAdapter + binding.rvMain.addOnScrollListener(object : EndlessRecyclerViewScrollListener(binding.rvMain.layoutManager!!) { + override fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView) { + viewModel.loadMoreFriends() + } + }) } private fun observeViewModel() { diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt index 18b11d4..8425c14 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt @@ -20,28 +20,43 @@ class FriendViewModel( private val _navigateDetailEvent = MutableLiveData>() val navigateDetailEvent: LiveData> = _navigateDetailEvent + private var pageNumber: Int = 1 + init { - fetchFriends() + fetchFriends(pageNumber) } - private fun fetchFriends() { + private fun fetchFriends(pageNumber: Int, itemCount: Int = ITEM_COUNT) { remoteFriendDataSource.getFriends( - pageNumber = 1, - itemCount = 20, + pageNumber = pageNumber, + itemCount = itemCount, onSuccess = { friends -> - _friendList.value = friends + _loading.value = false + _friendList.value = (_friendList.value ?: emptyList()) + friends }, onError = { + _loading.value = false // todo } ) } + fun loadMoreFriends() { + fetchFriends(++pageNumber) + } + fun onRefresh() { - // todo + _friendList.value = emptyList() + _loading.value = true + pageNumber = 1 + fetchFriends(pageNumber) } fun navigateFriendDetail(friend: Friend) { _navigateDetailEvent.value = Event(friend) } + + companion object { + private const val ITEM_COUNT = 20 + } } \ No newline at end of file From 3f82961fe0a150e22d520a4b56d6ef9620ae8834 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 16:13:45 +0900 Subject: [PATCH 24/35] =?UTF-8?q?=EB=92=A4=EB=A1=9C=20=EA=B0=80=EA=B8=B0?= =?UTF-8?q?=20=EB=91=90=EB=B2=88=20=EB=88=8C=EB=9F=AC=EC=84=9C=20=EC=95=B1?= =?UTF-8?q?=20=EC=A2=85=EB=A3=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sfoide/ui/friend/FriendActivity.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt index 20244f8..c35fa99 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt @@ -1,6 +1,7 @@ package com.studyfork.sfoide.ui.friend import android.os.Bundle +import android.widget.Toast import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.databinding.DataBindingUtil @@ -21,6 +22,8 @@ class FriendActivity : AppCompatActivity() { private lateinit var binding: ActivityFriendBinding + private var lastBackPressed: Long = 0L + private val viewModel: FriendViewModel by viewModels { object : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") @@ -67,4 +70,19 @@ class FriendActivity : AppCompatActivity() { private fun navigateFriendDetailActivity(friend: Friend) { startActivity(FriendDetailActivity.createIntent(this, friend)) } + + override fun onBackPressed() { + val current = System.currentTimeMillis() + val term = current - lastBackPressed + if (term > TWO_SECONDS) { + Toast.makeText(this, "뒤로가기를 한번 더 눌러주세요", Toast.LENGTH_SHORT).show() + lastBackPressed = current + } else { + super.onBackPressed() + } + } + + companion object { + private const val TWO_SECONDS = 2000 + } } \ No newline at end of file From ae5c865b1a7a18173382037428545dac9e6843ba Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 16:38:13 +0900 Subject: [PATCH 25/35] =?UTF-8?q?FriendInfoView=20=EC=A0=84=ED=99=94?= =?UTF-8?q?=EB=B2=88=ED=98=B8,=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=EB=A6=AC=EC=8A=A4=EB=84=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sfoide/ui/widget/FriendInfoView.kt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt b/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt index 81b6802..d86828e 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt @@ -45,4 +45,34 @@ class FriendInfoView @JvmOverloads constructor( ) addView(binding.root) } + + fun setOnPhoneClickListener(onPhoneClickListener: OnPhoneClickListener) { + binding.tvFriendMobile.setOnClickListener { + friend?.mobilePhone?.let { + onPhoneClickListener.onPhoneClick(it) + } + } + + binding.tvFriendTelephone.setOnClickListener { + friend?.telephone?.let { + onPhoneClickListener.onPhoneClick(it) + } + } + } + + fun setOnEmailClickListener(onEmailClickListener: OnEmailClickListener) { + binding.tvFriendEmail.setOnClickListener { + friend?.email?.let { + onEmailClickListener.onEmailClick(it) + } + } + } + + interface OnPhoneClickListener { + fun onPhoneClick(phoneNumber: String) + } + + interface OnEmailClickListener { + fun onEmailClick(email: String) + } } \ No newline at end of file From c2368d924af54390ccc6572df86fd1a4d3813ec1 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 16:38:42 +0900 Subject: [PATCH 26/35] =?UTF-8?q?FriendDetailActivity=20=EC=97=90=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/friend/detail/FriendDetailActivity.kt | 32 +++++++++++++++++++ .../ui/friend/detail/FriendDetailViewModel.kt | 30 +++++++++++++++++ .../res/layout/activity_friend_detail.xml | 8 ++++- 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailViewModel.kt diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt index 5c849bf..ca8e4b3 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt @@ -2,7 +2,9 @@ package com.studyfork.sfoide.ui.friend.detail import android.content.Context import android.content.Intent +import android.net.Uri import android.os.Bundle +import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.databinding.DataBindingUtil import com.google.android.gms.maps.CameraUpdateFactory @@ -14,19 +16,24 @@ import com.google.android.gms.maps.model.MarkerOptions import com.studyfork.sfoide.R import com.studyfork.sfoide.data.model.Friend import com.studyfork.sfoide.databinding.ActivityFriendDetailBinding +import com.studyfork.sfoide.ui.utils.EventObserver class FriendDetailActivity : AppCompatActivity(), OnMapReadyCallback { private lateinit var binding: ActivityFriendDetailBinding + private val viewModel: FriendDetailViewModel by viewModels() + private var friend: Friend? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_friend_detail) binding.lifecycleOwner = this + binding.vm = viewModel initMap() + observeViewModel() friend = intent.getParcelableExtra(EXTRA_FRIEND) binding.friend = this.friend @@ -38,6 +45,31 @@ class FriendDetailActivity : AppCompatActivity(), OnMapReadyCallback { mapFragment?.getMapAsync(this) } + private fun observeViewModel() { + with(viewModel) { + navigatePhoneAppEvent.observe( + this@FriendDetailActivity, + EventObserver(this@FriendDetailActivity::openDialApp) + ) + + navigateEmailAppEvent.observe( + this@FriendDetailActivity, + EventObserver(this@FriendDetailActivity::openEmailApp) + ) + } + } + + private fun openDialApp(phone: String) { + startActivity(Intent(Intent.ACTION_DIAL, Uri.parse("tel:$phone"))) + } + + private fun openEmailApp(email: String) { + startActivity(Intent(Intent.ACTION_SENDTO).apply { + data = Uri.parse("mailto:") + putExtra(Intent.EXTRA_EMAIL, email) + }) + } + override fun onMapReady(map: GoogleMap?) { friend?.coordinates?.let { val coordinates = LatLng(it.latitude, it.longitude) diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailViewModel.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailViewModel.kt new file mode 100644 index 0000000..fad120e --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailViewModel.kt @@ -0,0 +1,30 @@ +package com.studyfork.sfoide.ui.friend.detail + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.studyfork.sfoide.ui.utils.Event +import timber.log.Timber + +class FriendDetailViewModel : ViewModel() { + + private val _navigatePhoneAppEvent = MutableLiveData>() + val navigatePhoneAppEvent: LiveData> = _navigatePhoneAppEvent + + private val _navigateEmailAppEvent = MutableLiveData>() + val navigateEmailAppEvent: LiveData> = _navigateEmailAppEvent + + fun navigateEmail(email: String) { + _navigateEmailAppEvent.value = Event(email) + } + + fun navigatePhone(phoneNumber: String) { + val formattedPhoneNumber = phoneNumber.filter { it in NUMBER_FILTER } + Timber.e(formattedPhoneNumber) + _navigatePhoneAppEvent.value = Event(formattedPhoneNumber) + } + + companion object { + private const val NUMBER_FILTER = "0123456789" + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_friend_detail.xml b/app/src/main/res/layout/activity_friend_detail.xml index 923a1c2..02b6468 100644 --- a/app/src/main/res/layout/activity_friend_detail.xml +++ b/app/src/main/res/layout/activity_friend_detail.xml @@ -8,6 +8,10 @@ + + + app:layout_constraintTop_toBottomOf="@id/iv_friend_detail_picture" + app:onEmailClickListener="@{(email) -> vm.navigateEmail(email)}" + app:onPhoneClickListener="@{(phoneNumber) -> vm.navigatePhone(phoneNumber)}" /> Date: Sun, 12 Jul 2020 16:40:38 +0900 Subject: [PATCH 27/35] =?UTF-8?q?=ED=95=B4=EC=83=81=EB=8F=84=EA=B0=80=20?= =?UTF-8?q?=EB=84=88=EB=AC=B4=20=EB=82=AE=EC=95=84=EC=84=9C=20large=20?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt index b7d93d0..a6b9544 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt @@ -7,7 +7,7 @@ import com.studyfork.sfoide.data.remote.response.FriendsResponse fun FriendsResponse.Result.toEntity(): Friend { return Friend( id = this.login?.uuid ?: "", - thumbnail = this.picture?.thumbnail ?: "", + thumbnail = this.picture?.large ?: "", name = this.name.toString(), age = this.dob?.age ?: 0, gender = this.gender ?: "", From f3b33b695f43b40277acc222b5f9779b081d93e3 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 17:10:01 +0900 Subject: [PATCH 28/35] =?UTF-8?q?FriendMapper=20=EC=97=90=EC=84=9C=20count?= =?UTF-8?q?ry=20=ED=95=84=EB=93=9C=EB=A5=BC=20nat=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=20=EB=A7=A4=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt index a6b9544..c73d63c 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt @@ -11,7 +11,7 @@ fun FriendsResponse.Result.toEntity(): Friend { name = this.name.toString(), age = this.dob?.age ?: 0, gender = this.gender ?: "", - country = this.location?.country ?: "'", + country = this.nat ?: "", email = this.email ?: "", telephone = this.phone ?: "", mobilePhone = this.cell ?: "", From 2232acff993dd7b7a8a9e9f52e6ac536b703624e Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 17:10:33 +0900 Subject: [PATCH 29/35] =?UTF-8?q?TextViewExt=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../studyfork/sfoide/ui/ext/TextViewExt.kt | 61 +++++++++++++++++++ app/src/main/res/values/strings.xml | 25 ++++++++ 2 files changed, 86 insertions(+) create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/ext/TextViewExt.kt diff --git a/app/src/main/java/com/studyfork/sfoide/ui/ext/TextViewExt.kt b/app/src/main/java/com/studyfork/sfoide/ui/ext/TextViewExt.kt new file mode 100644 index 0000000..e8ee707 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/ext/TextViewExt.kt @@ -0,0 +1,61 @@ +package com.studyfork.sfoide.ui.ext + +import android.widget.TextView +import androidx.databinding.BindingAdapter +import com.studyfork.sfoide.R +import com.studyfork.sfoide.data.model.Friend + +private const val MALE = "male" + +@BindingAdapter("app:nameAndAge") +fun TextView.setNameAndAge(friend: Friend) { + text = "${friend.name}(${friend.age})" +} + +@BindingAdapter("app:gender") +fun TextView.setGender(gender: String) { + text = if (gender == MALE) { + context.resources.getString(R.string.male) + } else { + context.resources.getString(R.string.female) + } +} + +@BindingAdapter("app:country") +fun TextView.setCountry(country: String) { + text = when (country) { + "AU" -> context.resources.getString(R.string.au) + "BR" -> context.resources.getString(R.string.br) + "CA" -> context.resources.getString(R.string.ca) + "CH" -> context.resources.getString(R.string.ch) + "DE" -> context.resources.getString(R.string.de) + "DK" -> context.resources.getString(R.string.dk) + "ES" -> context.resources.getString(R.string.es) + "FI" -> context.resources.getString(R.string.fi) + "FR" -> context.resources.getString(R.string.fr) + "GB" -> context.resources.getString(R.string.gb) + "IE" -> context.resources.getString(R.string.ie) + "IR" -> context.resources.getString(R.string.ir) + "NO" -> context.resources.getString(R.string.no) + "NL" -> context.resources.getString(R.string.nl) + "NZ" -> context.resources.getString(R.string.nz) + "TR" -> context.resources.getString(R.string.tr) + "US" -> context.resources.getString(R.string.us) + else -> "" + } +} + +@BindingAdapter("app:email") +fun TextView.setEmail(email: String) { + text = "${context.resources.getString(R.string.email)} $email" +} + +@BindingAdapter("app:mobile") +fun TextView.setMobile(mobile: String) { + text = "${context.resources.getString(R.string.mobile_phone)} $mobile" +} + +@BindingAdapter("app:telephone") +fun TextView.setTelephone(telephone: String) { + text = "${context.resources.getString(R.string.telephone)} $telephone" +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 50c6e1a..588b21f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,28 @@ Sfoide + + 🙋‍♂ + 🙋‍♀ + + ☎️ + 📱 + 📧 + + 🇦🇺 + 🇧🇷 + 🇨🇦 + 🇨🇭 + 🇩🇪 + 🇩🇰 + 🇪🇸 + 🇫🇮 + 🇫🇷 + 🇬🇧 + 🇮🇪 + 🇮🇷 + 🇳🇴 + 🇳🇱 + 🇳🇿 + 🇹🇷 + 🇺🇸 \ No newline at end of file From 6e6bb32e3b212bdc65a1043cf75d0c7e0f1e24ae Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 17:11:07 +0900 Subject: [PATCH 30/35] =?UTF-8?q?view=5Ffriend=5Finfo=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EB=B0=94=EC=9D=B8=EB=94=A9=20=EC=96=B4=EB=8C=91?= =?UTF-8?q?=ED=84=B0=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/view_friend_info.xml | 40 +++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/app/src/main/res/layout/view_friend_info.xml b/app/src/main/res/layout/view_friend_info.xml index d677259..b6d373c 100644 --- a/app/src/main/res/layout/view_friend_info.xml +++ b/app/src/main/res/layout/view_friend_info.xml @@ -16,50 +16,70 @@ android:paddingStart="10dp" android:paddingEnd="10dp"> - + app:layout_constraintVertical_chainStyle="spread_inside"> + + + + + + + From ad61793ea13c5ae32b49c58953eee173adb9fe97 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 17:20:34 +0900 Subject: [PATCH 31/35] =?UTF-8?q?=EB=A6=AC=ED=94=84=EB=A0=88=EC=8B=9C=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt | 1 + .../main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt index c35fa99..cda2938 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt @@ -39,6 +39,7 @@ class FriendActivity : AppCompatActivity() { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_friend) binding.lifecycleOwner = this + binding.vm = viewModel initRecyclerView() observeViewModel() diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt index 8425c14..74f7d57 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt @@ -36,7 +36,6 @@ class FriendViewModel( }, onError = { _loading.value = false - // todo } ) } From e04c26c6b37e43a602ecd1309dbc857d4e8e9969 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 17:26:13 +0900 Subject: [PATCH 32/35] =?UTF-8?q?Friend=20=EB=A5=BC=20ui=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sfoide/data/datasource/RemoteFriendDataSourceImpl.kt | 2 +- .../java/com/studyfork/sfoide/data/mapper/FriendMapper.kt | 4 ++-- .../sfoide/data/remote/datasource/RemoteFriendDataSource.kt | 2 +- app/src/main/java/com/studyfork/sfoide/ui/ext/TextViewExt.kt | 2 +- .../java/com/studyfork/sfoide/ui/friend/FriendActivity.kt | 2 +- .../main/java/com/studyfork/sfoide/ui/friend/FriendAdapter.kt | 2 +- .../java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt | 2 +- .../studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt | 2 +- .../java/com/studyfork/sfoide/{data => ui}/model/Friend.kt | 2 +- .../java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt | 2 +- app/src/main/res/layout/activity_friend_detail.xml | 2 +- app/src/main/res/layout/item_friend.xml | 2 +- app/src/main/res/layout/view_friend_info.xml | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) rename app/src/main/java/com/studyfork/sfoide/{data => ui}/model/Friend.kt (92%) diff --git a/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt b/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt index c9b9de9..0237b03 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt @@ -1,7 +1,7 @@ package com.studyfork.sfoide.data.datasource import com.studyfork.sfoide.data.mapper.toEntity -import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.ui.model.Friend import com.studyfork.sfoide.data.remote.api.FriendApi import com.studyfork.sfoide.data.remote.datasource.RemoteFriendDataSource import com.studyfork.sfoide.data.remote.response.FriendsResponse diff --git a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt index c73d63c..de02614 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt @@ -1,7 +1,7 @@ package com.studyfork.sfoide.data.mapper -import com.studyfork.sfoide.data.model.Coordinates -import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.ui.model.Coordinates +import com.studyfork.sfoide.ui.model.Friend import com.studyfork.sfoide.data.remote.response.FriendsResponse fun FriendsResponse.Result.toEntity(): Friend { diff --git a/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt b/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt index dc2356a..d138f54 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt @@ -1,6 +1,6 @@ package com.studyfork.sfoide.data.remote.datasource -import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.ui.model.Friend interface RemoteFriendDataSource { diff --git a/app/src/main/java/com/studyfork/sfoide/ui/ext/TextViewExt.kt b/app/src/main/java/com/studyfork/sfoide/ui/ext/TextViewExt.kt index e8ee707..ede4984 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/ext/TextViewExt.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/ext/TextViewExt.kt @@ -3,7 +3,7 @@ package com.studyfork.sfoide.ui.ext import android.widget.TextView import androidx.databinding.BindingAdapter import com.studyfork.sfoide.R -import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.ui.model.Friend private const val MALE = "male" diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt index cda2938..c28ed89 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendActivity.kt @@ -11,7 +11,7 @@ import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.RecyclerView import com.studyfork.sfoide.R import com.studyfork.sfoide.data.datasource.RemoteFriendDataSourceImpl -import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.ui.model.Friend import com.studyfork.sfoide.data.remote.RetrofitService import com.studyfork.sfoide.databinding.ActivityFriendBinding import com.studyfork.sfoide.ui.friend.detail.FriendDetailActivity diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendAdapter.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendAdapter.kt index 68ab008..735dd05 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendAdapter.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendAdapter.kt @@ -7,7 +7,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.studyfork.sfoide.R -import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.ui.model.Friend import com.studyfork.sfoide.databinding.ItemFriendBinding class FriendAdapter( diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt index 74f7d57..1679dce 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt @@ -3,7 +3,7 @@ package com.studyfork.sfoide.ui.friend import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.ui.model.Friend import com.studyfork.sfoide.data.remote.datasource.RemoteFriendDataSource import com.studyfork.sfoide.ui.utils.Event diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt index ca8e4b3..74579d1 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/detail/FriendDetailActivity.kt @@ -14,7 +14,7 @@ import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.MarkerOptions import com.studyfork.sfoide.R -import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.ui.model.Friend import com.studyfork.sfoide.databinding.ActivityFriendDetailBinding import com.studyfork.sfoide.ui.utils.EventObserver diff --git a/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt b/app/src/main/java/com/studyfork/sfoide/ui/model/Friend.kt similarity index 92% rename from app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt rename to app/src/main/java/com/studyfork/sfoide/ui/model/Friend.kt index 594b19f..aeda6a1 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/model/Friend.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/model/Friend.kt @@ -1,4 +1,4 @@ -package com.studyfork.sfoide.data.model +package com.studyfork.sfoide.ui.model import android.os.Parcelable import kotlinx.android.parcel.Parcelize diff --git a/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt b/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt index d86828e..8df44ed 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/widget/FriendInfoView.kt @@ -6,7 +6,7 @@ import android.view.LayoutInflater import android.widget.FrameLayout import androidx.databinding.DataBindingUtil import com.studyfork.sfoide.R -import com.studyfork.sfoide.data.model.Friend +import com.studyfork.sfoide.ui.model.Friend import com.studyfork.sfoide.databinding.ViewFriendInfoBinding class FriendInfoView @JvmOverloads constructor( diff --git a/app/src/main/res/layout/activity_friend_detail.xml b/app/src/main/res/layout/activity_friend_detail.xml index 02b6468..f2ab7e9 100644 --- a/app/src/main/res/layout/activity_friend_detail.xml +++ b/app/src/main/res/layout/activity_friend_detail.xml @@ -7,7 +7,7 @@ + type="com.studyfork.sfoide.ui.model.Friend" /> + type="com.studyfork.sfoide.ui.model.Friend" /> + type="com.studyfork.sfoide.ui.model.Friend" /> Date: Sun, 12 Jul 2020 17:28:40 +0900 Subject: [PATCH 33/35] =?UTF-8?q?data=20=EB=A0=88=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EC=97=90=20FriendData=20=EB=AA=A8=EB=8D=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datasource/RemoteFriendDataSourceImpl.kt | 4 ++-- .../sfoide/data/mapper/FriendMapper.kt | 10 ++++---- .../studyfork/sfoide/data/model/FriendData.kt | 19 +++++++++++++++ .../datasource/RemoteFriendDataSource.kt | 4 ++-- .../sfoide/ui/friend/FriendViewModel.kt | 6 +++-- .../sfoide/ui/mapper/FriendMapper.kt | 23 +++++++++++++++++++ 6 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/com/studyfork/sfoide/data/model/FriendData.kt create mode 100644 app/src/main/java/com/studyfork/sfoide/ui/mapper/FriendMapper.kt diff --git a/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt b/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt index 0237b03..c648baf 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/datasource/RemoteFriendDataSourceImpl.kt @@ -1,7 +1,7 @@ package com.studyfork.sfoide.data.datasource import com.studyfork.sfoide.data.mapper.toEntity -import com.studyfork.sfoide.ui.model.Friend +import com.studyfork.sfoide.data.model.FriendData import com.studyfork.sfoide.data.remote.api.FriendApi import com.studyfork.sfoide.data.remote.datasource.RemoteFriendDataSource import com.studyfork.sfoide.data.remote.response.FriendsResponse @@ -16,7 +16,7 @@ class RemoteFriendDataSourceImpl( override fun getFriends( pageNumber: Int, itemCount: Int, - onSuccess: (friends: List) -> Unit, + onSuccess: (friends: List) -> Unit, onError: (error: Throwable) -> Unit ) { friendApi.getFriends( diff --git a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt index de02614..517644d 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/mapper/FriendMapper.kt @@ -1,11 +1,11 @@ package com.studyfork.sfoide.data.mapper -import com.studyfork.sfoide.ui.model.Coordinates -import com.studyfork.sfoide.ui.model.Friend +import com.studyfork.sfoide.data.model.CoordinatesData +import com.studyfork.sfoide.data.model.FriendData import com.studyfork.sfoide.data.remote.response.FriendsResponse -fun FriendsResponse.Result.toEntity(): Friend { - return Friend( +fun FriendsResponse.Result.toEntity(): FriendData { + return FriendData( id = this.login?.uuid ?: "", thumbnail = this.picture?.large ?: "", name = this.name.toString(), @@ -15,7 +15,7 @@ fun FriendsResponse.Result.toEntity(): Friend { email = this.email ?: "", telephone = this.phone ?: "", mobilePhone = this.cell ?: "", - coordinates = Coordinates( + coordinatesData = CoordinatesData( latitude = this.location?.coordinates?.latitude?.toDouble() ?: 0.0, longitude = this.location?.coordinates?.longitude?.toDouble() ?: 0.0 ) diff --git a/app/src/main/java/com/studyfork/sfoide/data/model/FriendData.kt b/app/src/main/java/com/studyfork/sfoide/data/model/FriendData.kt new file mode 100644 index 0000000..e4cadc5 --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/data/model/FriendData.kt @@ -0,0 +1,19 @@ +package com.studyfork.sfoide.data.model + +data class FriendData( + val id: String, + val thumbnail: String, + val name: String, + val age: Int, + val gender: String, + val country: String, + val email: String, + val telephone: String, + val mobilePhone: String, + val coordinatesData: CoordinatesData +) + +class CoordinatesData( + val latitude: Double, + val longitude: Double +) \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt b/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt index d138f54..fabe7ca 100644 --- a/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt +++ b/app/src/main/java/com/studyfork/sfoide/data/remote/datasource/RemoteFriendDataSource.kt @@ -1,13 +1,13 @@ package com.studyfork.sfoide.data.remote.datasource -import com.studyfork.sfoide.ui.model.Friend +import com.studyfork.sfoide.data.model.FriendData interface RemoteFriendDataSource { fun getFriends( pageNumber: Int, itemCount: Int, - onSuccess: (friends: List) -> Unit, + onSuccess: (friends: List) -> Unit, onError: (error: Throwable) -> Unit ) } \ No newline at end of file diff --git a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt index 1679dce..75ccde2 100644 --- a/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt +++ b/app/src/main/java/com/studyfork/sfoide/ui/friend/FriendViewModel.kt @@ -3,8 +3,9 @@ package com.studyfork.sfoide.ui.friend import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import com.studyfork.sfoide.ui.model.Friend import com.studyfork.sfoide.data.remote.datasource.RemoteFriendDataSource +import com.studyfork.sfoide.ui.mapper.toPresentation +import com.studyfork.sfoide.ui.model.Friend import com.studyfork.sfoide.ui.utils.Event class FriendViewModel( @@ -32,7 +33,8 @@ class FriendViewModel( itemCount = itemCount, onSuccess = { friends -> _loading.value = false - _friendList.value = (_friendList.value ?: emptyList()) + friends + _friendList.value = + (_friendList.value ?: emptyList()) + friends.map { it.toPresentation() } }, onError = { _loading.value = false diff --git a/app/src/main/java/com/studyfork/sfoide/ui/mapper/FriendMapper.kt b/app/src/main/java/com/studyfork/sfoide/ui/mapper/FriendMapper.kt new file mode 100644 index 0000000..dc548fa --- /dev/null +++ b/app/src/main/java/com/studyfork/sfoide/ui/mapper/FriendMapper.kt @@ -0,0 +1,23 @@ +package com.studyfork.sfoide.ui.mapper + +import com.studyfork.sfoide.data.model.FriendData +import com.studyfork.sfoide.ui.model.Coordinates +import com.studyfork.sfoide.ui.model.Friend + +fun FriendData.toPresentation(): Friend { + return Friend( + id = this.id, + thumbnail = this.thumbnail, + name = this.name, + age = this.age, + gender = this.gender, + country = this.country, + email = this.email, + telephone = this.telephone, + mobilePhone = this.mobilePhone, + coordinates = Coordinates( + latitude = this.coordinatesData.latitude, + longitude = this.coordinatesData.longitude + ) + ) +} \ No newline at end of file From 73d3d13551cb359e17ff6d72af3c8727020171e7 Mon Sep 17 00:00:00 2001 From: improve777 Date: Sun, 12 Jul 2020 17:37:59 +0900 Subject: [PATCH 34/35] =?UTF-8?q?item=5Ffriend=20=EB=A7=88=EC=A7=84,=20?= =?UTF-8?q?=EB=A6=AC=ED=94=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/item_friend.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/item_friend.xml b/app/src/main/res/layout/item_friend.xml index a9acf1e..91f369f 100644 --- a/app/src/main/res/layout/item_friend.xml +++ b/app/src/main/res/layout/item_friend.xml @@ -12,7 +12,11 @@ + android:layout_height="wrap_content" + android:layout_margin="8dp" + android:clickable="true" + android:focusable="true" + android:foreground="?attr/selectableItemBackground"> Date: Sun, 12 Jul 2020 17:38:29 +0900 Subject: [PATCH 35/35] =?UTF-8?q?activity=5Ffriend=5Fdetail=20=EA=B5=AC?= =?UTF-8?q?=EA=B8=80=EB=A7=B5=20marginTop=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/activity_friend_detail.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/activity_friend_detail.xml b/app/src/main/res/layout/activity_friend_detail.xml index f2ab7e9..0f517ad 100644 --- a/app/src/main/res/layout/activity_friend_detail.xml +++ b/app/src/main/res/layout/activity_friend_detail.xml @@ -47,6 +47,7 @@ android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="0dp" android:layout_height="200dp" + android:layout_marginTop="20dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/fiv_friend_detail" />