Can't use kotlin-extension in Adapter - android

Android Studio 3.6
build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: "kotlin-kapt"
android {
dataBinding {
enabled = true
}
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.myproject"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
Now in Activity I can use this:
import kotlinx.android.synthetic.main.event_details_activity.*
class EventDetailsActivity : AppCompatActivity() {
private lateinit var dataBinding: EventDetailsActivityBinding
companion object {
val EVENT = EventDetailsActivity.javaClass.canonicalName + "_EVENT"
private val TAG = EventDetailsActivity::class.java.name
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dataBinding =
DataBindingUtil.setContentView(this, R.layout.event_details_activity)
// THIS WORK FINE
eventTitleTextView.text = "Test"
Nice.
Now I want to use Kotlin extension in Adapter.
I try this:
import kotlinx.android.synthetic.main.event_list_item.*
class EventAdapter(
context: Context?,
data: List<*>?
) : DataBindingRecyclerViewAdapter(context, data) {
private var listener: AdapterListener? = null
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder,
position: Int
) {
super.onBindViewHolder(holder, position)
descriptionTextView.text = "TEST"
}
Here event_list_item.xml
<TextView
android:id="#+id/descriptionTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#{model.description}"
android:textColor="#android:color/darker_gray"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#+id/titleTextView"
app:layout_constraintStart_toStartOf="#+id/titleTextView"
app:layout_constraintTop_toBottomOf="#+id/titleTextView" />
java file:
public abstract class DataBindingRecyclerViewAdapter extends RecyclerView.Adapter {
But I get error:
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public val Activity.descriptionTextView: TextView! defined in kotlinx.android.synthetic.main.event_list_item
public val Dialog.descriptionTextView: TextView! defined in kotlinx.android.synthetic.main.event_list_item
public val android.app.Fragment.descriptionTextView: TextView! defined in kotlinx.android.synthetic.main.event_list_item
public val androidx.fragment.app.Fragment.descriptionTextView: TextView! defined in kotlinx.android.synthetic.main.event_list_item

I have the same problem and i solved it by add this into gradle build file
androidExtensions {
experimental = true
}

Related

Why does it still say "Unresolved reference: button" even when I have button id in xml?

I have simple android app, and I want to click button to pass other activity. But it says
Unresolved reference: button
even I give id in xml. I do not know where I mistake.
Screenshot:
activity_main.xml:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button"
android:text="Click"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
main_activity:
class MainActivity : AppCompatActivity() {
companion object {
const val USER = "user"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val user = User( "mayk", "qqqq", PersonalInfo("mayk", "james"))
button.setOnClickListener{
val intent = Intent (this, Activity2::class.java)
intent.putExtra(USER, user)
startActivity(intent)
}
}
}
val button = findViewById<View>(R.id.button)
why still say “Unresolved reference: button” even I have button id in xml?
The ids in your xml layout files are not Kotlin variables. You need to declare a variable val button before you can use it. You also need to initialize the variable to refer to a Button object. One way to do that is with
val button = findViewById<View>(R.id.button)
I suggest that you read the beginner guides at https://d.android.com to understand the fundamentals of Android programming.
No need to use findViewById()
Go to your Build.Gradle (Module: app)
Add the following line
apply plugin: 'kotlin-android-extensions'
or
id 'kotlin-android-extensions'
Then it will ask you to sync
Then press sync
After it will ask you to import that only by using ALT+ENTER
UPDATE : THIS SOLUTION IS DEPRECATED
now you have to use View Binding
set the viewBinding build option to true in the module-level build.gradle file
android {
...
buildFeatures {
viewBinding true
}
}
To set up an instance of the binding class for use with an activity, perform the following steps in the activity's onCreate() method:
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
You can now use the instance of the binding class to reference any of the views:
binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
For more information you can have a look at https://developer.android.com/topic/libraries/view-binding

Why does Kotlin Activity have a problem finding Buttons?

Attempting to update an older Android game project to use view binding. Android Studio version 4.1.3. I am thinking my problem has to do with the naming of my binding class.
the xml file is called activity_correct_guess.xml and I am using what I think is the name that gets generated by the view binding: ActivityCorrectGuessBinding. Appreciate and ideas!
The build errors:
Unresolved reference: ActivityCorrectGuessBinding
Unresolved reference: binding
Unresolved reference: binding
In the Gradle build module I have the following:
android {
compileSdkVersion 30
buildToolsVersion "30.0.0"
buildFeatures {
viewBinding = true
}
layout file: activity_correct_guess.xml
<Button
android:id="#+id/btnPlayAgain"
android:layout_width="wrap_content"
..... />
Activity file: CorrectGuessActivity.kt
class CorrectGuessActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityCorrectGuessBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
playAgain()
exitGame()
}
fun playAgain() {
binding.btnPlayAgain.setOnClickListener {
val intent = Intent("com.appkotlin2021v4.MainActivity")
startActivity(intent)
}
}
Typically, you define your view binding in the root of your Activity or Fragment or in an init block:
class CorrectGuessActivity : AppCompatActivity() {
//get to inflating!
private val binding = ActivityCorrectGuessBinding.inflate(layoutInflater)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
playAgain()
exitGame()
}
fun playAgain() {
binding.btnPlayAgain.setOnClickListener {
val intent = Intent("com.appkotlin2021v4.MainActivity")
startActivity(intent)
}
}
The only time you need to "wait to inflate" is when you're in a non-ViewGroup-based class like RecyclerView.Adapter, etc.
Yes, this is the correct way to define the view binding. thank you!

RecyclerView.Adapter , glide onLoadFailed` or `onResourceReady` not called and image is not show

Android studio 3.6
build.gradle:
android {
dataBinding {
enabled = true
}
// Configure only for each module that uses Java 8
// language features (either in its source code or
// through dependencies). E.g. lambda expressions.
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.project.client"
minSdkVersion 23
targetSdkVersion 29
versionCode 80
versionName "0.0.80"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
// use e.g. in my custom RecyclerView.Adapter
//apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'io.fabric'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
Here my RecyclerView adaptder:
class GazStationAdapter(newActivity: Activity, private val data: List<String>) :
RecyclerView.Adapter<GazStationAdapter.ViewHolder>() {
var activity: Activity? = null
init {
this.activity = newActivity
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val v = inflater.inflate(R.layout.gazstation_item_service_card, parent, false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val serivceURL = "http://www.gravatar.com/avatar/11111?s=40x40&d=identicon"
Debug.d("TAG", "onBindViewHolder: serivceURL = $serivceURL")
Glide.with(holder.itemView.context)
.load(serivceURL)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
Debug.d("TAG", "onBindViewHolder: glide_load_onLoadFailed")
return false;
}
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
Debug.d("TAG", "onBindViewHolder: glide_load_ready")
return false
}
})
.placeholder(R.drawable.profile)
.into(holder.image)
}
override fun getItemCount(): Int {
return data.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val image: ImageView
init {
image = itemView.findViewById<View>(R.id.gazStaionServiceimage) as ImageView
}
}
}
here gazstation_item_service_card.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_margin="4dp"
android:orientation="vertical">
<ImageView
android:id="#+id/gazStaionServiceimage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
</LinearLayout>
But image not load by url
Here logcat:
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
W Glide : Failed to find GeneratedAppGlideModule. You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler in your application and a #GlideModule annotated AppGlideModule implementation or LibraryGlideModules will be silently ignored
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
D TAG : onBindViewHolder: serivceURL = http://www.gravatar.com/avatar/11111?s=40x40&d=identicon
as you can see the methods onLoadFailed or onResourceReady NOT CALLED. The placeholder R.drawable.profilesuccess show.
If you have config apply plugin kotlin-kapt you have to also replace these line to gradle:
annotationProcessor 'com.github.bumptech.glide:compiler:[version]'
should be replaced by
kapt 'com.github.bumptech.glide:compiler:[version]'

Android Parcelable for Kotlin is not working

I am trying to pass data from one fragment to another but I am facing issue with sending data from parcelable from one fragment to another.
class MainFragment : Fragment() {
companion object {
public val KEY_PARSE_DATA = "parseData"
}
private var parseData: ParseData? = null
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater!!.inflate(R.layout.fragment_main, container, false).apply {
val editName = findViewById(R.id.edit_Name) as EditText
val editSurname = findViewById(R.id.edit_Surname) as EditText
val buttonNext = findViewById(R.id.btn_Next) as Button
buttonNext.setOnClickListener(View.OnClickListener {
val fragment = AnotherFragment()
if (parseData != null) {
var parseData = ParseData(editName.text.toString(), editSurname.text.toString())
val fragment = AnotherFragment()
val bundle = Bundle()
bundle.putParcelable(KEY_PARSE_DATA, parseData)
fragment.setArguments(bundle)
fragmentManager.beginTransaction().add(R.id.fragment_container, fragment).commitAllowingStateLoss()
}
})
}
}
}// Required empty public constructor
Parcelable class for implementing it
#SuppressLint("ParcelCreator")
#Parcelize
data class ParseData(val firstName: String, val lastName: String) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString()) {
}
override fun toString(): String {
return "ParseData(firstName='$firstName', lastName='$lastName')"
}
companion object : Parceler<ParseData> {
override fun ParseData.write(parcel: Parcel, flags: Int) {
parcel.writeString(firstName)
parcel.writeString(lastName)
}
override fun create(parcel: Parcel): ParseData {
return ParseData(parcel)
}
}
}
And another fragment which grab data from parcelable class in android
class AnotherFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater!!.inflate(R.layout.fragment_another, container, false).apply {
val textName = findViewById<TextView>(R.id.textFirst)
val textSurname = findViewById<TextView>(R.id.textSecond)
val bundle = arguments
if (bundle != null) {
val parseData = bundle.getParcelable<ParseData>(KEY_PARSE_DATA)
textName.setText(parseData.firstName)
textSurname.setText(parseData.lastName)
}
}
}
}
I tried some example but I cant get clear idea how parcelable is implemented in andoid application based on kotlin and build.gradle file
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.assignment.ankitt.kotlinsecond"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
androidExtensions {
experimental = true
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:support-v4:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
Add below code into your App Level gradle.
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
androidExtensions {
experimental = true
}
Now it is enough to add 'kotlin-parcelize' plugin.
So for example:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-parcelize'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
//
androidExtensions {
experimental = true
}
}
The order of plugin matters. kotlin-android must be before kotlin-android-extension. Then clean project.
Unable to add kotlin android extension
I'd recommend taking a look at the #Parcelize annotation provided with the Kotlin Android Extensions, it generates all necessary boilerplate for you so you don't have to write and maintain that code yourself.
Need to add these two in your app level Gradle
apply plugin: 'kotlin-android-extensions'
androidExtensions {
experimental = true`
}
Kotlin plugin should be enabled before 'kotlin-android-extensions'
so change the order to
apply plugin: 'com.android.application' #1
apply plugin: 'kotlin-android' #2
apply plugin: 'kotlin-android-extensions' #3
Hello All I had solved this question and there was issue with fragment transaction and parcelable
MainActivity to setup fragment
class MainActivity : AppCompatActivity() {
val manager = supportFragmentManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fragment = DetailFragment()
manager.findFragmentById(R.id.fragmentContainer)
manager.beginTransaction().add(R.id.fragmentContainer, fragment).commit()
}
}
First fragment to fill data
class DetailFragment : Fragment(), View.OnClickListener {
var editTextName: EditText? = null
var editTextLast: EditText? = null
var buttonNextFragment: Button? = null
var firstName: String? = null
var lastName: String? = null
companion object {
val KEY_PARSE_DATA = "detailData"
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view: View = inflater!!.inflate(R.layout.fragment_detail, container, false)
editTextName = view.findViewById(R.id.ed_firstName) as EditText
editTextLast = view.findViewById(R.id.ed_lastName) as EditText
buttonNextFragment = view.findViewById(R.id.btn_nextfragment) as Button
buttonNextFragment!!.setOnClickListener(this)
return view
}
override fun onClick(v: View?) {
firstName = editTextName!!.text.toString()
lastName = editTextLast!!.text.toString()
Toast.makeText(context, firstName, Toast.LENGTH_SHORT).show()
// val viewFragment = ViewFragment()
// val transaction = fragmentManager.beginTransaction()
// transaction.replace(R.id.fragmentContainer, viewFragment)
// transaction.commit()
var details = Details(firstName!!, lastName!!)
val viewFragment = ViewFragment()
val bundle = Bundle()
bundle.putParcelable(KEY_PARSE_DATA, details)
viewFragment.setArguments(bundle)
val transaction = fragmentManager.beginTransaction()
transaction.replace(R.id.fragmentContainer, viewFragment)
transaction.commit()
}
}
Display data coming from parcelable
class ViewFragment : Fragment() {
var textViewName: TextView? = null
var textViewLastName: TextView? = null
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view: View = inflater!!.inflate(R.layout.fragment_view, container, false)
textViewName = view.findViewById(R.id.text_name_another) as TextView
textViewLastName = view.findViewById(R.id.text_surname_another) as TextView
val bundle = arguments
if (bundle != null) {
val details = bundle.getParcelable<Details>(KEY_PARSE_DATA)
textViewName!!.setText(details.firstName)
textViewLastName!!.setText(details.lastName)
}
return view
}
}
Model class for implementation of parcelable
#Parcelize
class Details(val firstName: String, val lastName: String) : Parcelable
and my gradle file
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.assignment.ankitt.kotlintwo"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
androidExtensions {
experimental = true
}
}

