I am trying to find last item position in recycler view in Kotlin.But could not find same method or property in Kotlin like in java.
Int lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();//JAVA
If mLayoutManager contains findLastVisibleItemPosition() "in java" then you definitely can also call in Kotlin.
One thing I would suggest you is to check if mLayoutManager is of type LinearLayoutManager (or if you cast it), since RecyclerView.LayoutManager doesn't have method findLastVisibleItemPosition()
Related
In my project with kotlin and tornadofx, I want to extend the JavaFx Combobox class, adding new property which will be used for storing specialized row items.
My code...
1. data class MsItemsClass(val id: String, val description: String)
2. var javafx.scene.control.ComboBox<String>.extItems: ObservableList<MsItemsClass> = emptyList<MsItemsClass>()
get() = this.extItems
at line 2. compiler put the error "Kotlin: Initializer is not allowed here because this property has no backing field"
Well, but I cannot know how resolve the problem.
Can enyone help me?
I'm new to the Kotlin programming language. I have some questions regarding RecyclerView and ViewBinding. My English might not be good. I am sorry for that. But I will do my best to explain. I would love it if you could answer my questions. Please read the questions, looking the images
1.) We give the view to the constructor of the LandmarkHolder class. But when we send this view to the constructor of the RecyclerView.ViewHolder class, we make binding.root.
a) As far as I know, I need to write the object of RecyclerViewRowBinding (which I wrote as binding) in the constructor of Recycler.ViewHolder "in the same way" and send it there. But why do I have to write binding.root instead of "binding"? Why can't I just type "binding"? Because binding already has the design itself.
2.) While making a Layout Inflater, we normally access the XML file with the old method (R.layout. ....) and inflate it, that is, convert it to java code. The structure here has changed. Of course, it is converted to java code again, but there is a confused situation that I could not solve:
A class of the recycler_row.xml file is created called RecyclerRowBinding.
This class has an inflate method. I read from its website. In addition, this class directly references the ids of the views in the layout that are related to it. Now the thing that's stuck in my head is this: What am I inflating here? Because in the old usage (with finviewbyid), when we wrote the inflate method, we were adding a source xml file inside the iflate method.(Like CardView) But this new method does not have it. After the parent is written, attachtoParent is written as False.
3.)What we call this parent represents my RecyclerView?
4.) The holder object in the onBindViewHolder function belongs to the Landmarkholder class. So it uses properties of this class. But I see that it can access something called itemView. Here is how ItemView can relate to the Landmarkholder class. But I'm looking at the class itself, nothing related to this itemView is defined. How does this reach the itemView? Of course, the purpose of calling itemview is to call context. If the context exists in it, then the itemview also derives from another class. Does it derive from the View class? and the View class has this context I guess is it right? How can I call this itemView with "holder" object?
5.) This onCreateViewHolder returns the LandmarkHolder(binding) object. Then this function needs to be called elsewhere for it to work. (Normally it should be called, of course) Butwhere is it called from? On the emulator itself?
RecyclerViewAdapterRecycler_row.xmlMainActivity.xml
Why isn't the binding itself a view?
I didn't understand all your questions, but maybe this overview will help.
ViewBinding takes each of your XML layouts and creates a binding class for them that is comprised of properties matching each view that has an ID, plus one more property named root that holds the top-level view. It also has static functions called bind and inflate. So if you have a layout like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
<TextView
android:id="#+id/recyclerRowTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Test"
android:textColor="#0820aa"
android:textSize="20sp" />
</LinearLayout>
Then it creates a class that's the equivalent of this (in Java but I'll show a Kotlin version since that's what you're learning):
class RecyclerRowBinding private constructor(
val root: LinearLayout,
val recyclerRowTextView: TextView
) {
companion object {
fun bind(view: View): RecyclerRowBinding {
val root = view as LinearLayout
val recyclerRowTextView = root.findViewById<TextView>(R.id.recyclerRowTextView)
return RecyclerRowBinding(root, recyclerRowTextView)
}
fun inflate(layoutInflater: LayoutInflater): RecyclerRowBinding {
return inflate(layoutInflater, null, false)
}
fun inflate(layoutInflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean): RecyclerRowBinding {
val root = layoutInflater.inflate(R.layout.recycler_row, parent, attachToParent)
return bind(root)
}
}
}
I didn't exactly understand your questions, but a couple things to notice:
It's still inflating your views from XML with a LayoutInflater like you would if you were doing it without view binding.
The binding itself is not a view class. It only holds references to views.
The RecyclerView.ViewHolder abstract class's constructor requires an itemView object, which is the root view of the item layout, so you must pass binding.root to this constructor. The binding itself is not the view. RecyclerView.ViewHolder also has a property for this itemView, so when you create your own view holder that has a binding, there are two different ways to access the root view, either by using holder.binding.root or holder.itemView. However, binding.root will be of type LinearLayout, and itemView will be the less specific ViewGroup.
Adapter.onCreateViewHolder() is called by RecyclerView when it needs another view to display and doesn't have any previous views that it can recycle.
I want to have a window which shows info about certain ViewModel
Suppose you have a simple Person:
class Person(name: String) {
val nameProperty = SimpleStringProperty(name)
}
and have instance of Person save in property:
val personProperty = SimpleObjectProperty(Person("John"))
what's the correct solution to show Person's name in label?
Using this:
label(personProperty.value.nameProperty)
Will not update when I update the property's person:
personProperty.value = Person("Joe")
(That's obvious because only the reference changes, not the value itself)
So is there any good way to do this or do I have to manually add listeners for personProperty and update which Person does label point to?
EDIT:
I also found this question: JavaFX binding and property change, but it doesn't contain anything new and useful that I didn't know about, is there any TornadoFX-specific way of doing this?
This is exactly what the ItemViewModel does for you. If you want to make a binding for the name property that updates automatically, outside of an ItemViewModel, you can use the TornadoFX feature select:
val nameProperty = personProperty.select { it.nameProperty }
A listener can be attached to the property:
personProperty.onChange {
it?.nameProperty.let(nameLabel.textProperty().bind)
}
This can be wrapped in extension function to simplify the task.
As title says:
I´d like to change the text inside an editText with a button click.
I can do it with TextViews by using this code:
TextView.text= "new text here"
but it doesnt work for EditText
I already tried something like this:
editText.setText("new text here")
Can some one please tell me the equivalent code for editTexts?
this is my code so far:
dialog.setOnClickListener {
var builder = AlertDialog.Builder(this)
var inflater: LayoutInflater = layoutInflater
var view : View = inflater.inflate(R.layout.dialog,null)
builder.setView(view)
builder.setTitle("categories")
builder.setPositiveButton("Ver", { dialogInterface: DialogInterface, i: Int ->
mainscreen.visibility = View.GONE
ListView.visibility = View.VISIBLE
listdogs.visibility=View.VISIBLE
listdogs.adapter = adapterdogs
editText?.setText("husky")
})
Regards
You need editText?.setText("new text here") or editText!!.setText("new text here") if you are sure that this EditText is not null.
This is happening because java getter setter ambiguous in case of EditText, To understand this scenario you first need to understand that how kotlin generate the properties from java class for kotlin.
Kotlin official
Methods that follow the Java conventions for getters and setters (no-argument methods with names starting with get and single-argument methods with names starting with set) are represented as properties in Kotlin. Boolean accessor methods (where the name of the getter starts with is and the name of the setter starts with set) are represented as properties which have the same name as the getter method.
But in case EditText, which inherits setter from TextView creating problem here.
When a setter comes into play, property generation process becomes ambiguous. The reason is that the getter and the setter may have different types. Moreover, the getter and/or the setter may be overridden in a subclass,
which exactly is the case of EditText in Android.
It means that you can get an Editable for an EditText and set an Editable to an EditText. Therefore, Kotlin reasonably creates a synthetic property text of type Editable. Considering that the String Class is not editable, I cannot assign a String instance to the text property of the EditText class.
Original source https://medium.com/cashify-engineering/how-does-kotlin-generated-property-from-java-getters-and-setters-undocumented-by-jetbrains-7e1ad88052b1
I want to press key combination and get the fully qualified class name where the caret is at right now. I have deleloped a plugin but it required me to move the caret on to the class name.
PsiElement element = (PsiElement) e.getDataContext().getData("psi.Element");
element instanceof PsiClass {
PsiClass className = element;
}
How do I get the class name when I press my key combination when the caret is in somewhere in the class ?
You can use PsiTreeUtil.getParentOfType to find the parent class like this:
PsiClass stmt = PsiTreeUtil.getParentOfType(element, PsiClass.class);
Where element is the PsiElement currently under the caret (it seems you already know how to find it).
See the source code of PsiTreeUtil for more info.