This series of articles mainly introduces the use experience and principle of Tangram framework, which is open source by Tmall team. As the bottom layer of Tangram is based on Vlayout, it will also be briefly explained. This series will be introduced according to the following outline:

  1. Demand background

  2. Tangram and Vlayout are introduced

  3. The use of the Tangram

  4. Vlayout principle

  5. Tangram principle

  6. Tangram secondary encapsulation

This article introduces a simple use of Tangram.

The Demo code

Based on using

Introducing dependencies:

    // Related to tangram: Tangram uses the latest version prior to 3.0, while others use the latest version directly
    implementation 'com. Alibaba. Android: tangram: 2.2.5 @ aar'
    // Tangram's underlying support: vlayout
    implementation 'com. Alibaba. Android: vlayout: 1.2.36 @ aar'
    // Tangram virtual view (a more flexible view, covered in a separate opening paragraph)
 implementation('com. Alibaba. Android: virtualview: 1.4.6 @ aar') {  transitive true  }  // Tangram supports banner page-turning  implementation 'com. Alibaba. Android: ultraviewpager: 1.0.7.8 @ aar'  // Tangram needs RXJava internally  implementation 'the IO. Reactivex. Rxjava2: rxjava: 2.1.12'  implementation 'the IO. Reactivex. Rxjava2: rxandroid: 2.0.2' Copy the code

Initialization, which is basically passing the context in, and setting the image loading capability, so we use Glide,

public class MyApp extends Application {
    @Override
    public void onCreate(a) {
        super.onCreate();
        TangramBuilder.init(this.new IInnerImageSetter() {
 @Override  public <IMAGE extends ImageView> void doLoadImageUrl(@NonNull IMAGE view, @Nullable String url) {  Glide.with(view.getContext()).load(url).  error(R.mipmap.ic_launcher).  into(view);  }  }, NetImageView.class);  } } Copy the code

Used in an activity,

//MainActivity.java
void onCreate(Bundle savedInstanceState) {
    // Create builder to configure parameters
    TangramBuilder.InnerBuilder builder = TangramBuilder.newInnerBuilder(this);
    // Register your cell
 builder.registerCell(ImageTextView.class.getSimpleName(), ImageTextView.class);  builder.registerCell(SingleImageView.class.getSimpleName(), SingleImageView.class);   // Create engine  mEngine = builder.build();  / / bind RecyclerView  mEngine.bindView(mBinding.rvList);   mBinding.rvList.addOnScrollListener(new RecyclerView.OnScrollListener() {  @Override  public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  super.onScrolled(recyclerView, dx, dy);  // If the engine's onScroll event is triggered, the card that needs to be loaded asynchronously will be triggered to load data in advance  mEngine.onScrolled();  }  });   // Set data to trigger rendering  String file = FileUtil.getAssertsFile(this."main.json");  try {  mEngine.setData(new JSONArray(file));  } catch (JSONException e) {  e.printStackTrace();  } } Copy the code

As mentioned in the previous introduction, Tangram has built-in Card layout, which basically meets the requirements, so we only need to customize our own specific View, namely the Cell. We manually register two cells, ImageTextView and SingleImageView. So let’s look at the ImageTextView, which is a LinearLayout with an icon on top and a text on the bottom. We need to implement the ITangramViewLifeCycle interface and execute its logic in the corresponding callback.

public class ImageTextView extends LinearLayout implements ITangramViewLifeCycle {
    private NetImageView mImgIcon;
    private TextView mTvTitle;

    public ImageTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);  setOrientation(VERTICAL);  setGravity(Gravity.CENTER);  inflate(getContext(), R.layout.cell_image_text, this);  mImgIcon = findViewById(R.id.img_icon);  mTvTitle = findViewById(R.id.tv_title);  }   @Override  public void cellInited(BaseCell cell) {  }   @Override  public void postBindView(BaseCell cell) {  mImgIcon.load(cell.optStringParam("imgUrl"));  mTvTitle.setText(cell.optStringParam("title"));  }   @Override  public void postUnBindView(BaseCell cell) {  } } Copy the code

The layout file cell_image_text.xml looks like this,

<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

 <com.holiday.tangram.view.NetImageView  android:id="@+id/img_icon"  android:layout_width="50dp"  android:layout_height="50dp"  android:scaleType="centerCrop"  tools:background="@color/colorAccent" />   <TextView  android:id="@+id/tv_title"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_marginTop="4dp"  android:ellipsize="end"  android:maxLines="1"  tools:text="@string/app_name" /> </merge> Copy the code

Now that the cells are ready, let’s prepare the JSON template. Let’s start with a four-column container-fourColumn layout.

{
    "type": "container-fourColumn".    "items": [
        {
            "imgUrl": "https://tva1.sinaimg.cn/large/007S8ZIlgy1geqp9zhftrj303r03r3yl.jpg". "title": "Heading 1". "type": "ImageTextView"  },  {  "imgUrl": "https://tva1.sinaimg.cn/large/007S8ZIlgy1geqp9zhftrj303r03r3yl.jpg". "title": "Heading 2". "type": "ImageTextView"  },  {  "imgUrl": "https://tva1.sinaimg.cn/large/007S8ZIlgy1geqp9zhftrj303r03r3yl.jpg". "title": "Title". "type": "ImageTextView"  },  {  "imgUrl": "https://tva1.sinaimg.cn/large/007S8ZIlgy1geqp9zhftrj303r03r3yl.jpg". "title": "Title 4". "type": "ImageTextView"  }  ] } Copy the code