kotlin 'onCreate' overrides nothing

I am using component development, in my common module BaseActivity.kt and BaseFragment.kt. The following problems occur when other modules inherit them
> D:\Android\OneDaily\module_main\src\main\java\com\boco\main\MainActivity.kt
> Error:(7, 24) Unresolved reference: base
> Error:(9, 22) Unresolved reference: BaseActivity
> Error:(21, 5) 'onCreate' overrides nothing
> Error:(17, 5) 'getLayoutRes' overrides nothing
> Error:(22, 15) Unresolved reference: onCreate
> Error:(27, 22) Unresolved reference: findViewById
> Error:(42, 34) Unresolved reference: supportFragmentManager
> D:\Android\OneDaily\module_main\src\main\java\com\boco\main\TimelineFragment.kt
> Error:(7, 24) Unresolved reference: base
> Error:(10, 5) 'getLayoutRes' overrides nothing
> Error:(9, 26) Unresolved reference: BaseFragment
> Error:(14, 5) 'onCreateView' overrides nothing
> Error:(15, 22) Unresolved reference: onCreateView
BaseActivity.kt:
abstract class BaseActivity : AppCompatActivity() {
init {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
}
abstract fun getLayoutRes(): Int
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(getLayoutRes())
}
}
MainActivity.kt
class MainActivity : BaseActivity() {
private lateinit var mBottomNav: BottomNavigationView
private var mFragment1 = TimelineFragment() as Fragment
private var mFragment2 = TimelineFragment() as Fragment
private var mFragment3 = TimelineFragment() as Fragment
override fun getLayoutRes(): Int {
return R.layout.activity_main
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
It seems some functions have changed in the last update,
just remove the '?' from the Bundle
Like this:
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
}
It can happen also in a Fragment class: I found the same issue for the method onCreateView; to avoid that, just remove the ? from the LayoutInflater parameter,
Like this:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
I have to add "?" when using appcompat-v7:27.1.1
implementation "com.android.support:appcompat-v7:27.1.1
and
override fun onCreate(savedInstanceState : Bundle?){
super.onCreate(savedInstanceState)
}
Update function signatures or revert to compileSdk from 27 to 26
i have fixed this problem. The because of it is you don't config you common module. Please add two lines code at your common module's build.gradle top:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
hope this can help you.

Categories

Resources