5

I have a Fragment that displays a list of cities with weather informations. I am using a RecyclerView and I am trying to implement the Data Binding Library in my RecyclerView Adapter but for some reason I get this compile error :

> error: cannot find symbol import 
         com.example.zach.weatherapp.databinding.CityListItemBindingImpl;
>                                               ^   
> symbol:   class CityListItemBindingImpl   
> location: package com.example.zach.weatherapp.databinding

It's an auto generated class so i really don't know where the error is. I had the same error previously for other layouts when there was someting wrong in the xml file but here it seems fine.

ForecastAdapter.kt

package com.example.zach.weatherapp.Adapter

import ...

class ForecastAdapter(var myDataset: List<City>) :
    RecyclerView.Adapter<ForecastAdapter.ForecastViewHolder>() {

    var context:Context?=null
    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder.
    class ForecastViewHolder(var binding: CityListItemBinding) : RecyclerView.ViewHolder(binding.root){
        fun bind(city: City){
            binding.city = city
        }
    }


    // Create new views (invoked by the layout manager)
    override fun onCreateViewHolder(parent: ViewGroup,
                                    viewType: Int): ForecastAdapter.ForecastViewHolder {

        context = parent.context
        val layoutIdForListItem = R.layout.city_list_item
        val inflater = LayoutInflater.from(context)
        val shouldAttachToParentImmediately = false

        val binding = DataBindingUtil.inflate<CityListItemBinding>(inflater,layoutIdForListItem,parent,shouldAttachToParentImmediately)
        //val view = inflater.inflate(layoutIdForListItem, parent, shouldAttachToParentImmediately)

        return ForecastViewHolder(binding)
    }

    // Replace the contents of a view (invoked by the layout manager)
    override fun onBindViewHolder(holder: ForecastViewHolder, position: Int) {

        val city = myDataset[position]
        holder.bind(city)

        Glide.with(context)
            .load("http://openweathermap.org/img/w/${city.weather[0].icon}.png")
            .into(holder.binding.forceastImageView)
        holder.binding.container.setOnClickListener{ view: View ->
            Timber.d("Clicked on city %s",city.name)
            Navigation.findNavController(view).navigate(ListFragmentDirections.actionListFragmentToForecastDetailsFragment(city.id))}
    }

    // Return the size of your dataset (invoked by the layout manager)
    override fun getItemCount() = myDataset.size
}

city_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable name="city" type="com.example.zach.weatherapp.data.City"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
       android:orientation="horizontal"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/container">

        <TextView
                tools:text="Caen"
                android:text="@{city.name}"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" android:id="@+id/city_name_textview"
                app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="16dp"
                android:layout_marginTop="16dp" app:layout_constraintTop_toTopOf="parent"
                android:fontFamily="@font/roboto_light" android:textSize="22sp" android:textStyle="bold"
                android:maxLines="1" android:ellipsize="end"/>
        <TextView
                tools:text="Sunny"
                android:text="@{city.weather[0].description}"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/city_forecast_textview" app:layout_constraintStart_toStartOf="parent"
                android:layout_marginStart="16dp"
                app:layout_constraintTop_toBottomOf="@+id/city_name_textview" android:fontFamily="@font/roboto_light"
                android:layout_marginBottom="16dp" app:layout_constraintBottom_toBottomOf="parent"/>
        <ImageView
                android:layout_width="48dp"
                android:layout_height="48dp" app:srcCompat="@drawable/sunny"
                android:id="@+id/forceast_imageView" android:layout_marginTop="8dp"
                app:layout_constraintTop_toTopOf="parent" android:layout_marginBottom="8dp"
                app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.562"
                android:layout_marginEnd="32dp" app:layout_constraintEnd_toStartOf="@+id/temperatures_layout"/>
        <LinearLayout
                android:orientation="vertical"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" android:id="@+id/temperatures_layout"
                app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="16dp" android:layout_marginBottom="8dp"
                app:layout_constraintBottom_toBottomOf="parent" android:layout_marginTop="8dp"
                app:layout_constraintTop_toTopOf="parent">
            <TextView
                    tools:text="15°"
                    android:text="@{city.main.temp_max}"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" android:id="@+id/max_temperature_textview"
                    android:fontFamily="@font/roboto_light"
                    tools:layout_editor_absoluteY="17dp" tools:layout_editor_absoluteX="313dp"/>
            <TextView
                    tools:text="9°"
                    android:text="@{city.main.temp_min}"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/min_temperature_textview"
                    android:fontFamily="@font/roboto_light" tools:layout_editor_absoluteY="45dp"
                    tools:layout_editor_absoluteX="321dp" android:layout_gravity="right"/>
        </LinearLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

It might just be an Android Studio error because the xml file seems fine.

UPDATE : Error seems to come from Xml. I removed the android:text="@{city.xxx}" in my xml layout and instead updated my textViews manually in my ViewHolder bind method like so :

fun bind(boundCity: City){
        with(binding){
            cityNameTextview.text = boundCity.name
            cityForecastTextview.text = boundCity.weather[0].description
            maxTemperatureTextview.text = "${boundCity.main.temp_max}°"
            minTemperatureTextview.text = "${boundCity.main.temp_min}°"

            Glide.with(root.context)
                .load("http://openweathermap.org/img/w/${boundCity.weather[0].icon}.png")
                .into(forceastImageView)

            container.setOnClickListener{ view: View ->
                Timber.d("Clicked on city %s",boundCity.name)
                Navigation.findNavController(view).navigate(ListFragmentDirections.actionListFragmentToForecastDetailsFragment(boundCity.id))}
        }
    }

And I no longer get the error. The error comes whenever I add android:text="@{city.xx}" in my textviews and bind the city variable in the bind method. I still don't know why though....

7
  • clear and rebuild your project or invalidate cache and restart android studio. Commented Feb 5, 2019 at 16:05
  • I did try that but I get the same error anyway Commented Feb 6, 2019 at 13:48
  • You should check this explained answer stackoverflow.com/a/51579759/6891563 Commented Feb 12, 2019 at 12:15
  • I did try that but it didn't solve my problem Commented Feb 16, 2019 at 16:45
  • having same problem, when using two-way databinding but I noticed if I place a data class instead of a viewmodel here than it builds fine Commented Mar 23, 2019 at 21:22

2 Answers 2

0

This should work for you I believe;

class ForecastAdapter(private var myDataset: List<City>) : RecyclerView.Adapter<ForecastAdapter.ForecastViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ForecastAdapter.ForecastViewHolder {
    val itemBinding = CityListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
    return ForecastViewHolder(itemBinding)
}

override fun onBindViewHolder(holder: ForecastViewHolder, position: Int) {
    val city = myDataset[position]
    holder.bind(city)
}

override fun getItemCount() = myDataset.size

inner class ForecastViewHolder(var binding: CityListItemBinding) : RecyclerView.ViewHolder(binding.root){

    fun bind(boundCity: City){
        with(binding) {
        city = boundCity
        Glide.with(root.context)
                .load("http://openweathermap.org/img/w/${city.weather[0].icon}.png")
                .into(forceastImageView)

        container.setOnClickListener { view ->
            Timber.d("Clicked on city %s", city.name)
            Navigation.findNavController(view).navigate(ListFragmentDirections.actionListFragmentToForecastDetailsFragment(city.id))
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I tried your approach but I still get the same error
0

Hey you could try adding the following line after the <data> tag :

<import type="android.view.View" /> 

I found that worked for me when I had that error.

2 Comments

What line and what tag ?
Hey Zach, the edit was way off dont know what happend. But i fixed it. Hope it helps :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.