Skip to content

Commit

Permalink
Merge pull request #4 from paolovalerdi/ui_improvements
Browse files Browse the repository at this point in the history
✅ Refactoring UI
  • Loading branch information
Spikeysanju authored Jul 21, 2020
2 parents 574bbc0 + ba0e224 commit d7b3d98
Show file tree
Hide file tree
Showing 17 changed files with 263 additions and 144 deletions.
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
android:label="@string/app_name"
android:roundIcon="@drawable/nytimes"
android:supportsRtl="true"
android:theme="@style/Theme.Design.Light">
android:theme="@style/Theme.Topten">
<activity android:name="www.thecodemonks.techbytes.ui.base.BaseActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
10 changes: 2 additions & 8 deletions app/src/main/java/www/thecodemonks/techbytes/repo/Repo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,12 @@

package www.thecodemonks.techbytes.repo

import androidx.lifecycle.MutableLiveData
import org.jsoup.Jsoup
import www.thecodemonks.techbytes.db.ArticleDatabase
import www.thecodemonks.techbytes.model.Article

class Repo(private val db: ArticleDatabase) {

var crawledFromNYTimes: MutableLiveData<List<Article>> = MutableLiveData()

// insert or update article
suspend fun upsertArticle(article: Article) = db.getArticleDao().upsert(article)

Expand All @@ -45,7 +42,7 @@ class Repo(private val db: ArticleDatabase) {
suspend fun deleteArticle(article: Article) = db.getArticleDao().deleteArticle(article)

// crawl data from ny times by selecting Xpath elements
fun crawlFromNYTimes(url: String): MutableLiveData<List<Article>> {
fun crawlFromNYTimes(url: String): List<Article> {

val document = Jsoup.connect(url).get()
val articles: MutableList<Article> = mutableListOf()
Expand Down Expand Up @@ -78,10 +75,7 @@ class Repo(private val db: ArticleDatabase) {
}
}

// post value to liveData after crawling
crawledFromNYTimes.value = articles

return crawledFromNYTimes
return articles
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@ import android.os.StrictMode
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_articles.*
import www.thecodemonks.techbytes.R
import www.thecodemonks.techbytes.model.Category
Expand All @@ -50,6 +49,7 @@ import www.thecodemonks.techbytes.utils.Constants.NY_SPACE
import www.thecodemonks.techbytes.utils.Constants.NY_SPORTS
import www.thecodemonks.techbytes.utils.Constants.NY_TECH
import www.thecodemonks.techbytes.utils.Constants.NY_YOURMONEY
import www.thecodemonks.techbytes.utils.SpacesItemDecorator


class ArticlesFragment : Fragment(R.layout.fragment_articles) {
Expand Down Expand Up @@ -88,15 +88,30 @@ class ArticlesFragment : Fragment(R.layout.fragment_articles) {
categoryAdapter = CategoryAdapter(category)
category_rv.rootView.post {
category_rv.adapter = categoryAdapter
category_rv.layoutManager =
LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
category_rv.addItemDecoration(SpacesItemDecorator(16))
}

// observe changes on topic change for list
viewModel.currentTopic.observe(viewLifecycleOwner, Observer {
startCrawlObserver(it.toString())
article_rv.animate().alpha(0f)
.withStartAction {
progress_view.isVisible = true
progress_view.animate().alpha(1f)
}
.withEndAction {
viewModel.crawlFromNYTimes(it.toString())
}
})

// observe the articles
viewModel.articles.observe(viewLifecycleOwner, Observer {
newsAdapter.differ.submitList(it)
progress_view.animate().alpha(0f)
.withEndAction {
article_rv.animate().alpha(1f)
progress_view.isVisible = false
}
})

// onclick to select source & post value to liveData
categoryAdapter.setOnItemClickListener {
Expand All @@ -118,18 +133,6 @@ class ArticlesFragment : Fragment(R.layout.fragment_articles) {

}

private fun startCrawlObserver(url: String?) {
progress_view.visibility = View.VISIBLE
url?.let { currentTopic ->
viewModel.crawlFromNYTimes(currentTopic).observe(viewLifecycleOwner, Observer { list ->
newsAdapter.differ.submitList(list)
progress_view.visibility = View.GONE
})
}

}


override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.menu, menu)
Expand All @@ -150,9 +153,7 @@ class ArticlesFragment : Fragment(R.layout.fragment_articles) {
newsAdapter = NewsAdapter()
article_rv.apply {
adapter = newsAdapter
layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
article_rv.visibility = View.VISIBLE

addItemDecoration(SpacesItemDecorator(16))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.ui.NavigationUI
import kotlinx.android.synthetic.main.activity_base.*
import www.thecodemonks.techbytes.R
import www.thecodemonks.techbytes.db.ArticleDatabase
import www.thecodemonks.techbytes.repo.Repo
Expand All @@ -47,7 +48,7 @@ class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_base)

setSupportActionBar(toolbar)
// setup VMProviderFactory
val repo = Repo(
ArticleDatabase(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import www.thecodemonks.techbytes.model.Article
import www.thecodemonks.techbytes.ui.adapter.NewsAdapter
import www.thecodemonks.techbytes.ui.base.BaseActivity
import www.thecodemonks.techbytes.ui.viewmodel.ArticleViewModel
import www.thecodemonks.techbytes.utils.SpacesItemDecorator


class BookmarksFragment : Fragment(R.layout.fragment_bookmarks) {
Expand Down Expand Up @@ -122,7 +123,7 @@ class BookmarksFragment : Fragment(R.layout.fragment_bookmarks) {
newsAdapter = NewsAdapter()
bookmark_rv.apply {
adapter = newsAdapter
layoutManager = LinearLayoutManager(activity)
addItemDecoration(SpacesItemDecorator(16))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@

package www.thecodemonks.techbytes.ui.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import www.thecodemonks.techbytes.model.Article
import www.thecodemonks.techbytes.repo.Repo
Expand All @@ -37,6 +39,10 @@ import www.thecodemonks.techbytes.utils.Constants

class ArticleViewModel(private val repo: Repo) : ViewModel() {

private val _articles = MutableLiveData<List<Article>>()
val articles: LiveData<List<Article>>
get() = _articles

val currentTopic: MutableLiveData<String> by lazy {
MutableLiveData<String>().defaultTopic(Constants.NY_TECH)
}
Expand All @@ -55,7 +61,11 @@ class ArticleViewModel(private val repo: Repo) : ViewModel() {
}

// crawl data from NY times
fun crawlFromNYTimes(url: String) = repo.crawlFromNYTimes(url)
fun crawlFromNYTimes(url: String) {
viewModelScope.launch(IO) {
_articles.postValue(repo.crawlFromNYTimes(url))
}
}


private fun <T : Any?> MutableLiveData<T>.defaultTopic(initialValue: T) =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
*
* * MIT License
* *
* * Copyright (c) 2020 Spikey Sanju
* *
* * Permission is hereby granted, free of charge, to any person obtaining a copy
* * of this software and associated documentation files (the "Software"), to deal
* * in the Software without restriction, including without limitation the rights
* * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* * copies of the Software, and to permit persons to whom the Software is
* * furnished to do so, subject to the following conditions:
* *
* * The above copyright notice and this permission notice shall be included in all
* * copies or substantial portions of the Software.
* *
* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* * SOFTWARE.
*
*/

package www.thecodemonks.techbytes.utils

import android.content.res.Resources
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class SpacesItemDecorator(space: Int) : RecyclerView.ItemDecoration() {

private val space: Int = space.dp

override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val orientation = (parent.layoutManager as? LinearLayoutManager)?.orientation
?: LinearLayoutManager.VERTICAL
if (orientation == LinearLayoutManager.HORIZONTAL) {
when (parent.getChildLayoutPosition(view)) {
0 -> {
outRect.left = space
outRect.right = space
}
else -> outRect.right = space
}
} else {
when (parent.getChildLayoutPosition(view)) {
0 -> {
outRect.top = space
outRect.left = space
outRect.right = space
outRect.bottom = space
}
else -> {
outRect.left = space
outRect.right = space
outRect.bottom = space
}
}
}
}
}

val Int.dp: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt()
26 changes: 18 additions & 8 deletions app/src/main/res/layout/activity_base.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ /*
~ * MIT License
~ *
Expand All @@ -25,24 +24,35 @@
~ */
-->

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface"
tools:context="www.thecodemonks.techbytes.ui.base.BaseActivity">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="?colorSurface"
app:liftOnScroll="true">

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize" />

</com.google.android.material.appbar.AppBarLayout>

<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
app:navGraph="@navigation/nav_graph" />

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
15 changes: 5 additions & 10 deletions app/src/main/res/layout/fragment_article_details.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ /*
~ * MIT License
~ *
Expand All @@ -25,11 +24,10 @@
~ */
-->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="www.thecodemonks.techbytes.ui.base.BaseActivity">

<WebView
Expand All @@ -41,13 +39,10 @@
android:id="@+id/btn_saved_article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_margin="30dp"
android:background="@color/design_default_color_primary"
app:backgroundTint="@color/design_default_color_primary"
android:layout_gravity="bottom|end"
android:layout_margin="32dp"
android:contentDescription="@string/app_name"
android:src="@android:drawable/ic_input_add"
android:tint="@color/white" />

</RelativeLayout>
</FrameLayout>
Loading

0 comments on commit d7b3d98

Please sign in to comment.