Run as follows,


Now let’s look at another custom Cell, SingleImageView, which is a simple single image,

public class SingleImageView extends NetImageView implements ITangramViewLifeCycle {

    public SingleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setScaleType(ScaleType.CENTER_CROP);
 }   @Override  public void cellInited(BaseCell cell) {  }   @Override  public void postBindView(BaseCell cell) {  load(cell.optStringParam("imgUrl"));  }   @Override  public void postUnBindView(BaseCell cell) {  } } Copy the code

Then I’m going to do a 1 drag n layout called container-oneplusn

{
    "type": "container-onePlusN".    "style": {
        "aspectRatio": "1.778".        "margin": ",0,0,0 [10]"
 },  "items": [  {  "imgUrl": "https://wanandroid.com/blogimgs/942a5c62-ca87-4e7c-a93d-41ff59a15ba4.png". "type": "SingleImageView"  },  {  "imgUrl": "https://www.wanandroid.com/blogimgs/62c1bd68-b5f3-4a3c-a649-7ca8c7dfabe6.png". "type": "SingleImageView"  },  {  "imgUrl": "https://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png". "type": "SingleImageView"  },  {  "imgUrl": "https://www.wanandroid.com/blogimgs/90c6cc12-742e-4c9f-b318-b912f163b8d0.png". "type": "SingleImageView"  }  ] } Copy the code

The image is taken from the android banner, run like this,


Since there are four pieces of data, the display is 1 drag 3.

And then I’m going to do a rotation of the container and banner, and I’m going to use the single image SingleImageView,

{
    "type": "container-banner".    "style": {
        "margin": "[0,0,10,0]".        "pageWidth": 200. "pageHeight": 100. "indicatorMargin": "5". "infinite": "true". "indicatorImg2": "https://img.alicdn.com/tps/TB1XRNFNXXXXXXKXXXXXXXXXXXX-32-4.png". "indicatorImg1": "https://img.alicdn.com/tps/TB16i4qNXXXXXbBXFXXXXXXXXXX-32-4.png". "scrollMarginLeft": "10". "indicatorGap": "2". "indicatorHeight": "1.5". "itemRatio": "2.654". "scrollMarginRight": "10". "indicatorGravity": "center". "hGap": "20"  },  "items": [  {  "imgUrl": "https://wanandroid.com/blogimgs/942a5c62-ca87-4e7c-a93d-41ff59a15ba4.png". "type": "SingleImageView"  },  {  "imgUrl": "https://www.wanandroid.com/blogimgs/62c1bd68-b5f3-4a3c-a649-7ca8c7dfabe6.png". "type": "SingleImageView"  },  {  "imgUrl": "https://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png". "type": "SingleImageView"  },  {  "imgUrl": "https://www.wanandroid.com/blogimgs/90c6cc12-742e-4c9f-b318-b912f163b8d0.png". "type": "SingleImageView"  }  ] } Copy the code

As you can see, there are a lot of parameters that can be configured. You can see the documentation here. Run the following command,


The overall effect is as follows,



Built-in support

Tangram has built-in support for handling SimpleClickSupport, card data loading CardLoadSupport, and exposure logic ExposureSupport, which can be registered with TangramEngine’s Add method, as follows:

//MainActivity.java
mEngine.addSimpleClickSupport(new MyClickSupport());
Copy the code

Then look at MyClickSupport,

public class MyClickSupport extends SimpleClickSupport {
    public MyClickSupport(a) {
        setOptimizedMode(true);
    }

 @Override  public void defaultClick(View targetView, BaseCell cell, int eventType) {  super.defaultClick(targetView, cell, eventType);  QrToast.show(cell.stringType);  } } Copy the code

We can set click events in our own Cell, or we can send click events to support for global processing. If we want to use support to process click events, we need to add this line of code to the Cell.

//SingleImageView.java
@Override
public void cellInited(BaseCell cell) {
    setOnClickListener(cell);
}
Copy the code

For example, the home page of mall, most modules are click to jump to the page, the behavior is relatively simple, do not need every Cell to click the event, SimpleClickSupport can be very good support, in defaultClick to take out the page short chain to jump, for example,

public class MyClickSupport extends SimpleClickSupport {
    public MyClickSupport(a) {
        setOptimizedMode(true);
    }

 @Override  public void defaultClick(View targetView, BaseCell cell, int eventType) {  super.defaultClick(targetView, cell, eventType);  // Take out the short link of the page to jump to. Short chains can be either H5 or native and are handled internally by the Router  PageRouter.to(cell.optStringParam("link"));  } } Copy the code

It’s so easy to use. Well, that’s it for Tangram, and we’ll look into how it works, separating templates from data, and more


Refer to the article

  • GitHub-Tangram uses documentation
  • Tangram website

This article is formatted using MDNICE