2

What is the most efficient way to show model field information in an activity? Just like below picture for example, do they manually make each fields using View groups(LinearLayout, RelativeLayout, ConstraintLayout), or do they produce this using a RecyclerView? If this was made using a RecyclerView, how is this achievable?

Image

UPDATE(If we're using RecyclerView):
-Thank you for the replies, I think you guys are right,I should use LinearLayout if I want to achieve just like in picture sample. But in my case, I have a lot of data, 50 fields, and I dont want to manually make 1 ViewGroup for each field. With my example, I would only be using 4 fields for my User Model, and these items are purely for viewing, no other viewtypes and no specific functions.

User Model fields:
-Name
-Age
-Gender
-Address

I want each user field as an item in a recyclerview, but since my UserModel is not a List, I wouldnt be able to fed it to the RecyclerView. Below picture is what I want to achieve. Sorry If my problem is a bit ambiguous, I'm having a hard time explaining my problem.

I want to achieve

Boomiyaah
  • 23
  • 4
  • imho RecyclerView – Vadim Eksler Nov 08 '18 at 07:06
  • It is possible, using `RecyclerView` with different `viewType` but i would recommend doing it as nested views. – jbmcle Nov 08 '18 at 07:22
  • If you want to create it using RecyclerView with multiple ViewType. Here is the relevant link https://stackoverflow.com/questions/26245139/how-to-create-recyclerview-with-multiple-view-type/51153083#51153083 – Rohit Singh Nov 08 '18 at 07:28
  • @RohitSingh Thank you for the response, that would solve partially my problem, the problem is what kind of List would I feed the recyclerview? Can I loop inside a model with each fields? For example, I have 3 fields in a model [Name, Age, Address], how to make 1 model field for 1 recyclerview item? Thank you. – Boomiyaah Nov 08 '18 at 07:35
  • @Boomiyaah You're right you need to use `List` and check every instance in a switch `Cat instanceof Animal` and so on. – jbmcle Nov 08 '18 at 07:40
  • @Boomiyaah I did not understand what are exactly asking ? Please update your question with Your Model class and the problem. So that we have a better understanding – Rohit Singh Nov 08 '18 at 07:48
  • @jake the recyclerview iterates per item, for example, I have a Cat Model with fields [Name, Color, Age]. I want each recyclerview item per Cat field, just like in the picture example, I want 1 ViewGroup/line for the name with an icon, 1 Viewgroup/line for the Color with an icon, etc. Sorry, if my question is a bit confusing, I am having a hard time in explaining my problem haha – Boomiyaah Nov 08 '18 at 07:52
  • 1
    Welcome to StackOverflow! In my opinion a RecyclerView with n different viewTypes would be overkill. It's not like you'll have more than 20 items even when your model increases a LOT and each will have a different function (call a number, start navigation, etc.). I'd go with a manual implementation of each element inside a LinearLayout. – Oliver Metz Nov 08 '18 at 07:54
  • I agree with @OliverMetz . If you want exactly what is in the screenshot. Better create it with LinearLayout and make a View for item and include then using – Rohit Singh Nov 08 '18 at 07:58
  • I believe this Layout can easily be achieved using `Linear Layout` (vertical and horizontal). You shouldn't go for `RecylcerView` that wasn't good for this case – Ali Ahmed Nov 08 '18 at 08:00
  • @Boomiyaah you should use RecyclerView when you've many views of the same type, which can be recycled by the system: for instance 100 views scrollable, 50 of type A and 50 of type B, so that when they go out of screen, the memory allocated for the layout (the view) can be recycled by the system, and not destroyed. So, not this case. In this case I would use a LinearLayout with many different view types, and then give responsability to each type to know what to do; that is, I would abstract the view types a little bit to have common actions and interactions – Alessio Nov 08 '18 at 08:01
  • @OliverMetz , rohit singh, ali ahmed, thank you for the response! I think you are right, I should it it manully if I have different view type for items. However, I have 50 fields of data, and I dont want to manually create each ViewGroups. I have updated my question, I hope I make some sense, because I'm really having a hard time in explaining my question haha – Boomiyaah Nov 08 '18 at 08:35
  • Its just 4 items.what are the 50 different items? Is it like repetitive ? 10 users and 4 fields so 10*4 = 40 items ? – Rohit Singh Nov 08 '18 at 09:29
  • @RohitSingh What I meant is that in my actual project, I have 50 fields of data per model that's why I dont want to manually use LinearLayour for my items. I'm using the UserModel as an example for simplification. Sorry for the misunderstanding. – Boomiyaah Nov 08 '18 at 09:36

2 Answers2

0

As you have explained me in the comments.

  • You have a Model class USER which has 50 fields.
  • And if the items look like as they are in Screenshot.

If this is the case, it can be easily solved with Simple RecyclerView without even using ViewType

Your ItemView has a logo, a title, and a description.

1) Create a new Model for items of the List.

class ListItem{

   int logo;
   int title;
   int desc;

   // write getter and setter

}

2) Populate list?

Get data from User Model and convert it to ListItem Model
Lets say that first item is Name of the user.
Do like this

 ListItem username = new ListItem();
   username.setTitle("NAME");
   username .setLogo(R.id.userLogo);
   username.setDesc(user.name);

Lets say that second item is Age of the user

Do like this

 ListItem age = new ListItem();
   age.setTitle("AGE");
   username .setLogo(R.id.ageLogo);
   username.setDesc(user.age);

3) Feed the itemList in the Adapter

List<ListItem> myList = new List<ListItem>();
myList.add(username);
myList.add(age);

YourAdapter adapter = new Adapter(context,myList);
recyclerView.setAdapter(adapter);

Hope this helps. Peace:)

Rohit Singh
  • 16,950
  • 7
  • 90
  • 88
-1

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:

enter image description here

<?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);
Ezzy
  • 1,423
  • 2
  • 15
  • 32
  • In regard for your recyclerview suggestion, that wasnt the answer that I was looking for, I have updated my question, and sorry for the ambiguous question. I actually like your second answer, I did not know that you can generate views without using a RecyclerView. If there will be no answer regarding the recyclerview, I will actually take this as an alternative for my problem. Thank you, you really have a good suggestion. Sorry I cant still upvote, i will mark this as an answer If the recyclerview cant be done. – Boomiyaah Nov 08 '18 at 08:49