This tutorial is intended to go over a basic implementation of lists in the Chrome on Android MVC framework. If you're not sure what MVC is, seeAdditional Resources.
In this example we'll be creating a simple menu list where each list item consists of an icon and label.
The file structure of our component will be the following:
This class will own theModelListAdapter
that knows how to showPropertyModels
. In this example we'll be combining the responsibilities of what would otherwise be the coordinator and mediator for simplicity.
publicclassSimpleMenuCoordinator{privateSimpleMenuMediator mMediator;publicSimpleMenuCoordinator(Context context,ListView listView){ModelList listItems=newModelList();// Once this is attached to the ListView, there is no need to hold a reference to it.ModelListAdapter adapter=newModelListAdapter(listItems);// If this is a heterogeneous list, register more than one type. adapter.registerType(ListItemType.DEFAULT,()->LayoutInflater.from(context).inflate(R.layout.simple_menu_item,null),SimpleMenuItemViewBinder::bind); listView.setAdapter(adapter); mMediator=newSimpleMenuMediator(context, listItems);}}
This class is responsible for pushing updates into theModelList
. Updates to that object are automatically pushed and bound to the list view. For a more complex system, theModelList
may be part of a largerPropertyModel
that the mediator maintains.
classSimpleMenuMediator{privateModelList mModelList;SimpleMenuMediator(Context context,ModelList modelList){ mModelList= modelList;PropertyModel itemModel= generateListItem(ApiCompatibilityUtils.getDrawable(context.getResources(), R.drawable.icon), context.getResources().getString(R.string.label)); mModelList.add(newModelListAdapter.ListItem(ListItemType.DEFAULT, itemModel));}privatePropertyModel generateListItem(Drawable icon,String text){returnnewPropertyModel.Builder(SimpleMenuProperties.ALL_KEYS).with(SimpleMenuProperties.ICON, icon).with(SimpleMenuProperties.LABEL, text).with(SimpleMenuProperties.CLICK_LISTENER,(view)-> handleClick(view)).build();}privatevoid handleClick(View view){// Do some click logic here. This would typically be done in the mediator.}}
These are the types of data that we want to apply to each list item in our menu.
classSimpleMenuProperties{@IntDef({ListItemType.DEFAULT})@Retention(RetentionPolicy.SOURCE)/** * This can be one or more items depending on if the list is homogeneous. If homogeneous, * this definition can be skipped and 0 can be used in place of that parameter. */public@interfaceListItemType{int DEFAULT=0;}/** The icon for the list item. */publicstaticfinalWritableObjectPropertyKey<Drawable> ICON=newWritableObjectPropertyKey<>();/** The text shown next to the icon. */publicstaticfinalWritableObjectPropertyKey<String> LABEL=newWritableObjectPropertyKey<>();/** The action that occurs when the list item is tapped. */publicstaticfinalWritableObjectPropertyKey<OnClickListener> CLICK_LISTENER=newWritableObjectPropertyKey<>();publicstaticfinalPropertyKey[] ALL_KEYS={ICON, LABEL, CLICK_LISTENER};}
As per the MVC architecture, this class is responsible for taking a model and applying that information in to to a provided view.
classSimpleMenuItemViewBinder{// This can optionally be in the coordinator file depending on the complexity.publicstaticvoid bind(PropertyModel model,View view,PropertyKey propertyKey){if(SimpleMenuProperties.ICON== propertyKey){((ImageView) view.findViewById(R.id.simple_menu_icon)).setImageDrawable( model.get(SimpleMenuProperties.ICON));}elseif(SimpleMenuProperties.LABEL== propertyKey){((TextView) view.findViewById(R.id.simple_menu_label)).setText( model.get(SimpleMenuProperties.LABEL));}elseif(SimpleMenuProperties.CLICK_LISTENER== propertyKey){ view.setOnClickListener(model.get(SimpleMenuProperties.CLICK_LISTENER));}}}
<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2019 The Chromium Authors Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:background="@color/modern_primary_color"><org.chromium.ui.widget.ChromeImageViewandroid:id="@+id/simple_menu_icon"android:layout_width="18dp"android:layout_height="18dp"android:layout_gravity="center_vertical"android:scaleType="centerInside"/><TextViewandroid:id="@+id/simple_menu_label"android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center_vertical"android:textAppearance="@style/TextAppearance.BlackBody"/></LinearLayout>