-
Notifications
You must be signed in to change notification settings - Fork 25
Populating Views
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 withuser.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 withuser.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:
- 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. - 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.
- AdapterView and any of its subclasses (Ex. ListView, GridView, Spinner, Gallery), See Populating AdapterViews and RecyclerViews
- RecyclerView and any of its subclases, See Poppulating AdapterViews and RecyclerViews
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 withuser.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 withuser.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">
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" >
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
}
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);
}
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);
}
}
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;
}
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
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);
}
Sponsored by DSpot Sp. z o.o. Contact us at info@dspot.com.pl