udacity / andfun-kotlin-color-my-views

Other
30 stars 49 forks source link

Unresolved reference: box_one_text #11

Open abdullaiahmed opened 3 years ago

abdullaiahmed commented 3 years ago

Unresolved reference: box_one_text

on the Lesson 2: Layouts

  1. Exercise: Add Aligned Boxes with Click Handlers

I'm working on the Android Studio 4.1.1

cdenney0921 commented 3 years ago

I am also having the same issue in 4.1.1, I have tried a few of the studio's suggested actions but not sure where to go from here. Android studio is throwing an unresolved reference on the listOf items.

`package com.example.colormyviews

import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.graphics.Color import android.view.View

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setListeners() }

private fun setListeners() {
    val clickableViews: List<View> =
            listOf(box_one_text, box_two_text, box_three_text,
                    box_four_text, box_five_text, constraint_layout)

    for (item in clickableViews) {
        item.setOnClickListener {makeColored(it)}
    }
}

fun makeColored(view: View) {
    when (view.id) {

        // Boxes using Color class colors for background
        R.id.box_one_text -> view.setBackgroundColor(Color.DKGRAY)
        R.id.box_two_text -> view.setBackgroundColor(Color.GRAY)

        // Boxes using Android color resources for background
        R.id.box_three_text -> view.setBackgroundResource(android.R.color.holo_green_light)
        R.id.box_four_text -> view.setBackgroundResource(android.R.color.holo_green_dark)
        R.id.box_five_text -> view.setBackgroundResource(android.R.color.holo_green_light)

        else -> view.setBackgroundColor(Color.LTGRAY)
    }
}

}`

TheCodingArcher commented 3 years ago

Edited on 08/05/2021 : THIS IS NOT THE CORRECT OR EFFICIENT SOLUTION

@abdullaiahmed @cdenney0921 Add this in your app level Gradle:

plugins { id 'kotlin-android-extensions' }

and rebuild.

dacitsme commented 3 years ago

@TheCodingArcher

kotlin-android-extensions is under deprecation period.

View binding, which is part of Android Jetpack, is the replacement for it. You can follow this link to understand how view binding works: https://developer.android.com/topic/libraries/view-binding#kotlin

alfredbwong commented 3 years ago

@TheCodingArcher

kotlin-android-extensions is under deprecation period.

View binding, which is part of Android Jetpack, is the replacement for it. You can follow this link to understand how view binding works: https://developer.android.com/topic/libraries/view-binding#kotlin

This is what worked for me. Re-visit the About Me app lessons and follow same steps to do the data binding to views.

dacitsme commented 3 years ago

@alfredbwong it's nice to know that you were able to apply the concept you learnt in the previous lesson to solve this problem.

In android, there are two similar things called data binding and view binding. For this lesson, view binding seems more suitable than data binding.

You can find the differences here: https://stackoverflow.com/questions/58040778/android-difference-between-databinding-and-viewbinding

piyush-one commented 3 years ago

@abdullaiahmed , I did the old fashioned (inefficient but probably o.k for the purposes of this exercise) way: `private fun setListeners() { val listId: List = listOf( R.id.box_one_text, R.id.box_two_text, R.id.box_three_text, R.id.box_four_text, R.id.box_five_text )

    for (item in listId) {
        findViewById<View>(item).setOnClickListener { makeColored(it) }
    }
}`
seifer9almasy commented 3 years ago

To use viewBinding do as below:

buildFeatures { viewBinding true }

private lateinit var binding: ActivityMainBinding

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) val view = binding.root setContentView(view) setListeners() }

private fun setListeners() { val clickableViews : List = listOf(binding.boxOneText, binding.boxTwoText, binding.boxThreeText, binding.boxFourText, binding.boxFiveText, binding.contraintLayout) for (item in clickableViews){ item.setOnClickListener { makeColored(it) } } }



the rest of the code stay the same
snjgit commented 3 years ago

I also found I had to change R.id.red_button -> box_three_text. to R.id.red_button -> binding.boxThreeText.....

TheCodingArcher commented 3 years ago

@dacitsme @alfredbwong - Thank you for correcting me 👍

@seifer9almasy @snjgit - Thank you for the hints you guys have shown 👍

preveenraj commented 3 years ago

I think this would be a good solution: (Using databinding)


package com.example.colormyviews

import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.databinding.DataBindingUtil
import com.example.colormyviews.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        setListeners()
    }

    private fun setListeners() {
        val clickableViews: List<View>
        binding.apply {
            clickableViews = listOf(boxOneText, boxTwoText, boxThreeText, boxFourText, boxFiveText, constraintLayout)
        }
        clickableViews.forEach { view ->
            view.setOnClickListener { makeColored(it) }
        }
    }

    private fun makeColored(view: View) {
        when (view.id) {
            // Boxes using Color class colors for background
            R.id.box_one_text -> view.setBackgroundColor(Color.DKGRAY)
            R.id.box_two_text -> view.setBackgroundColor(Color.GRAY)
            // Boxes using Android color resources for background
            R.id.box_three_text -> view.setBackgroundResource(android.R.color.holo_green_light)
            R.id.box_four_text -> view.setBackgroundResource(android.R.color.holo_green_dark)
            R.id.box_five_text -> view.setBackgroundResource(android.R.color.holo_green_light)
            else -> view.setBackgroundColor(Color.LTGRAY)
        }
    }
}
alexjorgef commented 3 years ago

