AutoAdapter alternatives and similar packages
Based on the "Adapter" category.
Alternatively, view AutoAdapter alternatives based on common mentions on social networks and blogs.
-
FastAdapter
The bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction... -
SectionedRecyclerViewAdapter
DISCONTINUED. An Adapter that allows a RecyclerView to be split into Sections with headers and/or footers. Each Section can have its state controlled individually. -
Renderers
Renderers is an Android library created to avoid all the boilerplate needed to use a RecyclerView/ListView with adapters. -
SmartRecyclerAdapter
Small, smart and generic adapter for recycler view with easy and advanced data to ViewHolder binding. -
GridListViewAdapters
This library provides GridAdapters(ListGridAdapter & CursorGridAdapter) which enable you to bind your data in grid card fashion within android.widget.ListView, Also provides many other features related to GridListView. -
instant-adapter
DISCONTINUED. Just like instant coffee, saves 78% of your time on Android's Custom Adapters. -
EasyListViewAdapters
This library provides Easy Android ListView Adapters(EasyListAdapter & EasyCursorAdapter) which makes designing Multi-Row-Type ListView very simple & cleaner, It also provides many useful features for ListView. -
Suggestive ๐
DISCONTINUED. An Android UI library that allows easy implementation of (text) input suggestion popup windows. -
MultiLevelAdapter
Android library to allow collapsing and expanding items in RecyclerView's Adapter on multiple levels
SaaSHub - Software Alternatives and Reviews
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of AutoAdapter or a related project?
README
AutoAdapter
This Repository simplifies working with RecyclerView Adapter
Gradle:
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Add dependency to app gradle:
implementation 'com.github.Zuluft:AutoAdapter:v2.4.1'
annotationProcessor 'com.github.Zuluft:AutoAdapter:v2.4.1'
Simple Sample:
Step 1:
Create layout xml file, for example item_footballer.xml which contains TextViews with ids tvName, tvNumber, tvClub and ImageView with id ivDelete
Step 2 (Optional):
create model, that you want to be drawn on above created layout:
public final class FootballerModel {
private final String name;
private final int number;
private final String club;
public FootballerModel(final String name,
final int number,
final String club) {
this.name = name;
this.number = number;
this.club = club;
}
public String getName() {
return name;
}
public int getNumber() {
return number;
}
public String getClub() {
return club;
}
}
Step 3:
Create 'Renderer' class in the following way:
@Render(layout = R.layout.item_footballer,
views = {
@ViewField(
id = R.id.tvName,
name = "tvName",
type = TextView.class
),
@ViewField(
id = R.id.tvNumber,
name = "tvNumber",
type = TextView.class
),
@ViewField(
id = R.id.tvClub,
name = "tvClub",
type = TextView.class
)
})
public class FootballerRenderer{
}
@Render annotation is needed to generate ViewHolder for this Renderer by annotation processor.
Inside @Render annotation layout value is an itemView layout id and @ViewFields are containing information about the views in this layout. Name of the generated ViewHolder will be RendererClassName+'ViewHolder', in this case FootballerRendererViewHolder
Step 4:
Rebuild the project. Rebuilding generates ViewHolder class (FootballerRendererViewHolder), that we use in Step 5.
Step 5:
Extend your FootballerRenderer by Renderer and pass newly generated FootballerRendererViewHolder as a generic type:
@Render(layout = R.layout.item_footballer,
views = {
@ViewField(
id = R.id.tvName,
name = "tvName",
type = TextView.class
),
@ViewField(
id = R.id.tvNumber,
name = "tvNumber",
type = TextView.class
),
@ViewField(
id = R.id.tvClub,
name = "tvClub",
type = TextView.class
)
})
public class FootballerRenderer
extends
Renderer<FootballerRendererViewHolder> {
public final FootballerModel footballerModel;
public FootballerRenderer(final FootballerModel footballerModel) {
this.footballerModel = footballerModel;
}
@Override
public void apply(@NonNull final FootballerRendererViewHolder vh) {
final Context context = vh.getContext();
vh.tvName.setText(footballerModel.getName());
vh.tvClub.setText(footballerModel.getClub());
vh.tvNumber.setText(context.getString(R.string.footballer_number_template,
footballerModel.getNumber()));
}
}
As you see generated FootballerRendererViewHolder has tvName, tvClub, tvNumber fields.
Step 6:
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
mAutoAdapter = AutoAdapterFactory.createAutoAdapter();
mAutoAdapter.addAll(Stream.of(getFootballers()).map(FootballerRenderer::new)
.collect(Collectors.toList()));
mRecyclerView.setAdapter(mAutoAdapter);
}
private List<FootballerModel> getFootballers() {
return Arrays.asList(
new FootballerModel("Luis Suarez", 9, "Barcelona"),
new FootballerModel("Leo Messi", 10, "Barcelona"),
new FootballerModel("Ousmane Dembele", 11, "Barcelona"),
new FootballerModel("Harry Kane", 9, "Tottenham Hotspur"),
new FootballerModel("Dele Alli", 20, "Tottenham Hotspur"),
new FootballerModel("Alexis Sanchez", 7, "Arsenal")
);
}
This line Stream.of(getFootballers()).map(FootballerRenderer::new).collect(Collectors.toList()) converts FootballerModel to
FootballerRenderer using Stream
Mmm... What If I want to have heterogeneous items and layouts inside RecyclerView ?
AutoAdapter's working perfectly with heterogeneous items.
You can add any descedent of Renderer to AutoAdapter, for example it's not a problem to write the following:
...
mAutoAdapter.add(new FootballerRenderer());
mAutoAdapter.add(new BasketballerRenderer());
mAutoAdapter.add(new BoxerRenderer());
....
They all will draw their own layout.
How to add OnClickListener to itemView ?
AutoAdapter has clicks method, it has one required argument Renderer class, one optional argument child view id and returns Rx2 Observable with ItemInfo as generic type. ItemInfo has 3 public final fields: position, renderer, viewHolder.
...
mAutoAdapter.clicks(FootballerRenderer.class)
.map(itemInfo -> itemInfo.renderer)
.map(renderer -> renderer.footballerModel)
.subscribe(footballerModel ->
Toast.makeText(this,
footballerModel.getName(), Toast.LENGTH_LONG)
.show());
...
...
mAutoAdapter.clicks(FootballerRenderer.class, R.id.ivDelete)
.map(itemInfo -> itemInfo.position)
.subscribe(position -> {
mAutoAdapter.remove(position);
mAutoAdapter.notifyItemRemoved(position);
});
...
SortedAutoAdapter Sample:
@Render(layout = R.layout.item_footballer,
views = {
@ViewField(
id = R.id.tvName,
name = "tvName",
type = TextView.class
),
@ViewField(
id = R.id.tvNumber,
name = "tvNumber",
type = TextView.class
),
@ViewField(
id = R.id.tvClub,
name = "tvClub",
type = TextView.class
)
})
public class FootballerOrderableRenderer
extends
OrderableRenderer<FootballerOrderableRendererViewHolder> {
public final FootballerModel footballerModel;
public FootballerOrderableRenderer(final FootballerModel footballerModel) {
this.footballerModel = footballerModel;
}
@Override
public void apply(final FootballerOrderableRendererViewHolder vh) {
final Context context = vh.getContext();
vh.tvName.setText(footballerModel.getName());
vh.tvClub.setText(footballerModel.getClub());
vh.tvNumber.setText(context.getString(R.string.footballer_number_template,
footballerModel.getNumber()));
}
@Override
public int compareTo(@NonNull OrderableRenderer item) {
return Integer.valueOf(footballerModel.getNumber())
.compareTo(getFootballerModel(item).getNumber());
}
private FootballerModel getFootballerModel(@NonNull final OrderableRenderer orderableRenderer) {
return ((FootballerOrderableRenderer) orderableRenderer).footballerModel;
}
@Override
public boolean areContentsTheSame(@NonNull OrderableRenderer item) {
final FootballerModel otherFootballer = getFootballerModel(item);
return footballerModel.getClub().equals(otherFootballer.getClub())
&& footballerModel.getNumber() == otherFootballer.getNumber();
}
@Override
public boolean areItemsTheSame(@NonNull OrderableRenderer item) {
return footballerModel.getName().equals(getFootballerModel(item).getName());
}
}
public class SortedAutoAdapterSampleActivity
extends
AppCompatActivity {
private RecyclerView mRecyclerView;
private SortedAutoAdapter mSortedAutoAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,
LinearLayoutManager.VERTICAL));
mSortedAutoAdapter = AutoAdapterFactory.createSortedAutoAdapter();
mSortedAutoAdapter.clicks(FootballerOrderableRenderer.class)
.map(itemInfo -> itemInfo.renderer)
.map(renderer -> renderer.footballerModel)
.subscribe(footballerModel ->
Toast.makeText(this,
footballerModel.getName(), Toast.LENGTH_LONG)
.show());
mSortedAutoAdapter.clicks(FootballerOrderableRenderer.class, R.id.ivDelete)
.map(itemInfo -> itemInfo.position)
.subscribe(position ->
mSortedAutoAdapter.remove(position));
mSortedAutoAdapter.updateAll(Stream.of(getFootballers())
.map(FootballerOrderableRenderer::new)
.collect(Collectors.toList()));
mRecyclerView.setAdapter(mSortedAutoAdapter);
}
private List<FootballerModel> getFootballers() {
return Arrays.asList(
new FootballerModel("Luis Suarez", 9, "Barcelona"),
new FootballerModel("Leo Messi", 10, "Barcelona"),
new FootballerModel("Ousmane Dembele", 11, "FC Barcelona"),
new FootballerModel("Harry Kane", 9, "Tottenham Hotspur"),
new FootballerModel("Dele Alli", 20, "Tottenham Hotspur"),
new FootballerModel("Alexis Sanchez", 7, "Arsenal")
);
}
}