Skip to content

Commit 33086f8

Browse files
author
kanchan.pal
committed
remove data binding with view binding, support java 17
1 parent c644419 commit 33086f8

17 files changed

+285
-276
lines changed

app/build.gradle

+22-16
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
plugins {
2-
id ("com.android.application")
2+
id("com.android.application")
33
id("jacoco")
44
id("kotlin-android")
55
id("kotlin-kapt")
66
id("kotlin-allopen")
77
id("androidx.navigation.safeargs.kotlin")
88
id("com.google.dagger.hilt.android")
9-
109
}
1110

1211
allOpen {
@@ -15,21 +14,24 @@ allOpen {
1514
}
1615

1716
android {
18-
compileSdkVersion 33
17+
namespace "com.kanchanpal.newsfeed"
18+
compileSdk 34
1919

2020
buildFeatures {
2121

22-
dataBinding true
2322
viewBinding = true
23+
buildConfig = true
24+
}
2425

25-
// for view binding:
26-
// viewBinding true
26+
compileOptions {
27+
sourceCompatibility JavaVersion.VERSION_17
28+
targetCompatibility JavaVersion.VERSION_17
2729
}
2830

2931
defaultConfig {
3032
applicationId "com.kanchanpal.newsfeed"
3133
minSdkVersion 21
32-
targetSdkVersion 33
34+
targetSdkVersion 34
3335
versionCode 1
3436
versionName "1.0"
3537
testInstrumentationRunner "com.kanchanpal.newsfeed.util.AppTestRunner"
@@ -57,6 +59,10 @@ android {
5759
}
5860
}
5961

62+
kotlin {
63+
jvmToolchain (17)
64+
}
65+
6066
jacoco {
6167
toolVersion = "$rootProject.jacocoVersion"
6268
}
@@ -68,8 +74,8 @@ dependencies {
6874
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
6975
testImplementation 'junit:junit:4.12'
7076

71-
implementation("com.google.dagger:hilt-android:2.44")
72-
kapt("com.google.dagger:hilt-android-compiler:2.44")
77+
implementation("com.google.dagger:hilt-android:2.47")
78+
kapt("com.google.dagger:hilt-android-compiler:2.47")
7379

7480
kapt "androidx.room:room-compiler:$rootProject.roomVersion"
7581
kapt "com.github.bumptech.glide:compiler:$rootProject.glideVersion"
@@ -132,8 +138,8 @@ dependencies {
132138
androidTestImplementation "org.mockito:mockito-core:$rootProject.mockitoVersion"
133139
androidTestImplementation "org.mockito:mockito-android:$rootProject.mockitoAndroidVersion"
134140

135-
androidTestImplementation ('androidx.test.espresso:espresso-core:' + rootProject.espressoVersion) {
136-
exclude group:'com.androidx.support'
141+
androidTestImplementation('androidx.test.espresso:espresso-core:' + rootProject.espressoVersion) {
142+
exclude group: 'com.androidx.support'
137143

138144
}
139145
}
@@ -145,8 +151,8 @@ task fullCoverageReport(type: JacocoReport) {
145151
dependsOn 'createDebugCoverageReport'
146152
dependsOn 'testDebugUnitTest'
147153
reports {
148-
xml.enabled = true
149-
html.enabled = true
154+
xml.getRequired().set(true)
155+
html.getRequired().set(true)
150156
}
151157

152158
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*',
@@ -157,19 +163,19 @@ task fullCoverageReport(type: JacocoReport) {
157163
'**/*_*Factory.class',
158164
'**/*ComponentImpl.class',
159165
'**/*SubComponentBuilder.class']
160-
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/debug", excludes: fileFilter)
166+
def debugTree = fileTree(dir: "${layout.buildDir}/intermediates/classes/debug", excludes: fileFilter)
161167
def mainSrc = "${project.projectDir}/src/main/java"
162168

163169
sourceDirectories.from = files([mainSrc])
164170
classDirectories.from = files([debugTree])
165-
executionData.from = fileTree(dir: "$buildDir", includes: [
171+
executionData.from = fileTree(dir: "${layout.buildDirectory}", includes: [
166172
"jacoco/testDebugUnitTest.exec",
167173
"outputs/code-coverage/connected/*coverage.ec"
168174
])
169175
}
170176

171177
// we need all open to run tests which a we enable only for debug builds.
172-
project.tasks.whenTaskAdded {
178+
project.tasks.configureEach {
173179
if (it.name == "testReleaseUnitTest") {
174180
it.enabled = false
175181
}

app/src/main/java/com/kanchanpal/newsfeed/MainActivity.kt

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.kanchanpal.newsfeed
22

33
import android.os.Bundle
44
import androidx.appcompat.app.AppCompatActivity
5-
import androidx.databinding.DataBindingUtil
65
import androidx.navigation.NavController
76
import androidx.navigation.findNavController
87
import com.kanchanpal.newsfeed.databinding.ActivityMainBinding
@@ -11,12 +10,12 @@ import dagger.hilt.android.AndroidEntryPoint
1110
@AndroidEntryPoint
1211
class MainActivity : AppCompatActivity() {
1312
private lateinit var navController: NavController
13+
private lateinit var binding: ActivityMainBinding
1414

1515
override fun onCreate(savedInstanceState: Bundle?) {
1616
super.onCreate(savedInstanceState)
17-
18-
val binding : ActivityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main)
19-
17+
binding = ActivityMainBinding.inflate(layoutInflater)
18+
setContentView(binding.root)
2019
navController = findNavController(R.id.nav_fragment)
2120
}
2221
}

app/src/main/java/com/kanchanpal/newsfeed/api/ResponseModel.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ package com.kanchanpal.newsfeed.api
22

33
import androidx.room.Embedded
44
import androidx.room.Entity
5+
import androidx.room.Ignore
56
import androidx.room.PrimaryKey
67
import com.google.gson.annotations.Expose
78
import com.google.gson.annotations.SerializedName
89
import java.io.Serializable
10+
import java.util.UUID
911

1012

13+
@Entity
1114
data class NewsListResponse(
1215
@Expose
1316
@SerializedName("source")
@@ -21,11 +24,10 @@ data class NewsListResponse(
2124

2225
@Entity
2326
data class NewsListModel (
24-
2527
@PrimaryKey
2628
@Expose
2729
@SerializedName("title")
28-
var title: String = "",
30+
var title: String = UUID. randomUUID().toString(),
2931
@Expose
3032
@SerializedName("urlToImage")
3133
var urlToImage: String? = null,
@@ -41,8 +43,8 @@ data class NewsListModel (
4143
@Expose
4244
@SerializedName("publishedAt")
4345
var publishedAt: String? = null,
44-
45-
@Embedded @SerializedName("source") val source : Source? = null ) : Serializable
46+
@Embedded
47+
@SerializedName("source") var source : Source? = null ) : Serializable
4648

4749
data class Source(
4850
@SerializedName("id")

app/src/main/java/com/kanchanpal/newsfeed/common/BindingAdapters.kt

-21
This file was deleted.

app/src/main/java/com/kanchanpal/newsfeed/data/dao/NewsDao.kt

+4-7
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,13 @@ import androidx.room.Query
99
import com.kanchanpal.newsfeed.api.NewsListModel
1010

1111
@Dao
12-
interface NewsDao {
12+
interface NewsDao {
1313
@Query("Select * from NewsListModel")
14-
fun getNews() : LiveData<List<NewsListModel>>
14+
fun getNews() : LiveData<List<NewsListModel>>
1515

1616
@Insert(onConflict = OnConflictStrategy.REPLACE)
17-
suspend fun insertAll(newsList: List<NewsListModel>)
18-
19-
@Insert(onConflict = OnConflictStrategy.REPLACE)
20-
suspend fun insert(news: NewsListModel)
17+
fun insert(news: NewsListModel)
2118

2219
@Query("SELECT * FROM NewsListModel")
23-
fun getPagedNews(): DataSource.Factory<Int, NewsListModel>
20+
fun getPagedNews(): DataSource.Factory<Int, NewsListModel>
2421
}

app/src/main/java/com/kanchanpal/newsfeed/data/newsSet/NewsPageDataSource.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ class NewsPageDataSource @Inject constructor(
5555
}
5656
is Result.Success -> {
5757
val results = response.data.articles
58-
newsDao.insertAll(results)
58+
for (result in results) {
59+
newsDao.insert(result)
60+
}
5961
callback(results)
6062
networkState.postValue(NetworkState.LOADED)
6163
}

app/src/main/java/com/kanchanpal/newsfeed/news/NewsAdapter.kt

+19-9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import androidx.navigation.findNavController
77
import androidx.paging.PagedListAdapter
88
import androidx.recyclerview.widget.DiffUtil
99
import androidx.recyclerview.widget.RecyclerView
10+
import com.bumptech.glide.Glide
1011
import com.kanchanpal.newsfeed.api.NewsListModel
1112
import com.kanchanpal.newsfeed.databinding.RvNewsListItemsBinding
1213

@@ -18,18 +19,24 @@ class NewsAdapter : PagedListAdapter<NewsListModel, NewsAdapter.ViewHolder>(Diff
1819
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
1920
val newsItem = getItem(position)
2021
holder.apply {
21-
bind(createOnClickListener( newsItem), newsItem)
22+
bind(createOnClickListener(newsItem), newsItem)
2223
itemView.tag = newsItem
2324
}
2425
}
26+
2527
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
26-
return ViewHolder(RvNewsListItemsBinding.inflate(
27-
LayoutInflater.from(parent.context), parent, false))
28+
return ViewHolder(
29+
RvNewsListItemsBinding.inflate(
30+
LayoutInflater.from(parent.context), parent, false
31+
)
32+
)
2833
}
29-
private fun createOnClickListener( newItem: NewsListModel?): View.OnClickListener {
34+
35+
private fun createOnClickListener(newItem: NewsListModel?): View.OnClickListener {
3036
return View.OnClickListener {
31-
val direction = NewsListFragmentDirections
32-
.actionNewsListFragmentToNewsDetailFragment(newItem ?: NewsListModel())
37+
val direction = NewsListFragmentDirections.actionNewsListFragmentToNewsDetailFragment(
38+
newItem ?: NewsListModel()
39+
)
3340
it.findNavController().navigate(direction)
3441
}
3542
}
@@ -40,9 +47,12 @@ class NewsAdapter : PagedListAdapter<NewsListModel, NewsAdapter.ViewHolder>(Diff
4047

4148
fun bind(listener: View.OnClickListener, item: NewsListModel?) {
4249
binding.apply {
43-
clickListener = listener
44-
newsItem = item
45-
executePendingBindings() }
50+
clNews.setOnClickListener(listener)
51+
textView.text = item?.title
52+
// tvChannel.text = item?.source?.name
53+
tvDate.text = item?.publishedAt?.substring(0, 10)
54+
Glide.with(itemView).load(item?.urlToImage).into(binding.ivNews)
55+
}
4656
}
4757
}
4858
}

app/src/main/java/com/kanchanpal/newsfeed/news/NewsDetailFragment.kt

+13-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import android.view.View
66
import android.view.ViewGroup
77
import androidx.fragment.app.Fragment
88
import androidx.navigation.fragment.navArgs
9+
import com.bumptech.glide.Glide
10+
import com.kanchanpal.newsfeed.api.NewsListModel
911
import com.kanchanpal.newsfeed.databinding.FragmentNewsDetailBinding
1012

1113
class NewsDetailFragment : Fragment() {
@@ -22,7 +24,17 @@ class NewsDetailFragment : Fragment() {
2224
activity?.supportFragmentManager?.popBackStack()
2325
}
2426
val newsModel = args.newsItem
25-
binding.newsDetail = newsModel
27+
populateDetailsFields(newsModel, binding)
2628
return binding.root
2729
}
30+
31+
private fun populateDetailsFields(newsModel: NewsListModel, binding: FragmentNewsDetailBinding) {
32+
binding.apply {
33+
// tvSource.text = newsModel.source?.name
34+
tvDate.text = newsModel.publishedAt
35+
tvDescDetail.text = newsModel.description
36+
tvHeadLineDetail.text = newsModel.title
37+
Glide.with(requireActivity()).load(newsModel.urlToImage).into(imageView)
38+
}
39+
}
2840
}
+4-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<layout xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:app="http://schemas.android.com/apk/res-auto">
4-
<LinearLayout
5-
android:layout_width="match_parent"
2+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
64
android:layout_height="match_parent"
5+
android:layout_width="match_parent"
76
android:orientation="vertical">
87

98
<fragment
@@ -14,5 +13,4 @@
1413
app:defaultNavHost="true"
1514
app:navGraph="@navigation/nav_main"/>
1615

17-
</LinearLayout>
18-
</layout>
16+
</LinearLayout>

0 commit comments

Comments
 (0)