Dynamic expansion and folding function of imitating WeChat Moments Android

Write in front

If the text is too long to expand and collapse, my original idea is to judge the number of lines of the text content through the getLineCount() method of TextView , and then expand or collapse like this. In fact, when this method is called, the number of lines obtained by getLineCount is always 0 when the view is not completely drawn. This problem can be solved by using observers to monitor. The following is the specific operation.

Set the maximum number of rows displayed

According to PM's requirements, set the maximum number of lines to 5 lines:

		<!-- 内容 -->
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="start|center_vertical"
                    android:minHeight="30dp"
                    android:textColor="@color/menuFont"
                    android:textSize="16sp"
                    android:maxLines="5"
                    android:ellipsize="end" />
                <!-- 展开或收起 -->
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="start|center_vertical"
                    android:text="@string/pack_down"
                    android:textColor="@color/colorPrimaryDark"
                    android:textSize="16sp"
                    android:visibility="gone" />

Through android:maxLines="5"
android:ellipsize="end", everyone knows this, so I won't talk about it.

Create observer

Create an observer of the TextView responsible for content display in the Adapter

// 创建观察者,dynamicContent是负责内容展示的TextView
ViewTreeObserver viewTreeObserver = holder.dynamicContent.getViewTreeObserver();

Then through the observer to monitor, in order to avoid the observer to monitor repeated calls, so you need to remove

viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // 避免Observer监听重复调用,移除掉
                ViewTreeObserver observer = holder.dynamicContent.getViewTreeObserver();
                observer.removeOnGlobalLayoutListener(this);
                // 在这里编写你需要的收起或展开的代码
                code...
            }
        });

Then, I use the getLineCount method to determine whether to expand or collapse the operation in the above monitoring

 		if (holder.dynamicContent.getLineCount() >= 5) {
                    holder.packTV.setVisibility(View.VISIBLE);
                    // 全文/收起
                    holder.packTV.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            if (!isPack){
                                // 当前为默认状态False(内容处于收起状态),点击后文本按钮变成收起(内容处于展开状态)
                                holder.packTV.setText(R.string.pack_up);
                                isPack = true;
                                holder.dynamicContent.setMaxLines(50);
                            } else {
                                // 点击后文本按钮变成展开(内容处于收起状态)
                                holder.packTV.setText(R.string.pack_down);
                                isPack = false;
                                holder.dynamicContent.setMaxLines(5);
                            }
                        }
                    });
                } else {
                    holder.packTV.setVisibility(View.GONE);
                }

The maximum number of rows after expansion I set above is 50 rows.
In this way, the function of unfolding or retracting can be realized by monitoring by the observer.
And isPack is used to mark the current state of being expanded or collapsed.

// 判断展开或收起
    private boolean isPack = false;

Paste the complete code block

// 获取TextView的文本内容行数,大于5行就显示全文展示,因为在View没有完全绘制的时候,所有的TextView的文本长度都是0,使用观察者去监听可以解决
        ViewTreeObserver viewTreeObserver = holder.dynamicContent.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // 避免Observer监听重复调用,移除掉
                ViewTreeObserver observer = holder.dynamicContent.getViewTreeObserver();
                observer.removeOnGlobalLayoutListener(this);
                if (holder.dynamicContent.getLineCount() >= 5) {
                    holder.packTV.setVisibility(View.VISIBLE);
                    // 全文/收起
                    holder.packTV.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            if (!isPack){
                                // 当前为默认状态False(内容处于收起状态),点击后文本按钮变成收起(内容处于展开状态)
                                holder.packTV.setText(R.string.pack_up);
                                isPack = true;
                                holder.dynamicContent.setMaxLines(50);
                            } else {
                                // 点击后文本按钮变成展开(内容处于收起状态)
                                holder.packTV.setText(R.string.pack_down);
                                isPack = false;
                                holder.dynamicContent.setMaxLines(5);
                            }
                        }
                    });
                } else {
                    holder.packTV.setVisibility(View.GONE);
                }
            }
        });

Write at the end

The project is about to end. Record the problems encountered during the process. Regarding the expansion and collapse functions of this imitation circle of friends, I did it a long time ago, and I forgot which blogs of the great gods I referred to at the time, and referred to some blogs and articles on the Internet. , There may be similarities, sorry.

Guess you like

Origin blog.csdn.net/A_Intelligence/article/details/85004712