Skip to content
This repository has been archived by the owner on May 4, 2022. It is now read-only.

Populating Views

Adrián Rivero edited this page May 7, 2017 · 22 revisions

To populate a view with a model, we annotate the model injected field with @Populate.

@Model
@Populate
User user;

This will use the methods and fields from the model to populate the data in the user interface. In the layout, the IDs should be assigned following one of the next rules:

  • The ID should start with the field name plus the symbol "_" plus the field or method name. Ex: user_name to populate with user.getName().
  • The ID should start with the field name and then the field or method name starting with a capital letter. Ex: userName to populate with user.getName().

To access to the model fields that are Models, it can be done following the same rules... let's say that the User model has a field named "partner" that it's also an User, and you want to populate a view with the "partner" name, then you assign the id in the layout to the view to be populated as user_partner_name.

DecleX supports populating by default these views:

  1. TextView and any of its subclasses (Ex. EditText). TextViews are populated using the method setText(String), the field that is going to be used is automatically cast to a String if it is required.
  2. ImageView and any of its subclasses. ImageViews are populated using Picasso library. You can pass as parameter an URL (it'll be downloaded in background by Picasso), a File object, a resource id (ex. R.drawable.image) or a file path.
  3. AdapterView and any of its subclasses (Ex. ListView, GridView, Spinner, Gallery), See Populating AdapterViews and RecyclerViews
  4. RecyclerView and any of its subclases, See Poppulating AdapterViews and RecyclerViews

Populating AdapterViews and RecyclerView

To populate an AdapterView (ListView, GridView, Spinner, Gallery) or a RecyclerView you should assign an arbitrary ID to it, then a field with the same name it is declared in your Enhanced Component (Ex. Activity or Fragment). You should provide in the layout the layout to use for the items in the tools:listitem attribute.

@Model
@Populate
List<User> users;
<android.support.v7.widget.RecyclerView
        android:id="@+id/users"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/item_users" >

Each of the views in the provided layout (R.layout.item_users in the example) should use one of the following rules:

  • The ID should start with the class name in lowercase plus the symbol "_" plus the field or method name. Ex: user_name to populate with user.getName() for each user in the list.
  • The ID should start with the class name in lowercase and then the field or method name starting with a capital letter. Ex: userName to populate with user.getName() for each user in the list.

In the case of populating a RecyclerView, it should be initialized with the LayoutManager:

    @AfterViews
    void initRecyclerView(RecyclerView users) {
        LinearLayoutManager layoutManager = new LinearLayoutManager(context);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        users.setLayoutManager(layoutManager);
    }

Populating List of Strings

A special case, is when you want to Populate a list with only Strings, let's say a grid view with images, and a List of all the URL is available, in this case, your layout for the items should have one element with the id text. Example of a Grid View with images:

@Populate
List<String> images;
<GridView
        android:id="@+id/images"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/image_item" >

image_item.xml

<ImageView
        android:id="@+id/text"
        android:layout_width="72dp"
        android:layout_height="72dp">

Populating list with a model list

A list can also be populated with a model list field, let's say the class user has a list of images, the AdapterView or RecyclerView should be declared in this case using the name of the field (images):

@Model
User user;
<GridView
        android:id="@+id/user_images"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/image_item" >

Populator methods and View Injection in methods

A method can be annotated with @Populate to inject the Views that has been populated in order to add extra configurations:

@Model
@Populate
User user;

@Model
@Populate
List<User> friends;

@Populate
void user(ImageView user_image) {
    //Do something with the current user image
}

@Populate
void friends(ImageView user_image, TextView user_name) {
    //Do something with the friend user_image or user_name
}

See that the populator method for a list is executed for each item of the list.

Any inflated view can also be injected in AndroidAnnotations @AfterViews

@Model
User user;

@AfterViews
void initViews(ImageView user_image) {
    //Do something with user_image
}

Inflating Layouts with Populators

Populators can also be used to inflate Layouts using the injected model, for instance, you can inflate a Header with the information of a user, where the user friends details is shown in the list, and assign this Header to the list:

@Model
@Populate(R.id.header_user)
User user;


@Populate
void user(ListView user_friends, View header_user) {
    user_friends.addHeaderView(header_user);
}

Populating custom or specific views

If you want to populate a different view, then you should declare a method named "assignField" in your Enhanced Component.

public void assignField(View view, Object value) {
    //Assign the parameter "value" to the parameter "view"
}

For instance, if we have a WebView and we want to populate with a specific field of our injected model, we have to declare a method similar to this:

void assignField(View view, Object object) {
    if (view instanceof WebView) {
        ((WebView)view).loadData(object.toString(), "text/html; charset=utf-8", null);
    }
}

Populating with primitives or Strings

Primitives and Strings can also be populated, to use this, you should assign an arbitrary ID to the View that you want to populate, then you declare a field matching the same Id:

@EActivity(R.layout.activity_enhanced)
public class EnhancedActivity extends Activity {

    @Populate
    String text;

    @Populate
    int age;
}

Events and Actions in Model Injection with Populators

When a Populator is applied to a Model, if any Event or Action is used to Load or Update the model, this will result in upating the User Interface linked to the field by the Populator. So, in this example, every time that the event UpdateUIEvent is dispatched, all the views populated by the injected field user are going to be automatically upated as well.

@Model
@Populate
@UpdateOnEvent(UpdateUIEvent.class)
User user;

See also Events and Actions in Model Injection

Populating properties

Frequently, a simple view need to be populated with more than one parameter of a Model, let's say the Text should be populated and the Text Color should be configured, in this case, you can declare a void method that takes as parameter a View class in the Model:

void setTextAndColor(TextView view) {
    view.setText(text);
    view.setTextColor(textColor);
}
Clone this wiki locally