Skip to content

Commit 32c8192

Browse files
committedJan 11, 2020
added Navigation Component, Fragment, Layouts and much more.
1 parent 0150dbd commit 32c8192

13 files changed

+264
-96
lines changed
 

‎app/build.gradle

+30-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ apply plugin: 'kotlin-android'
44

55
apply plugin: 'kotlin-android-extensions'
66

7+
apply plugin: "kotlin-kapt"
78
android {
89
compileSdkVersion 29
910
buildToolsVersion "29.0.2"
@@ -14,6 +15,7 @@ android {
1415
versionCode 1
1516
versionName "1.0"
1617
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18+
buildConfigField("String", "API_KEY", API_KEY)
1719
}
1820

1921

@@ -23,27 +25,47 @@ android {
2325
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
2426
}
2527
}
26-
}
2728

29+
dataBinding {
30+
enabled = true
31+
}
32+
}
2833

2934

3035
dependencies {
3136

32-
def retrofitVersion="2.6.1"
33-
def rxAndroidVersion="2.1.1"
34-
def okHttpVersion="4.2.2"
35-
37+
def retrofitVersion = "2.6.1"
38+
def rxAndroidVersion = "2.1.1"
39+
def okHttpVersion = "4.2.2"
40+
def navVersion = "2.1.0"
3641
implementation fileTree(dir: 'libs', include: ['*.jar'])
37-
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
42+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
3843
implementation 'androidx.appcompat:appcompat:1.1.0'
3944
implementation 'androidx.core:core-ktx:1.1.0'
4045
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
41-
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
42-
implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"
46+
implementation 'androidx.recyclerview:recyclerview:1.1.0'
47+
implementation 'androidx.cardview:cardview:1.0.0'
48+
49+
// ROOM
50+
51+
// NAVIGATION COMPONENT
52+
implementation "androidx.navigation:navigation-fragment-ktx:$navVersion"
53+
implementation "androidx.navigation:navigation-ui-ktx:$navVersion"
54+
55+
// RX ANDROID
4356
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
57+
58+
// RETROFIT
4459
implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitVersion"
60+
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
61+
implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"
62+
63+
// OK HTTP
4564
implementation "com.squareup.okhttp3:okhttp:$okHttpVersion"
4665
implementation "com.squareup.okhttp3:logging-interceptor:$okHttpVersion"
66+
67+
// TESTING
68+
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
4769
testImplementation 'junit:junit:4.12'
4870
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
4971
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

‎app/src/main/AndroidManifest.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
android:roundIcon="@mipmap/ic_launcher_round"
1212
android:supportsRtl="true"
1313
android:theme="@style/AppTheme">
14-
<activity android:name=".MainActivity">
14+
<activity android:name=".view.MainActivity">
1515
<intent-filter>
1616
<action android:name="android.intent.action.MAIN" />
1717

‎app/src/main/java/com/androiddevs/newsflash/MainActivity.kt

-70
This file was deleted.

‎app/src/main/java/com/androiddevs/newsflash/repository/NewsApiService.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.androiddevs.newsflash.repository
22

3+
4+
import com.androiddevs.newsflash.BuildConfig
35
import com.androiddevs.newsflash.data.NewsResult
46
import com.androiddevs.newsflash.data.NewsSources
57
import io.reactivex.Observable
@@ -60,7 +62,7 @@ interface NewsApiService {
6062
val original = chain.request()
6163

6264
val request = original.newBuilder()
63-
.addHeader("X-Api-Key", "PUT YOUR OWN API KEY HERE")
65+
.addHeader("X-Api-Key", BuildConfig.API_KEY)
6466
.method(original.method, original.body)
6567
.build()
6668

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.androiddevs.newsflash.view
2+
3+
import androidx.appcompat.app.AppCompatActivity
4+
import android.os.Bundle
5+
import android.util.Log
6+
import com.androiddevs.newsflash.R
7+
import com.androiddevs.newsflash.repository.NewsApiService
8+
import io.reactivex.android.schedulers.AndroidSchedulers
9+
import io.reactivex.disposables.Disposable
10+
import io.reactivex.schedulers.Schedulers
11+
12+
class MainActivity : AppCompatActivity()
13+
{
14+
15+
override fun onCreate(savedInstanceState: Bundle?)
16+
{
17+
super.onCreate(savedInstanceState)
18+
setContentView(R.layout.activity_main)
19+
20+
21+
22+
23+
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.androiddevs.newsflash.view.adapter
2+
3+
4+
import android.view.LayoutInflater
5+
import android.view.ViewGroup
6+
import androidx.databinding.DataBindingUtil
7+
import androidx.recyclerview.widget.RecyclerView
8+
import com.androiddevs.newsflash.R
9+
import com.androiddevs.newsflash.data.NewsResult
10+
import com.androiddevs.newsflash.databinding.HomeNewsRowBinding
11+
12+
13+
class HomeNewsRecyelerAdapter(private var newsList: ArrayList<NewsResult.News.Article>) :
14+
RecyclerView.Adapter<HomeNewsRecyelerAdapter.ViewHolder>() {
15+
16+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
17+
val layoutInflater = LayoutInflater.from(parent.context)
18+
19+
val homeNewsRowBinding: HomeNewsRowBinding = DataBindingUtil.inflate(
20+
layoutInflater, R.layout.home_news_row,
21+
parent,
22+
false
23+
)
24+
25+
return ViewHolder(homeNewsRowBinding)
26+
}
27+
28+
override fun getItemCount(): Int {
29+
return newsList.size
30+
}
31+
32+
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
33+
val newsArticle = newsList[position]
34+
holder.bind(newsArticle)
35+
}
36+
class ViewHolder(binding: HomeNewsRowBinding) : RecyclerView.ViewHolder(binding.root) {
37+
private var binding: HomeNewsRowBinding? = binding
38+
39+
fun bind(obj: NewsResult.News.Article){
40+
binding!!.setVariable(com.androiddevs.newsflash.BR.news,obj)
41+
}
42+
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.androiddevs.newsflash.view.fragments
2+
3+
4+
import android.os.Bundle
5+
import android.util.Log
6+
import androidx.fragment.app.Fragment
7+
import android.view.LayoutInflater
8+
import android.view.View
9+
import android.view.ViewGroup
10+
import androidx.databinding.DataBindingUtil
11+
import androidx.recyclerview.widget.LinearLayoutManager
12+
13+
import com.androiddevs.newsflash.R
14+
import com.androiddevs.newsflash.data.NewsResult
15+
import com.androiddevs.newsflash.databinding.FragmentHomeBinding
16+
import com.androiddevs.newsflash.databinding.FragmentHomeBinding.inflate
17+
import com.androiddevs.newsflash.databinding.HomeNewsRowBinding
18+
import com.androiddevs.newsflash.repository.NewsApiService
19+
import com.androiddevs.newsflash.view.adapter.HomeNewsRecyelerAdapter
20+
import io.reactivex.android.schedulers.AndroidSchedulers
21+
import io.reactivex.disposables.Disposable
22+
import io.reactivex.schedulers.Schedulers
23+
import kotlinx.android.synthetic.main.fragment_home.*
24+
25+
/**
26+
* A simple [Fragment] subclass.
27+
*/
28+
class HomeFragment : Fragment() {
29+
private val newsApiService by lazy { NewsApiService.create() }
30+
private lateinit var disposable: Disposable
31+
private lateinit var newsList: ArrayList<NewsResult.News.Article>
32+
override fun onCreateView(
33+
inflater: LayoutInflater, container: ViewGroup?,
34+
savedInstanceState: Bundle?
35+
): View? {
36+
val homeBinding = DataBindingUtil.inflate<FragmentHomeBinding>(
37+
inflater,
38+
R.layout.fragment_home,
39+
container,
40+
false
41+
)
42+
newsList = ArrayList()
43+
disposable = newsApiService.getTopHeadlines("us", "", "", "", 10, 0)
44+
.subscribeOn(Schedulers.io())
45+
.observeOn(AndroidSchedulers.mainThread())
46+
.subscribe({ result ->
47+
for (article in result.articles) {
48+
newsList.add(article)
49+
}
50+
homeRecyclerView.adapter = HomeNewsRecyelerAdapter(newsList)
51+
homeRecyclerView.layoutManager = LinearLayoutManager(context)
52+
}, { error -> Log.v("Error", error.message.toString()) })
53+
return homeBinding.root
54+
}
55+
56+
57+
}
+15-16
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
2+
<layout xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:app="http://schemas.android.com/apk/res-auto"
4-
xmlns:tools="http://schemas.android.com/tools"
5-
android:layout_width="match_parent"
6-
android:layout_height="match_parent"
7-
tools:context=".MainActivity">
8-
9-
<TextView
10-
android:layout_width="wrap_content"
11-
android:layout_height="wrap_content"
12-
android:text="Hello World!"
13-
app:layout_constraintBottom_toBottomOf="parent"
14-
app:layout_constraintLeft_toLeftOf="parent"
15-
app:layout_constraintRight_toRightOf="parent"
16-
app:layout_constraintTop_toTopOf="parent" />
17-
18-
</androidx.constraintlayout.widget.ConstraintLayout>
4+
xmlns:tools="http://schemas.android.com/tools">
5+
<androidx.constraintlayout.widget.ConstraintLayout
6+
android:layout_width="match_parent"
7+
android:layout_height="match_parent"
8+
tools:context=".view.MainActivity">
9+
<fragment
10+
android:id="@+id/fragment_main"
11+
android:name="androidx.navigation.fragment.NavHostFragment"
12+
android:layout_width="match_parent"
13+
android:layout_height="match_parent"
14+
app:defaultNavHost="true"
15+
app:navGraph="@navigation/navigation_graph"/>
16+
</androidx.constraintlayout.widget.ConstraintLayout>
17+
</layout>
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<layout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools">
4+
<FrameLayout
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent"
7+
tools:context=".view.fragments.HomeFragment">
8+
<androidx.recyclerview.widget.RecyclerView
9+
android:id="@+id/homeRecyclerView"
10+
android:layout_width="match_parent"
11+
android:layout_height="match_parent"/>
12+
</FrameLayout>
13+
</layout>
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
3+
xmlns:android="http://schemas.android.com/apk/res/android">
4+
<data>
5+
<variable
6+
name="news"
7+
type="com.androiddevs.newsflash.data.NewsResult.News.Article" />
8+
</data>
9+
<androidx.cardview.widget.CardView
10+
android:layout_width="match_parent"
11+
android:layout_height="wrap_content"
12+
android:layout_margin="8dp"
13+
android:orientation="vertical">
14+
15+
<androidx.constraintlayout.widget.ConstraintLayout
16+
android:layout_width="match_parent"
17+
android:layout_height="wrap_content">
18+
19+
<TextView
20+
android:id="@+id/textView"
21+
android:layout_width="0dp"
22+
android:layout_height="wrap_content"
23+
android:layout_marginStart="16dp"
24+
android:layout_marginEnd="16dp"
25+
android:layout_marginTop="16dp"
26+
android:text="@{news.title}"
27+
android:textStyle="bold"
28+
android:textSize="20sp"
29+
android:textColor="@android:color/black"
30+
app:layout_constraintStart_toStartOf="parent"
31+
app:layout_constraintTop_toTopOf="parent" />
32+
33+
<TextView
34+
android:id="@+id/textView2"
35+
android:layout_width="0dp"
36+
android:layout_height="wrap_content"
37+
android:layout_marginStart="16dp"
38+
android:layout_marginEnd="16dp"
39+
android:layout_marginTop="16dp"
40+
android:text="@{(news.author.length>0)? news.author : @string/unknown_value}"
41+
android:textSize="18sp"
42+
android:textColor="@android:color/black"
43+
app:layout_constraintStart_toStartOf="parent"
44+
app:layout_constraintTop_toBottomOf="@+id/textView" />
45+
46+
<TextView
47+
android:layout_width="0dp"
48+
android:layout_height="wrap_content"
49+
android:layout_marginStart="16dp"
50+
android:layout_marginTop="16dp"
51+
android:layout_marginEnd="16dp"
52+
android:layout_marginBottom="8dp"
53+
android:text="@{news.content}"
54+
app:layout_constraintBottom_toBottomOf="parent"
55+
app:layout_constraintEnd_toEndOf="parent"
56+
app:layout_constraintStart_toStartOf="parent"
57+
app:layout_constraintTop_toBottomOf="@+id/textView2" />
58+
59+
</androidx.constraintlayout.widget.ConstraintLayout>
60+
</androidx.cardview.widget.CardView>
61+
</layout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
xmlns:tools="http://schemas.android.com/tools"
5+
android:id="@+id/navigation_graph"
6+
app:startDestination="@id/homeFragment">
7+
8+
<fragment
9+
android:id="@+id/homeFragment"
10+
android:name="com.androiddevs.newsflash.view.fragments.HomeFragment"
11+
android:label="fragment_home"
12+
tools:layout="@layout/fragment_home" />
13+
</navigation>

‎app/src/main/res/values/strings.xml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<resources>
22
<string name="app_name">News Flash</string>
3+
<string name="unknown_value">Unknown</string>
34
</resources>

‎gradle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# Specifies the JVM arguments used for the daemon process.
88
# The setting is particularly useful for tweaking memory settings.
99
org.gradle.jvmargs=-Xmx1536m
10+
API_KEY = ""
1011
# When configured, Gradle will run in incubating parallel mode.
1112
# This option should only be used with decoupled projects. More details, visit
1213
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects

0 commit comments

Comments
 (0)
Please sign in to comment.