I would use a RecyclerView
with a custom adapter to achieve this result, depending on how advanced each item can be. If it's simple interaction and design, eg icon
, text
and maybe a click listener
then it's good enough.
If it's anything more advanced, many different types of actions that can be preformed by each button, then maybe you could just go with a LinearLayout
and generate each button with their specific action.
If you would rather generate the buttons, scroll to the bottom for an example
Assuming that you want to use a RecyclerView
, then it could look something like this:
You could have an adapter item looking something like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/padding_view_small">
<ImageView
android:id="@+id/icon"
android:layout_width="25dp"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_person_black_24dp"/>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/placeholder"
android:textColor="@color/black"
android:layout_marginStart="@dimen/padding_view_small"
android:layout_marginLeft="@dimen/padding_view_small"/>
</LinearLayout>
Your adapter
public class MyAdapter extends RecyclerView.Adapter
{
private Context _context;
private List<MyObject> _items;
public void setItems(List<MyObject> items)
{
this._items = items;
notifyDataSetChanged();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
_context = parent.getContext();
return new MyAdapter.ItemViewHolder(parent);
}
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position)
{
final MyAdapter.ItemViewHolder viewHolder = (MyAdapter.ItemViewHolder) holder;
final MyObject item = _items.get(position);
viewHolder._icon.setImageResource(item.getIcon());
viewHolder._name.setText(item.getText());
}
@Override
public int getItemCount()
{
return _items != null ? _items.size() : 0;
}
private static class ItemViewHolder extends RecyclerView.ViewHolder
{
private ImageView _icon;
private TextView _text;
private ItemViewHolder(ViewGroup parent)
{
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_layout, parent, false));
this._icon = itemView.findViewById(R.id.icon);
this._text = itemView.findViewById(R.id.text);
}
}
}
MyObject class for storing information about each button
public class MyObject
{
private int _icon;
private String _text;
public MyObject(int icon, String text)
{
this._icon = icon;
this._text = text;
}
public int getIcon()
{
return this._icon;
}
public int getText()
{
return this._text;
}
}
Then you could also maybe directly pass a ClickListener
to the MyObject
, or you can also add an additional variable called Type
so that you know what to do when a user clicks a specific type.
Generating buttons without a RecyclerView
You can have a basic LinearLayout
view holder that's gonna hold all the views.
<LinearLayout
android:id="@+id/action_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
Method for generating views
private View generateView(int icon, String text)
{
LayoutInflater inflater = LayoutInflater.from(_context);
View view = inflater.inflate(R.layout.adapter_layout, null);
ImageView icon = view.findViewById(R.id.icon);
icon.setImageResource(icon);
TextView text = view.findViewById(R.id.text);
text.setText(text);
return view;
}
Dynamically adding new views
View showDialogView = generateView(ContextCompat.getDrawable(_context, R.drawable.test), "Show dialog");
//Here you can set a click listener to what should happen when you click the item
showDialogView.setOnClickListener....
linearLayout.addView(showDialogView);