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
15 changes: 14 additions & 1 deletion 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 {
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

This patch adds the kotlin-kapt plugin to the list of plugins in the build.gradle file.

The kotlin-kapt plugin is used for Kotlin annotation processing. It generates code based on annotations in your Kotlin code, which can be used for tasks such as dependency injection and database access.

There are no potential issues or errors with this change.

Expand Down Expand Up @@ -32,13 +33,25 @@ android {
kotlinOptions {
jvmTarget = '17'
}

buildFeatures {
viewBinding true
dataBinding true
}
}

dependencies {

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.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
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'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
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

This patch adds some new dependencies to the dependencies section of the build.gradle file.

  • androidx.constraintlayout:constraintlayout:2.1.4: This is the ConstraintLayout library, which provides a flexible layout manager for Android apps.

  • androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version: This is the ViewModel component of the Android Architecture Components library. It allows you to store and manage UI-related data in a lifecycle-conscious way.

  • androidx.fragment:fragment-ktx:1.5.7: This is the Fragment component of the AndroidX library. It provides a way to modularize your app's UI into reusable pieces.

  • androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version: This is the LiveData component of the Android Architecture Components library. It allows you to observe changes to data in a lifecycle-conscious way.

  • androidx.core:core-splashscreen:1.0.1: This is the SplashScreen API, which provides a standard way to show a splash screen in your app.

  • androidx.preference:preference-ktx:1.2.0: This is the Preference component of the AndroidX library. It provides a way to manage user preferences in your app.

There are no potential issues or errors with this change.

Expand Down
14 changes: 12 additions & 2 deletions Demo/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@
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:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Demo"
tools:targetApi="31" />
android:theme="@style/Theme.App.Starting"
tools:targetApi="31">
<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>
</application>
</manifest>
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
}
}
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()
}
}
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, there are a few things to consider:

  1. The installSplashScreen() method is only available in Android 12 and higher. If the minimum SDK version of the app is lower than 31, this method call will cause a runtime error on devices running Android versions lower than 12.

  2. The setupTheme() method sets the activity theme based on the current accent color. This may not be desirable if the app allows users to change the accent color at runtime. In that case, the theme should be set dynamically whenever the accent color changes.

  3. The setupFragment() method replaces the container view with a CoordinatorLayoutFragment. It may be useful to add some logic to determine which fragment to show based on user input or other factors.

  4. It's generally a good practice to include a newline at the end of the file.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.krunal.demo.uicomponents

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment
import com.google.android.material.color.MaterialColors
import com.krunal.demo.R
import com.krunal.demo.databinding.FragmentAppBarBinding
import com.krunal.demo.uicomponents.extentions.getThemeColor

class AppBarFragment : Fragment(R.layout.fragment_app_bar) {

private lateinit var binding: FragmentAppBarBinding

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
binding = FragmentAppBarBinding.inflate(layoutInflater)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupAppBars()
}

private fun setupAppBars() {
binding.tbItems.inflateMenu(R.menu.toolbar_menu)
val searchItem = binding.tbSearch.menu.findItem(R.id.miSearch)
val searchView = searchItem.actionView as SearchView
searchView.isIconified = false
}
}
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, there are a few things to consider:

  1. It's always a good practice to add a newline at the end of the file.
  2. The getThemeColor extension function is not used in this file. If it's not being used anywhere else in the project, it can be removed to reduce unnecessary code.

Other than that, the code looks good and should work as expected.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.krunal.demo.uicomponents

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.children
import androidx.fragment.app.Fragment
import com.google.android.material.button.MaterialButton
import com.krunal.demo.R
import com.krunal.demo.databinding.FragmentButtonBinding

class ButtonFragment : Fragment(R.layout.fragment_button), OnClickListener {

private lateinit var binding: FragmentButtonBinding

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
binding = FragmentButtonBinding.inflate(layoutInflater)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupClickListener()
}

override fun onClick(view: View?) {
(view as? MaterialButton)?.let {
Toast.makeText(requireContext(), "${it.text} clicked", Toast.LENGTH_SHORT).show()
}
}

private fun setupClickListener() {

binding.btnNormal.setOnClickListener(this)
binding.btnBordered.setOnClickListener(this)
binding.appCompatButton.setOnClickListener(this)
binding.btnDisabled.setOnClickListener(this)
binding.btnOutlined.setOnClickListener(this)
binding.btnText.setOnClickListener(this)
binding.imgBtnImage.setOnClickListener(this)
binding.btnInfo.setOnClickListener(this)
binding.btnGradient.setOnClickListener(this)

binding.switchEnable.setOnCheckedChangeListener { btn, checked ->
binding.root.children
.filterNot { it == binding.switchEnable }
.forEach { it.isEnabled = checked }
btn.text =
if (checked) getString(R.string.enabled_switch) else getString(R.string.disabled_switch)
}
}
}
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 looks good.

Please add a newline at the end of the file to follow standard conventions.

@@ -34,3 +34,4 @@ class ButtonFragment : Fragment(R.layout.fragment_button), OnClickListener {
         }
     }
 }
+

Reply with "OK" if you have made the changes.

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.krunal.demo.uicomponents

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
import android.widget.CompoundButton.OnCheckedChangeListener
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.krunal.demo.R
import com.krunal.demo.databinding.FragmentCheckboxBinding

