Please i would like a detailed explanation on what an inner class does what happens in this specific instance. If i dont type out the inner in an inner class of recycleview. calling notifyDataSetChanged() throws an error like this
But if i type inner in front of the ViewHolder Class. The notifyDataSetChanged() error clears
A nested class marked as inner can access the members of its outer class.
Here the class ViewHolder is nested in the class TimeAdapter. So it need to be marked as inner to access to the function "notifyDataSetChanged" of the class TimeAdapter
kotlin inner classes have access to outer class that's why you can call notifyDataSetChanged() method of RecyclerViewAdapter. If you don't make it inner class it doesn't have access to outer class and you can't call outer class method.
Inner make the inner class access the outer class methods
Bek answered you
https://stackoverflow.com/a/65219384/8139353
but i have a simple note about notifyDataSetChanged()
you must avoid using it if you want to update a specific rows
you must use notifyItemChanged(layoutPosition)
this function update only the row you updating
and if you had updated more than one row
you can use notifyItemRangeChanged(layoutPosition, 5)// position and items count
there are many fuctions to use it in adapter like notifyItemRemoved(layoutPosition)
Related
I had Android Studio convert my code for an OnClickListener.
Obviously a lambda is used here. What I don't know is whether the lambda is passed to a function of the View class or to the constructor of the OnClickListener class.
I have already looked in the Android documentation for a method with the name OnClickListener in the View class but found nothing.
If the latter is the case, I don't understand how an instance of the OnClickListener class can be created even though it is an interface.
val onClickListener = View.OnClickListener { refreshListView() }
The class OnClickListener is an inner class of the View class:
https://developer.android.com/reference/android/view/View.OnClickListener
Inner classes are identified by a '.' in their classname, on byte code level they are separated with a '$' instead.
With the invocation as written in your question you create an anonymous class implementing the functional interface and implementing its onClick(View) method. You can do the same in Java with a bit more verbose syntax, but technically the same.
I'm trying to delete a note from a Room Database by calling a method when the user long clicks
on the note, I set up the onLongClickListener on the RView adapter:
viewHolder.itemView.setOnCLickListener{
NotesFragment().deleteSingleNote(notesID)
}
On NotesFragment, the method looks like:
fun deleteSingleNote(notesID: Long) {
notesFragmentViewModel.deleteSingleNoteFromDB(notesID)
}
and on the ViewModel the method deletes the note through a coroutine.
The app crashes on long click, saying that the lateinit notesFragmentViewModel had not been initializing, pointing to the onLongCLickListener line, and NotesFragment line I pasted above.
The thing is, the notes are populated on the screen through a NotesFragmentViewModel LiveData variable which contains all the notes, so the ViewModel is very much initialized by the time I long click on the item.
I tried initializing the ViewModel on the adapter, but I got an exception related to ViewModel not being allowed tobe instantialized on something other than a fragment/activity.
This is my first post on SOverflow, so please let me know if I did anything wrong
Inside the OnClickListener you want to access the NotesFragment instance which is currently displayed. But with NotesFragment() you create a new instance of NotesFragment. Since it will not be attached to any Activity it's very likely that the notesFragmentViewModel property of the new instance has not been initialized.
So to avoid an Exception you have to access the correct instance of NotesFragment. You could introduce a parameter of type NotesFragment to the constructor of the RecyclerView.Adapter, but this is considered bad practice.
It's better to let the adapter class have an interface (let's call it ListItemClickedListener) and a constructor which requires an instance of ListItemClickedListener as parameter.
interface ListItemClickedListener{
fun singleNoteLongClicked(notesID: Long)
}
Then you can have either NotesFragment implement ListItemClickedListener and pass itself to the adapter or you use an anonymous local instance of ListItemClickedListener.
Inside the adapter:
viewHolder.itemView.setOnCLickListener{
listItemClickListener.singleNoteLongClicked(notesID)
}
In NotesFragment:
override fun singleNoteLongClicked(notesID: Long){
this#NotesFragment.deleteSingleNote(notesID)
}
See for example this post for an implementation of this pattern.
I know JAVA's generic concept = type
and Android's Recycler View concept.
I already know this -> extends RecyclerView.Adapter. have seen from the Android developer site.
But, this is still difficult to understand.
I was looking at Firebase's Cloud Firestore code.
And some codes...
extends FirestoreAdapter<SomeClassAdapter.ViewHolder>
and
public abstract class FirestoreAdapter<VH extends RecyclerView.ViewHolder>
extends RecyclerView.Adapter<VH>
these concepts are so difficult for me...
some generics and something extends in there.
I've done a lot of searches and I've done a lot of thinking. Can you explain easily, please?? or some sites to refer.
Thanks for reading! any kind of tip does not matter. I`ll appreciate!
Perhaps it would be easier to understand if I explain this with an example:
Assume we have an adapter class named SomeClassAdapter which has an inner class called ItemViewHolder as below:
public class SomeClassAdapter extends FirestoreAdapter {
...
private class ItemViewHolder extends FirestoreAdapter.ViewHolder {
...
}
}
If we want to extend SomeClassAdapter using the inner class (ItemViewHolder) as our view holder we would use:
public class Example extends FirestoreAdapter<SomeClassAdapter.ItemViewHolder>
But the second concept you mentioned is the super class which we extend in our example (it's abstract and we have to extend it and override its abstract methods in order to make an instance)
Now assume we have a class which requires a type to use it across the class declaration. In that case we declare a class like FirestoreAdapter and pass the generic type inside <..> like: FirestoreAdapter<VH>. In case we need our VH to be a sub type of another class like RecyclerView.ViewHolder we declare it as: FirestoreAdapter<VH extends RecyclerView.ViewHolder>.
And what if we need our FirestoreAdapter itself to be a sub type of another class such as RecyclerView.Adapter? So it would be FirestoreAdapter<VH extends RecyclerView.ViewHolder>
extends RecyclerView.Adapter. In our example the RecyclerView.Adapter class needs a generic type extending RecyclerView.ViewHolder itself and we want to use the same type we used for FirestoreAdapter<VH> here so we simply pass VH as our generic type for RecyclerView.Adapter. And to come into a conclusion we'll have:
FirestoreAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH>
Immediate translation.
Translated to human speak we get this, The generic FirestoreAdapter will only except parameterized types of ViewHolder or its subclasses. Finally it will inherit all of the available fields from its super class, which is the generic class RecyclerView.Adapter
Proof and documentation is down below.
< VH extends RecyclerView.ViewHolder >
This is part is utilizing Bounded Type Parameters
Why use Bounded Type Parameters?
Well the documentation states:
There may be times when you want to restrict the types that can be used as type arguments in a parameterized type.
Before we move on it is important that we define type type arguments and parameterized type
What are type arguments?
As stated in the documentation :
Many developers use the terms "type parameter" and "type argument" interchangeably, but these terms are not the same. When coding, one provides type arguments in order to create a parameterized type.
We can then map this definition over to our code to understand that our own CustomAdapter.ViewHolder acts as a type arguments . Now we can move on.
What is a parameterized type?
Well the Documentation states
We can think of parameterized types as formal instantiations of our type arguments To instantiate this class, use the new keyword, as usual, but place between the class name and the parenthesis:
Box integerBox = new Box();
What is < VH extends RecyclerView.ViewHolder > doing?
The documentation states :
To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound
Now type parameters are simply anything that goes inside the angle brackets <>. Source
With that being said we can come to the conclusion that VH is nothing more that a type parameter and extends RecyclerView.ViewHolder is saying that our generic class only accepts ViewHolder objects or its subclasses.
Conclusion
public abstract class FirestoreAdapter
extends RecyclerView.Adapter
translates to, The generic FirestoreAdapter will only except parameterized types of ViewHolder or its subclasses. Finally it will inherit all of the available fields from its super class which is the generic class RecyclerView.Adapter
I am getting below compilation error
Realm model classes must either extend RealmObject or implement
RealmModel to be considered a valid model class
In this particular scenario
class Animals extends RealmObject {
}
class Dog extends Animals {
}
I am getting this error for the Dog class.
That error appears when I am indirectly extending RealmObject. i.e Dog is extending Animals (which in turns extends RealmObject), not RealmObject directly.
Inheritance / Polymorphism is still an open issue in Realm,
Check this link https://github.com/realm/realm-java/issues/761
While the issue has not been closed yet, it is recommended to use composition instead of inheritance: F.ex. you could have
public interface Animalistic {
makeNoise();
}
which is then implemented by each animal.
This question already has answers here:
Extending from two classes
(13 answers)
Closed 9 years ago.
I want to extend two library class files in a java class.How to do this.
You have not given more details about the question.
You can only extend a single class. And implement interfaces from many sources.
Extending multiple classes is not available.
You can use nested classes or inner classes
class A extends B {
private class C extends D {
// A , B , C , D accessible here
}
}
Why Use Nested Classes?
Compelling reasons for using nested classes include the following:
It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.
It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.
It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.
when to use nested classes
You can find more solutions on this link
Edit
This is an answer to you comment. You want to call method of outer class in inner class. This is an example.
class Outer {
void show() {
System.out.println("inside outter show");
}
class Inner{
void show() {
Outer.this.show(); //this is calling Outer class method into Inner class
Example e = new Example(); //create object of another class
e.show(); //call to method
System.out.println("inside inner show");
}
}
public static void main(String[] args) {
Outer o = new Outer();
Inner i = o.new Inner(); //create an object of Inner class
i.show(); //this is calling Inner class method from outside method
}
}
class Example
{
void show()
{
System.out.println("inside example show");
}
}
Output:
inside outter show
inside example show
inside inner show
Unfortunately in JAVA you can only extend a single class that means each Class can only extend one class. you can implement many interfaces but not extend.
however there are ways in which you can sort of surpass it, you can just make the libs public and then include them so you could create an instance and use their functions, you can create an inner class and use it for whatever purposes you need...
you can also create a chain of extension like:
public class A extends Activity
public class B extends A
so B will extend both...sort of
its hared to give you a working solution when we dont exactly know the issue,do you mean adding support libs? adding SDK? or really extending two classes (which is impossible straight forward).
#Aniket gave you an example of how to work around it so to speak...
hope I helped
sorry for the bad news:)