Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions Demo/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}

android {
Expand All @@ -24,26 +25,30 @@ android {
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}

buildFeatures {
viewBinding true
dataBinding true
}
}

dependencies {

implementation 'androidx.core:core-ktx:1.9.0'
def lifecycle_version = "2.6.1"
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
implementation 'androidx.fragment:fragment-ktx:1.5.5'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation 'androidx.fragment:fragment-ktx:1.5.7'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.core:core-splashscreen:1.0.1"
implementation "androidx.preference:preference-ktx:1.2.0"

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
Expand Down
22 changes: 21 additions & 1 deletion Demo/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,34 @@
xmlns:tools="http://schemas.android.com/tools">

<application
android:name=".DemoApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.Demo"
android:theme="@style/Theme.App.Starting"
tools:targetApi="31">
<activity
android:name=".stackexchange.StackExchangeActivity"
android:exported="true"
android:theme="@style/Theme.StackExchange">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".UIComponentsActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="true">
Expand Down
22 changes: 22 additions & 0 deletions Demo/app/src/main/java/com/krunal/demo/DemoApplication.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.krunal.demo

import android.app.Application
import com.krunal.demo.uicomponents.helpers.PreferenceHelper

class DemoApplication: Application() {

override fun onCreate() {
super.onCreate()

instance = this

/**
* Initialize [PreferenceHelper]
*/
PreferenceHelper.initialize(applicationContext)
}

companion object {
lateinit var instance: Application
}
}
9 changes: 6 additions & 3 deletions Demo/app/src/main/java/com/krunal/demo/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {

lateinit var binding: ActivityMainBinding
lateinit var mPlayer: MediaPlayer
private lateinit var binding: ActivityMainBinding
private lateinit var mPlayer: MediaPlayer
private val viewModel: MainActivityViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding = ActivityMainBinding.inflate(layoutInflater)

setContentView(binding.root)

binding.mainViewModel = viewModel

// Update time without data binding
CoroutineScope(Dispatchers.IO).launch {
viewModel.timeFlow.collectLatest { time ->
runOnUiThread {
Copy link
Copy Markdown

@github-actions github-actions bot May 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AIReviewRadar

The changes in this patch look good.

However, it would be better to add a comment explaining the purpose of binding.mainViewModel = viewModel for future developers who may work on this code.

Other than that, I don't see any issues with this patch.

@@ -12,15 +12,18 @@ import kotlinx.coroutines.launch
 
 class MainActivity : AppCompatActivity() {
 
-    lateinit var binding: ActivityMainBinding
-    lateinit var mPlayer: MediaPlayer
+    private lateinit var binding: ActivityMainBinding
+    private lateinit var mPlayer: MediaPlayer
     private val viewModel: MainActivityViewModel by viewModels()
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-
         binding = ActivityMainBinding.inflate(layoutInflater)
 
         setContentView(binding.root)
+
+        // Set up view model for data binding
+        binding.mainViewModel = viewModel
+
+        // Update time without data binding
         CoroutineScope(Dispatchers.IO).launch {
             viewModel.timeFlow.collectLatest { time ->
                 runOnUiThread {

Please add a comment explaining the purpose of binding.mainViewModel = viewModel.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package com.krunal.demo

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.*
import java.util.Date

class MainActivityViewModel : ViewModel() {

private val _timeFlow = MutableSharedFlow<String>()
val timeFlow: MutableSharedFlow<String> = _timeFlow
private val _timeFlow = MutableStateFlow<String?>(null)
val timeFlow: StateFlow<String?> = _timeFlow

init {
start()
Expand Down
31 changes: 31 additions & 0 deletions Demo/app/src/main/java/com/krunal/demo/UIComponentsActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.krunal.demo

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.krunal.demo.uicomponents.ButtonFragment
import com.krunal.demo.uicomponents.CoordinatorLayoutFragment
import com.krunal.demo.uicomponents.ThemeFragment
import com.krunal.demo.uicomponents.cardscreen.CardFragment
import com.krunal.demo.uicomponents.helpers.ThemeHelper

class UIComponentsActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()
setupTheme()
setContentView(R.layout.activity_uicomponents)
setupFragment()
}

private fun setupTheme() {
setTheme(ThemeHelper.getThemeResource(ThemeHelper.getThemeAccent()))
}

private fun setupFragment() {
supportFragmentManager.beginTransaction()
.replace(R.id.uiComponentsFragment, CoordinatorLayoutFragment())
.commit()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.krunal.demo.stackexchange

import android.graphics.Color
import android.os.Bundle
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.badge.BadgeUtils
import com.google.android.material.badge.ExperimentalBadgeUtils
import com.krunal.demo.R
import com.krunal.demo.databinding.ActivityStackExchangeBinding
import com.krunal.demo.stackexchange.exchange.ExchangeFragment
import com.krunal.demo.stackexchange.market.MarketFragment
import com.krunal.demo.stackexchange.wallet.WalletFragment
import com.krunal.demo.uicomponents.extentions.getThemeColor
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch


class StackExchangeActivity : AppCompatActivity() {

private lateinit var binding: ActivityStackExchangeBinding
private val viewModel: StackExchangeActivityViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityStackExchangeBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.viewModel = viewModel
setupUI()
setupBottomNavigation()
}

private fun setupUI() {

setupAppBar()

binding.apply {
fabExchange.setOnClickListener {
bottomNavigation.selectedItemId = R.id.actionExchange
}
}
}

@androidx.annotation.OptIn(ExperimentalBadgeUtils::class)
private fun setupAppBar() {
setSupportActionBar(binding.toolbar)
val badge = BadgeDrawable.create(this).apply {
badgeTextColor = getThemeColor(com.google.android.material.R.attr.colorOnSecondary)
backgroundColor = getThemeColor(com.google.android.material.R.attr.colorSecondary)
}

binding.notificationView.apply {
clipToOutline = false
bringToFront()
viewTreeObserver.addOnGlobalLayoutListener {
BadgeUtils.attachBadgeDrawable(
badge,
binding.notificationView
)
}
}

lifecycleScope.launch {
viewModel.notificationCount.collectLatest {
if (it == 0) {
badge.isVisible = false
} else {
badge.number = it
}
}
}
}

private fun setupBottomNavigation() {
changeFragment(MarketFragment())

binding.bottomNavigation.setOnItemSelectedListener { menuItem ->
val fragment = when (menuItem.itemId) {
R.id.actionMarket -> MarketFragment()
R.id.actionExchange -> ExchangeFragment()
else -> WalletFragment()
}
changeFragment(fragment)
return@setOnItemSelectedListener true
}
}

private fun changeFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction().replace(R.id.fragmentContainer, fragment).commit()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.krunal.demo.stackexchange

import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

class StackExchangeActivityViewModel : ViewModel() {

private val _notificationCount: MutableStateFlow<Int> = MutableStateFlow(6)
val notificationCount: StateFlow<Int> = _notificationCount
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.krunal.demo.stackexchange.adapters

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.krunal.demo.databinding.ItemPortfolioBinding
import com.krunal.demo.stackexchange.models.ShareDetails

class PortfolioAdapter : RecyclerView.Adapter<PortfolioAdapter.PortfolioViewHolder>() {

private val shareDetailsList: MutableList<ShareDetails> = mutableListOf()

class PortfolioViewHolder(private val binding: ItemPortfolioBinding) :
RecyclerView.ViewHolder(binding.root) {

fun bind(shareDetails: ShareDetails) {
binding.shareDetails = shareDetails
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PortfolioViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ItemPortfolioBinding.inflate(layoutInflater, parent, false)
return PortfolioViewHolder(binding)
}

override fun getItemCount(): Int = shareDetailsList.count()

override fun onBindViewHolder(holder: PortfolioViewHolder, position: Int) {
holder.bind(shareDetailsList[position])
}

@SuppressLint("NotifyDataSetChanged")
fun submitList(list: List<ShareDetails>) {
shareDetailsList.clear()
shareDetailsList.addAll(list)
notifyDataSetChanged()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.krunal.demo.stackexchange.adapters

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.krunal.demo.databinding.ItemShareDetailsBinding
import com.krunal.demo.stackexchange.models.ShareDetails

class ShareDetailsAdapter : RecyclerView.Adapter<ShareDetailsAdapter.ShareDetailsViewHolder>() {

private val shareDetailsList: MutableList<ShareDetails> = mutableListOf()

class ShareDetailsViewHolder(private val binding: ItemShareDetailsBinding) :
RecyclerView.ViewHolder(binding.root) {

fun bind(shareDetails: ShareDetails) {
binding.shareDetails = shareDetails
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShareDetailsViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ItemShareDetailsBinding.inflate(layoutInflater, parent, false)
return ShareDetailsViewHolder(binding)
}

override fun getItemCount(): Int = shareDetailsList.count()

override fun onBindViewHolder(holder: ShareDetailsViewHolder, position: Int) {
holder.bind(shareDetailsList[position])
}

@SuppressLint("NotifyDataSetChanged")
fun submitList(list: List<ShareDetails>) {
shareDetailsList.clear()
shareDetailsList.addAll(list)
notifyDataSetChanged()
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AIReviewRadar

The code changes look good. However, it is recommended to add a newline at the end of the file to follow standard conventions.

Loading