class CheckboxFragment : Fragment(R.layout.fragment_checkbox), OnCheckedChangeListener {

private lateinit var binding: FragmentCheckboxBinding
private var selectedLanguages = mutableListOf<String>()

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
binding = FragmentCheckboxBinding.inflate(layoutInflater)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListeners()
}

private fun setupListeners() {
selectedLanguages.add("English")
selectedLanguages.add("Hindi")
binding.cbEnglish.setOnCheckedChangeListener(this)
binding.cbHindi.setOnCheckedChangeListener(this)
binding.cbGujarati.setOnCheckedChangeListener(this)
binding.cbSpanish.setOnCheckedChangeListener(this)
binding.btnSaveChanges.setOnClickListener {
Toast.makeText(requireContext(), selectedLanguages.joinToString(), Toast.LENGTH_SHORT)
.show()
}
}

override fun onCheckedChanged(btn: CompoundButton?, isChecked: Boolean) {
val language = when (btn) {
binding.cbEnglish -> "English"
binding.cbHindi -> "Hindi"
binding.cbGujarati -> "Gujarati"
binding.cbSpanish -> "Spanish"
else -> ""
}
if (isChecked) {
selectedLanguages.add(language)
} else {
selectedLanguages.remove(language)
}
}
}
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, there are a few things that can be improved in the documentation:

  1. Add a brief description of what this fragment does and how it fits into the app.
  2. Add comments to explain the purpose of selectedLanguages and how it is used.
  3. Add comments to explain the purpose of setupListeners() and how it sets up the listeners for the checkboxes.
  4. Add comments to explain the purpose of onCheckedChanged() and how it updates the list of selected languages.

Here's an example of how the documentation could be improved:

/**
 * Fragment that displays a list of checkboxes for selecting languages.
 * The selected languages are stored in a list and can be retrieved by calling
 * `selectedLanguages`.
 */
class CheckboxFragment : Fragment(R.layout.fragment_checkbox), OnCheckedChangeListener {

    // List of selected languages
    private var selectedLanguages = mutableListOf<String>()

    ...

    /**
     * Sets up the listeners for the checkboxes and initializes the list of selected languages.
     */
    private fun setupListeners() {
        selectedLanguages.add("English")
        selectedLanguages.add("Hindi")
        binding.cbEnglish.setOnCheckedChangeListener(this)
        binding.cbHindi.setOnCheckedChangeListener(this)
        binding.cbGujarati.setOnCheckedChangeListener(this)
        binding.cbSpanish.setOnCheckedChangeListener(this)
        binding.btnSaveChanges.setOnClickListener {
            Toast.makeText(requireContext(), selectedLanguages.joinToString(), Toast.LENGTH_SHORT)
                .show()
        }
    }

    /**
     * Called when the state of a checkbox changes.
     * Updates the list of selected languages based on the state of the checkbox.
     */
    override fun onCheckedChanged(btn: CompoundButton?, isChecked: Boolean) {
        val language = when (btn) {
            binding.cbEnglish -> "English"
            binding.cbHindi -> "Hindi"
            binding.cbGujarati -> "Gujarati"
            binding.cbSpanish -> "Spanish"
            else -> ""
        }
        if (isChecked) {
            selectedLanguages.add(language)
        } else {
            selectedLanguages.remove(language)
        }
    }
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.krunal.demo.uicomponents

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.Fragment
import com.google.android.material.chip.Chip
import com.krunal.demo.R
import com.krunal.demo.databinding.FragmentChipBinding

class ChipFragment : Fragment(R.layout.fragment_chip) {

private lateinit var binding: FragmentChipBinding

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentChipBinding.inflate(layoutInflater)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupChips()
}

private fun setupChips() {
binding.etChip.addTextChangedListener {
binding.tilChip.isEndIconVisible = binding.etChip.text.isNullOrEmpty().not()
}

binding.etChip.setOnEditorActionListener { _, _, _ ->
addChip()
true
}

binding.tilChip.setEndIconOnClickListener {
addChip()
}
}

private fun addChip() {
val chip = Chip(requireContext())
chip.text = binding.etChip.text
chip.setOnCloseIconClickListener { binding.cgProgrammatically.removeView(it) }
chip.setCloseIconResource(R.drawable.ic_cross)
chip.isCloseIconVisible = true
binding.cgProgrammatically.addView(chip)
binding.etChip.text?.clear()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.krunal.demo.uicomponents

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import com.google.android.material.behavior.SwipeDismissBehavior
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import com.krunal.demo.databinding.FragmentCoordinatorLayoutBinding

class CoordinatorLayoutFragment : Fragment() {

private lateinit var binding: FragmentCoordinatorLayoutBinding

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
binding = FragmentCoordinatorLayoutBinding.inflate(layoutInflater)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupUI()
}

private fun setupUI() {
setupSnackBar()
}

private fun setupSnackBar() {
binding.btnSwipeableSnackBar.setOnClickListener {
Snackbar.make(requireView(), (it as Button).text, Snackbar.LENGTH_LONG).apply {
behavior = BaseTransientBottomBar.Behavior()
animationMode = BaseTransientBottomBar.ANIMATION_MODE_SLIDE
behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_ANY)
show()
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.krunal.demo.uicomponents

import androidx.fragment.app.Fragment
import com.krunal.demo.R

class CustomViewFragment : Fragment(R.layout.fragment_custom_view)
Loading