diff --git a/.gitignore b/.gitignore
index aa724b7..eb8dd00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,11 @@
.DS_Store
/build
/captures
+/gradle.properties
+bin/
+gen/
+# Proguard folder generated by Eclipse
+proguard/
.externalNativeBuild
.cxx
local.properties
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
index 79ee123..6e6eec1 100644
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
deleted file mode 100644
index 0a9027d..0000000
--- a/.idea/deploymentTargetDropDown.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 526b4c2..a2d7c21 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -13,7 +13,6 @@
-
diff --git a/.idea/misc.xml b/.idea/misc.xml
index c2064d2..c3fd6cf 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,6 +5,10 @@
diff --git a/apk/News.apk b/apk/News.apk
new file mode 100644
index 0000000..3973d06
Binary files /dev/null and b/apk/News.apk differ
diff --git a/app/build.gradle b/app/build.gradle
index 95548f6..305cde4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,30 +1,42 @@
-
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
- id 'androidx.navigation.safeargs.kotlin'
}
apply plugin: 'kotlin-android'
android {
- compileSdk 30
+
defaultConfig {
-// configurations.all {
-// resolutionStrategy { force 'androidx.core:core-ktx:1.6.0' }
-// }
+ multiDexEnabled true
applicationId "com.example.newsapp"
minSdk 21
- targetSdk 30
+ targetSdk 31
versionCode 1
versionName "1.0"
- compileSdk 31
+ compileSdk 32
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+// Please ensure you have a valid API KEY for https://newsapi.org/
+// to use this app
+// A valid key will need to be entered
+ buildConfigField("String", 'API_KEY', API_KEY)
+// buildConfigField('String' , 'myParameter', 'someValue')
+
+ }
+
+ compileOptions {
+
+ coreLibraryDesugaringEnabled true
+
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+
}
buildTypes {
@@ -32,52 +44,46 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
+// buildTypes.each {
+// it.buildConfigField 'String', 'API_KEY', API_KEY
+// }
}
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
+
+
kotlinOptions {
jvmTarget = '1.8'
}
+ namespace 'com.example.newsapp'
}
dependencies {
- implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
- def room_version = '2.4.2'
- def nav_version = '2.4.1'
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
-
- implementation "androidx.navigation:navigation-fragment-ktx:2.4.1"
- implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
-
- implementation "androidx.room:room-runtime:$room_version"
- kapt "androidx.room:room-compiler:$room_version"
-
implementation "androidx.activity:activity-ktx:1.4.0"
-
- implementation 'androidx.core:core-ktx:1.7.0'
- implementation 'androidx.appcompat:appcompat:1.4.1'
- implementation 'com.google.android.material:material:1.5.0'
+ implementation 'androidx.core:core-ktx:1.8.0'
+ implementation 'androidx.appcompat:appcompat:1.4.2'
+ implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ def room_version = '2.4.2'
+ implementation "androidx.room:room-runtime:$room_version"
+ kapt "androidx.room:room-compiler:$room_version"
+
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0'
-
-// GSON
-
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
-
implementation 'com.squareup.picasso:picasso:2.71828'
- implementation "androidx.core:core-ktx:+"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.facebook.shimmer:shimmer:0.5.0'
+
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1732ab1..8cad41b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,9 +1,15 @@
-
+
+
+
+
+
+
+
+
+
-
-
-
+ android:name=".SavedNewsActivity"
+ android:label="Saved News"
+ android:parentActivityName=".MainActivity" />
\ No newline at end of file
diff --git a/app/src/main/java/com/example/newsapp/CustomAdapter.kt b/app/src/main/java/com/example/newsapp/CustomAdapter.kt
deleted file mode 100644
index 6b56fa5..0000000
--- a/app/src/main/java/com/example/newsapp/CustomAdapter.kt
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.example.newsapp
-
-import android.content.Context
-import android.content.Intent
-import android.net.Uri
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageButton
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-import com.squareup.picasso.Picasso
-
-
-class CustomAdapter(private val newsList: MutableList, val saveListener: SaveClickListener) : RecyclerView.Adapter(){
-
- private lateinit var context: Context
-
- companion object{
- var myClickListener: SaveClickListener? = null
-
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
-
- val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
- context = parent.context
- return ViewHolder(view)
- }
-
-
- private fun openNews(url: String, cont: Context){
-
- val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
- cont.startActivity(intent)
- }
-
-
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
-
- val newsData = newsList[holder.adapterPosition]
-
- holder.headLine.text = newsData.headLine
- holder.description.text = newsData.description
-
- if(!newsData.image.isNullOrEmpty()) {
- Picasso.get().load(newsData.image).fit().centerCrop().into(holder.image)
- }else{
- holder.image.visibility = View.GONE
- }
-
-
- if(context.toString().contains("com.example.newsapp.SavedNews")){
- holder.saveBtn.setImageResource(R.drawable.ic_baseline_delete_outline_24)
- }
-
-
- holder.image.setOnClickListener {
- newsData.url?.let { it1 -> openNews(it1, context) }
- }
-
- holder.headLine.setOnClickListener{ newsData.url?.let { it1 ->
- openNews(
- it1, context)
- } }
-
- holder.shareBtn.setOnClickListener {
-
- val intent = Intent(Intent.ACTION_SEND)
- intent.putExtra(Intent.EXTRA_TEXT, "Hey, checkout this news : " + newsData.url)
- intent.type = "text/plain"
- context.startActivity(Intent.createChooser(intent, "Share with :"))
-
- }
-
- myClickListener = saveListener
-
- holder.saveBtn.setOnClickListener {
- if (myClickListener != null) {
- myClickListener?.onSaveBtnClick(holder.adapterPosition)
- }
- }
- }
-
-
-
- override fun getItemCount(): Int {
- return newsList.size
- }
-
- class ViewHolder(ItemView: View?) : RecyclerView.ViewHolder(ItemView!!){
-
- val saveBtn: ImageButton = itemView.findViewById(R.id.save_news)
- val shareBtn: ImageButton = itemView.findViewById(R.id.share_btn)
- val image: ImageView = itemView.findViewById(R.id.news_image)
- val headLine: TextView = itemView.findViewById(R.id.headline)
- val description: TextView = itemView.findViewById(R.id.description)
-
-
- }
-
- interface SaveClickListener {
- fun onSaveBtnClick(position: Int)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/newsapp/MainActivity.kt b/app/src/main/java/com/example/newsapp/MainActivity.kt
index f47e182..405b9f2 100644
--- a/app/src/main/java/com/example/newsapp/MainActivity.kt
+++ b/app/src/main/java/com/example/newsapp/MainActivity.kt
@@ -1,203 +1,185 @@
package com.example.newsapp
+import android.content.Context
import android.content.Intent
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities
+import android.os.Build
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
-import android.view.animation.TranslateAnimation
-import android.widget.*
-import androidx.annotation.Nullable
+import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.ViewModelProvider
-import androidx.recyclerview.widget.DividerItemDecoration
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
+import androidx.viewpager2.widget.ViewPager2
+import com.example.newsapp.adapters.FragmentAdapter
import com.example.newsapp.architecture.NewsViewModel
import com.facebook.shimmer.ShimmerFrameLayout
-
+import com.google.android.material.tabs.TabLayout
+import com.google.android.material.tabs.TabLayoutMediator
+//import com.example.newsapp.BuildConfig
class MainActivity : AppCompatActivity() {
+ companion object {
+
+ var APIRequestError = false
+ var errorMessage = "error"
+ const val API_KEY = BuildConfig.API_KEY
+ const val TOTAL_NEWS_TAB = 7
+ const val TOP_HEADLINES_COUNT = 5
+ const val GENERAL = "general"
+ const val SCIENCE = "science"
+ const val HEALTH = "health"
+ const val ENTERTAINMENT = "entertainment"
+ const val BUSINESS = "business"
+ const val TECHNOLOGY = "technology"
+ const val SPORTS = "sports"
+ const val NEWS_URL = "news url"
+ const val NEWS_TITLE = "news title"
+ const val NEWS_IMAGE_URL = "news image url"
+ const val NEWS_SOURCE = "news source"
+ const val NEWS_PUBLICATION_TIME = "news publication time"
+ const val NEWS_DESCRIPTION = "news description"
+ const val NEWS_CONTENT = "news content"
+ var generalNews: ArrayList = ArrayList()
+ var entertainmentNews: MutableList = mutableListOf()
+ var businessNews: MutableList = mutableListOf()
+ var healthNews: MutableList = mutableListOf()
+ var scienceNews: MutableList = mutableListOf()
+ var sportsNews: MutableList = mutableListOf()
+ var techNews: MutableList = mutableListOf()
+
+ }
+
+// Tabs Title
+ private val newsCategories = arrayOf(
+ "Home",
+ BUSINESS,
+ ENTERTAINMENT,
+ SCIENCE,
+ SPORTS,
+ TECHNOLOGY,
+ HEALTH
+ )
+
private lateinit var viewModel: NewsViewModel
- private lateinit var recyclerView: RecyclerView
- private lateinit var newsContainer: FrameLayout
- private lateinit var fetchedNews: MutableList
- private lateinit var mAdapter: CustomAdapter
+ private lateinit var tabLayout: TabLayout
+ private lateinit var viewPager: ViewPager2
+ private lateinit var fragmentAdapter: FragmentAdapter
private lateinit var shimmerLayout: ShimmerFrameLayout
- private lateinit var categoryContainer: LinearLayout
- private lateinit var dropBtn: ImageButton
-
- private var hideCategory: Boolean = false
+ private var totalRequestCount = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
- categoryContainer = findViewById(R.id.cate_container)
- dropBtn = findViewById(R.id.drop_btn)
- newsContainer = findViewById(R.id.news_container)
- recyclerView = findViewById(R.id.recyclerView)
- shimmerLayout = findViewById(R.id.shimmerLayout)
- recyclerView.layoutManager = LinearLayoutManager(this)
- recyclerView.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
- viewModel = ViewModelProvider(this)[NewsViewModel::class.java]
- fetchedNews = mutableListOf()
-
- findViewById