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
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 looks good to me.

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

@@ -0,0 +1,37 @@
+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
+    }
+}
+
+```


<!-- This is an auto-generated comment by AIReviewRadar -->

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 changes look good. However, there is no documentation provided for the ButtonFragment class and its methods. It would be helpful to add some comments explaining the purpose of the class and how it works. Additionally, it would be good to add some inline comments explaining the purpose of each method and any complex logic within them.

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)
}
}
}
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()
}
}
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 would be better to add a comment explaining the purpose of the ChipFragment class and its functions. Additionally, it is recommended to add error handling in case binding.etChip.text is null when adding a chip.

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)
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

There are no issues with this code change. It simply adds a new Kotlin file CustomViewFragment.kt to the uicomponents package, which extends the Fragment class and sets its layout resource to R.layout.fragment_custom_view.

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

import android.os.Bundle
import android.util.Patterns
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.core.view.children
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.Fragment
import com.google.android.material.textfield.TextInputLayout
import com.krunal.demo.R
import com.krunal.demo.databinding.FragmentEditTextBinding
import com.krunal.demo.uicomponents.extentions.hideKeyboard


class EditTextFragment : Fragment(R.layout.fragment_edit_text) {

private lateinit var binding: FragmentEditTextBinding

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

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

private fun setupListeners() {
binding.root.setOnFocusChangeListener { view, isFocused ->
if (isFocused) view.hideKeyboard()
}

binding.etEmail.setOnFocusChangeListener { emailView, isFocused ->
val email = binding.etEmail.text.toString()
binding.emailContainer.error = if (!isFocused && !isValidEmail(email)) {
"Invalid email address"
} else {
null
}
}

binding.etEmail.addTextChangedListener {
if (it?.length == 0) binding.emailContainer.error = null
}

binding.btnClear.setOnClickListener {
binding.root.children.forEach {
if (it is EditText) {
it.text.clear()
} else if (it is TextInputLayout) {
it.editText?.text?.clear()
}
}
}
}

private fun isValidEmail(email: String): Boolean {
val pattern = Patterns.EMAIL_ADDRESS
return pattern.matcher(email).matches()
}
}
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 its purpose.
  2. Add comments to explain the purpose of each function and listener.
  3. Add a comment to explain the purpose of isValidEmail function.

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

/**
 * A fragment that demonstrates the usage of EditText and TextInputLayout components.
 * This fragment contains an email field with validation and a clear button to reset all fields.
 */
class EditTextFragment : Fragment(R.layout.fragment_edit_text) {

    private lateinit var binding: FragmentEditTextBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View {
        // Inflate the layout for this fragment
        binding = FragmentEditTextBinding.inflate(layoutInflater)
        return binding.root
    }

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

    /**
     * Sets up listeners for various UI components.
     */
    private fun setupListeners() {
        // Hide keyboard when the root view is focused
        binding.root.setOnFocusChangeListener { view, isFocused ->
            if (isFocused) view.hideKeyboard()
        }

        // Validate email address when the email field loses focus
        binding.etEmail.setOnFocusChangeListener { emailView, isFocused ->
            val email = binding.etEmail.text.toString()
            binding.emailContainer.error = if (!isFocused && !isValidEmail(email)) {
                "Invalid email address"
            } else {
                null
            }
        }

        // Clear error message when the email field text changes
        binding.etEmail.addTextChangedListener {
            if (it?.length == 0) binding.emailContainer.error = null
        }

        // Clear all fields when the clear button is clicked
        binding.btnClear.setOnClickListener {
            binding.root.children.forEach {
                if (it is EditText) {
                    it.text.clear()
                } else if (it is TextInputLayout) {
                    it.editText?.text?.clear()
                }
            }
        }
    }

    /**
     * Checks if the given email address is valid.
     *
     * @param email The email address to validate.
     * @return true if the email address is valid, false otherwise.
     */
    private fun isValidEmail(email: String): Boolean {
        val pattern = Patterns.EMAIL_ADDRESS
        return pattern.matcher(email).matches()
    }
}

69 changes: 69 additions & 0 deletions Demo/app/src/main/java/com/krunal/demo/uicomponents/FabFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.krunal.demo.uicomponents

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.google.android.material.snackbar.Snackbar
import com.krunal.demo.R
import com.krunal.demo.databinding.FragmentFabBinding

class FabFragment : Fragment(R.layout.fragment_fab) {

private lateinit var binding: FragmentFabBinding
private var visible: Boolean = false
private lateinit var snackBar: Snackbar

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

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.fabAdd.setOnClickListener {
changeVisibility()
if (visible) snackBar.show()
}
setupExpandableFab()
setupSnackBar()
}

private fun changeVisibility() {
visible = visible.not()
binding.fabAdd.setImageResource(
if (visible) R.drawable.ic_cross
else R.drawable.ic_add
)
binding.fabEdit.visibility = if (visible) View.VISIBLE else View.INVISIBLE
binding.fabImage.visibility = if (visible) View.VISIBLE else View.INVISIBLE
}

private fun setupExpandableFab() {
binding.fabExtended1.isChecked = true
binding.fabExtended2.isChecked = true

binding.fabExtended1.addOnCheckedChangeListener { _, isChecked ->
binding.fabExtended1.isExtended = isChecked
}

binding.fabExtended2.addOnCheckedChangeListener { _, isChecked ->
binding.fabExtended2.isExtended = isChecked
}

binding.fabExtended3.setOnClickListener {
binding.fabExtended3.isExtended = binding.fabExtended3.isExtended.not()
}
}

private fun setupSnackBar() {
snackBar = Snackbar.make(binding.root, "Fab button opened", Snackbar.LENGTH_SHORT)
snackBar.anchorView = binding.fabImage
snackBar.setAction("Close") {
changeVisibility()
}
}
}
Loading