preface

Although now live is not so hot now, but it is still a lot of App, an important function of earned income, like netease news client, trill now live has introduced the function such as short video, and that the male screen is an important tool to live, so we know about the implementation and screen is also a necessary, and the realization of the screen can have a lot of practice, But for now, I think the faster way is to use RecyclerView to achieve, just offer my humble opinion.

function

The simplest way to display the public screen is to display the messages sent by the user through a sliding list. Of course, the server usually pushes a single piece or a group of data to the client, and then the client adds the new data to the original data source and refreshes the list. Of course, we can support various messages on the public screen to make it look more diverse; Secondly, we can increase the size limit of the data source to prevent memory explosion due to the large data pool. In addition, you can add caching function to data source, put collected data into cache pool, and periodically update the cache pool to the public screen to avoid too frequent drawing on the public screen.

Meet the above functions, basically can become a passing public screen, this paper is based on the above several basic function points for analysis, and then code implementation, which will inevitably have unreasonable places, I hope you point out.

1. Insert data

One or more pieces of data can be inserted and displayed on the public screen.

2. Support for multiple public screens

As shown in the above, there are four kinds of style of the screen, the first is the system notification (first green live rule), the second is the general chat messages, and the third is a gift, is the fourth event notification (pink screen), of course, if you need more, you can continue to add.

3. Supports the public screen size limit

As shown in the figure below, I limit the number of public screens to 100. When I continue to send public screens, old data from the data source is erased and new data is added to the datapool. This will avoid the memory overload caused by some popular rooms being flushed.

4. The buffer pool

With the addition of the cache pool, data refresh will take about 400ms. Therefore, the insert operations within 400ms will be put into the cache pool first, and then the UI will be refreshed when the time is up. In this way, the problem of high GPU caused by frequent UI drawing can be avoided.

implementation

First of all, the layout file is a RecyclerView. The functions of RecyclerView are called by THE API of RecyclerView. I will not go into details and analyze the main function points.

1. Insert data

Insert data into the RecyclerView Adapter to increase the data source, and then notify. Of course, RecyclerView supports local updates. For performance problems, we do not need to refresh the whole data source after inserting data, but only update the newly added data.

Can be called if only one is inserted

notifyItemInserted(getItemCount());
Copy the code

If multiple inserts are used, you can call

notifyItemRangeInserted(startPos, addSize);
Copy the code

Insert data into RecyclerView (int Position, smoothScrollToPosition, int Position, int Position);

Int bottomIndex = adapter.getitemCount () -1; mChatView.smoothScrollToPosition(bottomIndex);Copy the code

2. Diversified public screens

We can load different layout files according to different types of messages. For example:

@Override
public BaseChatViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    switch (viewType) {
        case MyChatMsg.TYPE_NORMAL_TEXT:
            return new NormalChatHolder(LayoutInflater.from(AppUtils.getContext()).inflate(R.layout.layout_normal_text, parent, false));
        case MyChatMsg.TYPE_SYSTEM_NEWS:
            return new SystemNewsHolder(LayoutInflater.from(AppUtils.getContext()).inflate(R.layout.layout_system_news_text, parent, false));
        case MyChatMsg.TYPE_GIFT_MSG:
            return new GiftNewsHolder(LayoutInflater.from(AppUtils.getContext()).inflate(R.layout.layout_gift_text, parent, false));
        default:
            return new HeaderChatHolder(LayoutInflater.from(AppUtils.getContext()).inflate(R.layout.layout_header_text, parent, false));
    }
}
Copy the code

Then, we can customize different views in different layouts. As our UI in the above figure is relatively simple, so our layout is a TextView can be satisfied, with SpannableStringBuilder can do some rich text display.

3. Limit the public screen size

After inserting data, compare the size of the data source with the size we limited, remove the excess, and then update the UI. For example:

Private void removeOverItems() {// Get data source size int dataSize = getDataSize(); Int mMaxChatNum = DEFAULT_MAX_CHAT_NUM; If (dataSize > mMaxChatNum) {beyondSize = dataSize - mMaxChatNum; SubList (0, beyondSize).clear(); mdatas.sublist (0, beyondSize).clear(); // Update UI notifyItemRangeRemoved(1, beyondSize); }}Copy the code

4. The buffer pool

In the run() method, change the data source of the Adapter and notify it. This Runnable is executed periodically, for example, 400ms, so as to avoid frequent drawing of the Adapter for notifying every data insert. See the source code for details.

The source code

If you’re interested in taking a closer look, go to SimpleChatView. If you think that’s OK, you can give Star support.