I think this would be a good solution: (Using databinding)

package com.example.colormyviews

import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.databinding.DataBindingUtil
import com.example.colormyviews.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        setListeners()
    }

    private fun setListeners() {
        val clickableViews: List<View>
        binding.apply {
            clickableViews = listOf(boxOneText, boxTwoText, boxThreeText, boxFourText, boxFiveText, constraintLayout)
        }
        clickableViews.forEach { view ->
            view.setOnClickListener { makeColored(it) }
        }
    }

    private fun makeColored(view: View) {
        when (view.id) {
            // Boxes using Color class colors for background
            R.id.box_one_text -> view.setBackgroundColor(Color.DKGRAY)
            R.id.box_two_text -> view.setBackgroundColor(Color.GRAY)
            // Boxes using Android color resources for background
            R.id.box_three_text -> view.setBackgroundResource(android.R.color.holo_green_light)
            R.id.box_four_text -> view.setBackgroundResource(android.R.color.holo_green_dark)
            R.id.box_five_text -> view.setBackgroundResource(android.R.color.holo_green_light)
            else -> view.setBackgroundColor(Color.LTGRAY)
        }
    }
}

@preveenraj code seems to be the correct way to use data binding. Make sure you enable data binding on your buid.gradle module file:

android {

    ...

    dataBinding {
        enabled = true
    }
}
schapira commented 3 years ago

Edited on 08/05/2021 : THIS IS NOT THE CORRECT OR EFFICIENT SOLUTION

@abdullaiahmed @cdenney0921 Add this in your app level Gradle:

plugins { id 'kotlin-android-extensions' }

and rebuild.

I would like to understand why its works? what's the magic?

monojk commented 2 years ago

@abdullaiahmed , I did the old fashioned (inefficient but probably o.k for the purposes of this exercise) way: `private fun setListeners() { val listId: List = listOf( R.id.box_one_text, R.id.box_two_text, R.id.box_three_text, R.id.box_four_text, R.id.box_five_text )

    for (item in listId) {
        findViewById<View>(item).setOnClickListener { makeColored(it) }
    }
}`

This worked for me the best. The other solutions either used the deprecated kotlin-android-extensions or have a different project structure (path android included)

karencfisher commented 2 years ago

Following up to piyush-one's suggestion, a simpler (if less efficient) working solution:

private fun setListeners() {
        val clickableViews: List<Int> =
            listOf(R.id.box_one_text, R.id.box_two_text, R.id.box_three_text,
                   R.id.box_four_text, R.id.box_five_text)

        for (item in clickableViews) {
            findViewById<View>(item).setOnClickListener { makeColored(it) }
        }
    }

    private fun makeColored(view: View) {
        when (view.id) {

            // Boxes using Color class colors for background
            R.id.box_one_text -> view.setBackgroundColor(Color.DKGRAY)
            R.id.box_two_text -> view.setBackgroundColor(Color.GRAY)

            // Boxes using Android color resources for background
            R.id.box_three_text -> view.setBackgroundResource(android.R.color.holo_green_light)
            R.id.box_four_text -> view.setBackgroundResource(android.R.color.holo_green_dark)
            R.id.box_five_text -> view.setBackgroundResource(android.R.color.holo_green_light)

            else -> view.setBackgroundColor(Color.LTGRAY)
        }
    }

I have to add, alas, that winding up having to debug a lot of the code given in the course material is becoming tedious. (Though I suppose I am learning even more in the process?) I suspect, of course, that the issues arise from later versions of Android Studio. I am finding a lot of such discrepancies. Maybe its time for the course to be updated!

Is it possible to make pull requests with such fixes? We can, of course, try to be useful rather than grumpy. ;)

SudKul commented 2 years ago

Not enough details to replicate the issue. Though, we have upgraded the master branch to use AndroidX in this commit.

We recommend you use the https://knowledge.udacity.com/ platform to discuss individual issues with our experienced mentors and submit a PR to help others avoid facing the same issue.

I am intentionally keeping this thread open.

lionyouko commented 2 years ago

Yeah, it doesn't matter for me the solutions given. I would like to know why exactly that worked in the video, but when you try to make the list of views, it says those names don't exist. Nothing was said before about data biding for this project, so much that it does not use data biding in OnCreate. I would like two know why it works there in their Android Studio.

haneesh-bandaru commented 1 year ago

https://github.com/Haneesh05/colormyviews

go through this repo I have completed the code and it is running perfectly good.

DarkOhms commented 1 year ago

I know there are multiple ways to solve this problem. It is just a bit disturbing to me that this is considered the solution code and it doesn't work.