mrmans0n / smart-adapters Goto Github PK
View Code? Open in Web Editor NEWGeneric and interchangeable Adapters for ListView / RecyclerView done easy
License: MIT License
Generic and interchangeable Adapters for ListView / RecyclerView done easy
License: MIT License
Hello,
I would like to somehow highlight selected items inside my recyclerview.
At the moment I am stuck how to properly notify my BindableRelativeLayout that this position is selected.
Where do you usually store your information about selected items?
Thank you!
@mrmans0n the exception occur when I scroll the listView.something wrong in my code?
my code:
SmartAdapter.empty()
.map(TodoListItem.class, TodoInPreogressListHeader.class)
.map(TodoListItem.class, TodoInProgressListItemView.class)
.builder(new DefaultBindableLayoutBuilder() {
@Override
public Class<? extends BindableLayout> viewType(@NonNull Object item, int position, @NonNull Mapper mapper) {
if (item instanceof TodoListItem) {
TodoListItem todoItem = (TodoListItem) item;
if (todoItem.todo == null) {
return TodoInPreogressListHeader.class;
} else {
return TodoInProgressListItemView.class;
}
} else {
return super.viewType(item, position, mapper);
}
}
})
.into(viewHolder.todoList)
the exception:
java.lang.ArrayIndexOutOfBoundsException: length=2; index=1521438901
at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:6437)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4989)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4193)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:524)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
i proguard-rules.pro file writer
-keep class io.nlopez.smartadapters.* { ; }
-dontwarn io.nlopez.smartadapters.
crash log:
java.lang.RuntimeException: Something went wrong creating the views. Please review your BindableLayout implementation.
at io.nlopez.smartadapters.builders.DefaultBindableLayoutBuilder.build(DefaultBindableLayoutBuilder.java:32)
at io.nlopez.smartadapters.adapters.RecyclerMultiAdapter.onCreateViewHolder(RecyclerMultiAdapter.java:114)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:5228)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4453)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4363)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1961)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1370)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1333)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:562)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2900)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3071)
can you help me~ think you~
Hi there,
While testing the SmartAdapter on API 19, I am getting the error mentioned in the subject right after initialising the Adapter:
SmartAdapter.items(waitingList)
.map(Challenge.class, RunningMultiplayerGamesView.class)
.into(this.listWaitingForPlayer);
The exact stacktrace is:
Process: , PID: 29598
java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
at android.widget.ListView.measureScrapChild(ListView.java:1183)
at android.widget.ListView.onMeasure(ListView.java:1149)
at android.view.View.measure(View.java:16497)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
at android.view.View.measure(View.java:16497)
at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1226)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.widget.ScrollView.onMeasure(ScrollView.java:326)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291)
at android.view.View.measure(View.java:16497)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1916)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1113)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1295)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:544)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
What I think is that for Api < 19 (not confirmed though, have only tested with API 22+ and it works) FrameLayout can't be cast correctly to AbsListView params. So my guess that somewhere in the AdapterCode we need to apply
setLayoutParams(new AbsListView.LayoutParams(100,100));
What do you think?
Thank you
We want to extract the adapter common methods to a common interface and add some flag for automatically reload the adapter after an insertion, so it can be disabled (right now it's hardcoded) for solving problems like #7.
It is stated in the README that you setting a map between model and view is not necessary when you pass your own implementation of BindableLayoutBuilder but it is not true:
But if I add some dummy mapping to bypass this exception the problem is then a different one: The different type of cells (views) are mixed when they are reused:
Consider your own example:
Adapter:
SmartAdapter.items(myObjectList)
.map(Tweet.class, TweetView.class)
.into(myListView);
BindableLayoutBuilder:
public class TweetBindableLayoutBuilder implements BindableLayoutBuilder {
@Override
public BindableLayout build(ViewGroup parent, Mapper mapper, Class aClass, Object item) {
// parent = the parent, Mapper = object -> view mapper defined in the SmartAdapters invocation
// aClass = current model (item) class, item = current object
Tweet tweet = (Tweet) item;
if (tweet.hasGallery()) {
return new TweetGalleryView(parent.getContext());
} else if (tweet.hasImage()) {
return new TweetImageView(parent.getContext());
} else if (tweet.hasEmbeds()) {
return new TweetEmbedView(parent.getContext());
} else {
return new TweetView(parent.getContext());
}
}
}
Then, inside the RecyclerView adapter method getItemViewType we have:
public int getItemViewType(int position) {
if (listItems == null) {
return 0;
}
Object object = listItems.get(position);
return mapper.position(object.getClass());
}
As the mapper will get position 0 for the class Tweet, all the cells will be considered the same so the build method of the TweetBindableLayoutBuilder could not be called a TweetImageView is needed because it reused another one, which can be of any (undesired) type like TweetView or TweetGalleryView
with SmartAdapter how can change cell size ( custom LayoutMangager ) in RecyclerView by itemViewType ?
thanks
hi Nacho Lopez
do you plan to implement data binding features in this library ?
thanks
In proguard mode, its throwing error
Something went wrong creating the views. Please review your BindableLayout implementation. at io.nlopez.smartadapters.builders.DefaultBindableLayoutBuilder.build(Unknown Source) at io.nlopez.smartadapters.adapters.RecyclerMultiAdapter.onCreateViewHolder(Unknown Source) at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(Unknown Source) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(Unknown Source) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(Unknown Source)
Folllowed this https://github.com/mrmans0n/smart-adapters/issues/22 link and it didn't work out.
Proguard file:
`-keep class io.nlopez.smartadapters.** { *; }
-dontwarn io.nlopez.smartadapters.*
-keep class *.itemView.{ *;}`
Android ArrayIndexOutOfBoundsException and AbsListViewRecycleBin.addScrapView
java.lang.ArrayIndexOutOfBoundsException: length=2; index=894640594
Mapper.viewTypeFromViewClass(builder.viewType(object, position, mapper))
RecyclerView.Adapter.getItemId()
/**
* Return the stable ID for the item at <code>position</code>. If {@link #hasStableIds()}
* would return false this method should return {@link #NO_ID}. The default implementation
* of this method returns {@link #NO_ID}.
*
* @param position Adapter position to query
* @return the stable ID of the item at position
*/
public long getItemId(int position) {
return NO_ID;
}
RecyclerMultiAdapter.getItemId is not extensible
@Override
public long getItemId(int position) {
return position;
}
When add listener in ListView or RecyclerView,we cannot show reveal effect in 5.0+ ,or selector effect in each item...u can see this problem in ur sample app
Have you ever see this exception?
java.lang.IllegalArgumentException: Object class class java.util.ArrayListnot found in mapper
at io.nlopez.smartadapters.builders.DefaultBindableLayoutBuilder.viewType(DefaultBindableLayoutBuilder.java:40)
atio.nlopez.smartadapters.adapters.RecyclerMultiAdapter.getItemViewType(RecyclerMultiAdapter.java:134)
In README.md,
public class TweetBindableLayoutBuilder extends DefaultBindableLayoutBuilder {
@Override
public int viewType(@NonNull Object item, int position, Mapper mapper) {
if (item instanceof Tweet.class) {
Tweet tweet = (Tweet) item;
if (tweet.hasGallery()) {
return Mapper.viewTypeFromViewClass(TweetGalleryView.class);
} else if (tweet.hasImage()) {
return Mapper.viewTypeFromViewClass(TweetImageView.class);
} else if (tweet.hasEmbeds()) {
return Mapper.viewTypeFromViewClass(TweetEmbedView.class);
}
}
// With this fallback we return control for all the other cases to be handled as the default use.
return super(item, position, mapper);
}
}
should be
public class TweetBindableLayoutBuilder extends DefaultBindableLayoutBuilder {
@Override
public int viewType(@NonNull Object item, int position, Mapper mapper) {
if (item instanceof Tweet) {
Tweet tweet = (Tweet) item;
if (tweet.hasGallery()) {
return Mapper.viewTypeFromViewClass(TweetGalleryView.class);
} else if (tweet.hasImage()) {
return Mapper.viewTypeFromViewClass(TweetImageView.class);
} else if (tweet.hasEmbeds()) {
return Mapper.viewTypeFromViewClass(TweetEmbedView.class);
}
}
// With this fallback we return control for all the other cases to be handled as the default use.
return super.viewType(item, position, mapper);
}
}
Thanks again for this great library :)
This log shows as many times as the itemView's number. But my app is still running normally in debug mode. In release mode its very slow..
ViewGroup: addInArray been called, this = android.support.v7.widget.RecyclerView{41fde8b8 VFED.... .F....ID 0,42-444,849 #7f090033 app:id/recyclerView}call stack = java.lang.Throwable: addInArray at android.view.ViewGroup.addInArray(ViewGroup.java:3786) at android.view.ViewGroup.attachViewToParent(ViewGroup.java:4349) at android.support.v7.widget.RecyclerView.access$1300(Unknown Source) at android.support.v7.widget.RecyclerView$5.attachViewToParent(Unknown Source) at android.support.v7.widget.ChildHelper.attachViewToParent(Unknown Source) at android.support.v7.widget.RecyclerView$LayoutManager.addViewInt(Unknown Source) at android.support.v7.widget.RecyclerView$LayoutManager.addView(Unknown Source) at android.support.v7.widget.RecyclerView$LayoutManager.addView(Unknown Source) at android.support.v7.widget.GridLayoutManager.layoutChunk(Unknown Source) at android.support.v7.widget.LinearLayoutManager.fill(Unknown Source) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(Unknown Source) at android.support.v7.widget.GridLayoutManager.onLayoutChildren(Unknown Source) at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(Unknown Source) at android.support.v7.widget.RecyclerView.dispatchLayout(Unknown Source) at android.support.v7.widget.RecyclerView.onLayout(Unknown Source)
how to fix?
Right now we have to deal with BindableLayout being a FrameLayout, so if we want to optimize the views created we are very limited in what we can do. It's a performance hog if we want our custom view to be a linear layout for instance, we would get FrameLayout > LinearLayout > your other stuff, having there a dumb view polluting our ui.
We should be able to have BindableFrameLayout, BindableLinearLayout, BindableRelativeLayout, etc which all implement a common BindableLayout interface. This way we would be able to add new view container types even from outside the library.
I want to add a Boolean getter for the builders so we can query if they allow object class to multiple view class mapping. This way we can fail fast if the library is being used wrong, and five instant meaningful errors.
Is it possible to implement a BindableLayoutBuilder where the view class of an item depends on the item position in the adapter instead of its data?
I tried to return different layout id's when overriding BindableLayout.getLayoutId() but it didn't work (due to viewholders' recycling, I guess) and can't find the way to get the position from the BindableLayoutBuilder.
Thanks for the lib, so useful :)
first of all, thanks for rapid bug fixing
can you add animation when item is visible in adapter ?
you can give idea from this library :
thanks
when i use custom itemAnimator, i must use notifyItemInserted
and notifyItemRemoved
instead of notifyDataSetChanged
in adapter, in smart adapter how can do it ?
thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.