Android端扩展开发

本文介绍了使用低代码集成(含UI)方式接入互动直播Android端后,自定义扩展开发的方法。

前提条件

背景说明

请先点击此处在线体验直播间各页面提供的组件,并同步了解对应组件的定制方法。

我们提供两种定制方法,以满足不同程度的定制需求:

  • 槽位定制:我们开放了SDK中的部分视图区域(槽位),支持客户在集成应用时自定义这部分区域(槽位)的UI或能力,以满足客户基本定制需求。

  • 组件定制:对于一些较为复杂的定制需求,可以通过组件定制的方式来满足。

槽位定制

  1. 在进入直播间之前(比如静态代码块的地方),添加如下槽位配置。

    static {
        LivePrototype.getInstance().setLiveHook(new LiveHook()
                // 设置右上角的槽位视图
                .setUpperRightSlot(context -> buildTextView(context, "右上角视图"))
                // 设置页面中部的槽位视图
                .setMiddleSlot(context -> buildTextView(context, "页面中部视图"))
        );
    }
    
    private static TextView buildTextView(Context context, String text) {
        TextView textView = new TextView(context);
        textView.setGravity(Gravity.CENTER);
        textView.setBackgroundColor(Color.parseColor("#66ff0000"));
        textView.setTextColor(Color.WHITE);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
        textView.setText(text);
        textView.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
        ));
        return textView;
    }
  2. 添加上述槽位设置的代码后,请重新运行并安装应用。

    此时的直播间效果如下图。页面中的红色区域,即为上述代码的槽位设置效果。

    您可以根据自己的业务需求,在其中添加自定义的视图内容。

    槽位定制效果

组件定制

组件背景(选读)

直播间中涉及到视图逻辑非常复杂,视图与视图之间还会存在一定的联动逻辑(如底部的点赞和顶部的点赞数分别对应点赞逻辑的写和读,底部的输入框和弹幕面板分别对应弹幕逻辑的写和读)。

秉承代码设计的高内聚低耦合原则,抽象出组件的概念,旨在将视图逻辑在一个独立的类范围类自闭环掉。在直播间页面,能看到的每个视图,大到整个信息面板,小到分享、点赞、美颜每个图标,他们都是或者属于一个组件。

考虑到组件与组件之间有着极为复杂的相对位置关系,因此SDK内部的设计,是通过 setContentView 传递的 xml 资源文件来进行组件的灵活配置的。

工程编码

此处以自定义一个能够监听弹幕信息的组件为例,来对组件定制方式进行实际说明。

  1. 新建自定义组件 CustomMessageView

    public class CustomMessageView extends AppCompatTextView implements ComponentHolder {
    
        private final Component component = new Component();
    
        public CustomMessageView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
                  setTextColor(Color.RED);
                  setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
        }
    
        @Override
        public IComponent getComponent() {
            return component;
        }
    
        private class Component extends BaseComponent {
            @Override
            public void onInit(LiveContext liveContext) {
                super.onInit(liveContext);
                // 设置互动服务的回调监听事件
                chatService.addEventHandler(new SampleChatEventHandler() {
                    @Override
                    public void onCommentReceived(CommentEvent event) {
                        setText(String.format("%s: %s", event.creatorNick, event.content));
                    }
                });
            }
        }
    }
  2. 找到SDK中默认的布局文件 ilr_activity_live.xml ,然后复制一份重命名为 activity_custom_live.xml 到工程资源目录下。

  3. activity_custom_live.xml 中的 LiveContentLayer 节点里的最后面添加的自定义组件,如下图示。 自定义组件代码

  4. 将新的布局文件设置给SDK。

    static {
        LivePrototype.getInstance().setLiveHook(new LiveHook()
                .setLiveLayoutRes(R.layout.activity_custom_live)
        );
    }
  5. 运行并安装应用,进入直播间后,此时在底部输入框发送弹幕时,便能看到自定义的信息组件,如下图。组件定制效果

常见问题

如何定制一个组件?

组件分为视图组件和逻辑组件:

  • 视图组件:是包含直播间视图的组件。如点赞组件、输入框组件。可使用上文的 CustomMessageView 的方式进行定制。

  • 逻辑组件:是只包含业务逻辑的组件。如监听点击分享按钮的事件然后做事件打点处理。可先继承 BaseComponent 添加一个组件处理类,然后再将该类注册到SDK中去。

// 自定义逻辑组件
public class ShareClickHandleComponent extends BaseComponent {
    @Override
    public void onEvent(String action, Object... args) {
        if (Actions.SHARE_CLICKED.equals(action)) {
            // 这里写分享事件的点击处理逻辑
        }
    }
}

// 注册组件
static {
    LivePrototype.getInstance().setLiveHook(new LiveHook()
            .addComponentSlots(ShareClickHandleComponent::new)
    );
}

定制的组件如何进行注册?

对于视图组件,只需要把对应的视图View添加到布局文件中即可,SDK内部会自动扫描XML布局文件中,所有实现了 ComponentHolder 的接口。

对于逻辑组件,通过调用 LiveHookaddComponentSlots方法进行注册。

组件之间如何进行通信?

组件通信分为发送方和接收方,参考以下代码进行对应的操作。

// 发送方
public class AComponent extends BaseComponent {

    public static final String ACTION_SOMETHING = "something";

    private void notifySomething() {
        // 发送一个事件
        postEvent(ACTION_SOMETHING);
    }
}


// 接收方
public class BComponent extends BaseComponent {

    @Override
    public void onEvent(String action, Object... args) {
        switch (action) {
            case AComponent.ACTION_SOMETHING:
                // 接收到 AComponent 发送过来的事件
                break;
        }
    }
}