android实现评论区功能

27 篇文章 0 订阅
6 篇文章 0 订阅
文章展示了如何在Android应用中创建一个包含Banner广告、信息展示、评论列表的复杂布局。使用RecyclerView作为基础,定义了不同的ViewHolder类型来处理不同类型的视图。同时,文章详细介绍了如何使用Glide库加载网络图片,以及如何在滚动时加载更多数据。
摘要由CSDN通过智能技术生成

效果

在这里插入图片描述

activity_detail.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:orientation="vertical"
    tools:context=".ui.activity.DetailActivity">

    <LinearLayout
        android:id="@+id/fl_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fff"
        android:gravity="center_vertical"
        android:orientation="vertical">
        <View
            android:id="@+id/v_status_seat"
            android:layout_width="match_parent"
            android:layout_height="0dp"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:padding="5dp">

            <ImageView
                android:layout_width="23dp"
                android:id="@+id/iv_back"
                android:layout_height="wrap_content"
                android:src="@mipmap/title_left" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="15dp"
                android:gravity="center_vertical">

                <ImageView
                    android:id="@+id/iv_ta_logo"
                    android:layout_width="35dp"
                    android:layout_height="35dp"
                    android:src="@mipmap/ic_head_default" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="13dp"
                    android:text="00"
                    android:textColor="#171717" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:id="@+id/recyclerView"
        android:layout_weight="1"
        android:layout_height="0dp"/>
<!--    <ScrollView-->
<!--        android:id="@+id/sv_content"-->
<!--        android:layout_width="match_parent"-->
<!--        android:layout_height="0dp"-->
<!--        android:scrollbars="none"-->
<!--        android:layout_weight="1">-->

<!--        <LinearLayout-->
<!--            android:layout_width="match_parent"-->
<!--            android:layout_height="wrap_content"-->
<!--            android:orientation="vertical">-->

<!--            <LinearLayout-->
<!--                android:layout_width="match_parent"-->
<!--                android:layout_height="wrap_content"-->
<!--                android:orientation="vertical">-->

<!--                <com.youth.banner.Banner-->
<!--                    android:id="@+id/banner"-->
<!--                    app:banner_indicator_selected_color="#03A9F4"-->
<!--                    android:layout_width="match_parent"-->
<!--                    android:layout_height="400dp" />-->
<!--            </LinearLayout>-->

<!--            <LinearLayout-->
<!--                android:layout_width="match_parent"-->
<!--                android:layout_height="wrap_content"-->
<!--                android:orientation="vertical"-->
<!--                android:padding="15dp">-->

<!--                <TextView-->
<!--                    android:layout_width="wrap_content"-->
<!--                    android:layout_height="wrap_content"-->
<!--                    android:text="童年的味道"-->
<!--                    android:textColor="#F3000000"-->
<!--                    android:textSize="18sp" />-->

<!--                <TextView-->
<!--                    android:layout_width="wrap_content"-->
<!--                    android:layout_height="wrap_content"-->
<!--                    android:layout_marginTop="15dp"-->
<!--                    android:text="编辑于 2023-03-02 11:38 广东"-->
<!--                    android:textColor="#919191"-->
<!--                    android:textSize="10sp" />-->

<!--                <View-->
<!--                    android:layout_width="match_parent"-->
<!--                    android:layout_height="1dp"-->
<!--                    android:layout_marginTop="15dp"-->
<!--                    android:background="#F0F0F0" />-->

<!--                <TextView-->
<!--                    android:layout_width="wrap_content"-->
<!--                    android:layout_height="wrap_content"-->
<!--                    android:layout_marginTop="20dp"-->
<!--                    android:textSize="12sp"-->
<!--                    android:text="共6条评论"-->
<!--                    android:textColor="#676666" />-->

<!--                <LinearLayout-->
<!--                    android:layout_width="match_parent"-->
<!--                    android:layout_height="wrap_content"-->
<!--                    android:layout_marginTop="15dp"-->
<!--                    android:gravity="center_vertical"-->
<!--                    android:orientation="horizontal">-->

<!--                    <ImageView-->
<!--                        android:id="@+id/iv_my_logo"-->
<!--                        android:layout_width="35dp"-->
<!--                        android:layout_height="35dp"-->
<!--                        android:src="@mipmap/ic_head_default" />-->

<!--                    <TextView-->
<!--                        android:layout_width="match_parent"-->
<!--                        android:layout_height="30dp"-->
<!--                        android:layout_marginLeft="10dp"-->
<!--                        android:textSize="15sp"-->
<!--                        android:background="@drawable/bg_radius_100_light_gray"-->
<!--                        android:gravity="center_vertical"-->
<!--                        android:text="爱评论的人总是热情的~"-->
<!--                        android:textColor="#717070" />-->
<!--                </LinearLayout>-->
<!--            </LinearLayout>-->

<!--            <LinearLayout-->
<!--                android:layout_width="match_parent"-->
<!--                android:layout_height="wrap_content"-->
<!--                android:orientation="vertical">-->

<!--                -->
<!--            </LinearLayout>-->
<!--        </LinearLayout>-->
<!--    </ScrollView>-->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fff"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#F0F0F0" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingLeft="15dp"
            android:paddingRight="15dp">

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:layout_weight="1"
                android:layout_marginRight="5dp"
                android:background="@drawable/bg_radius_100_light_gray"
                android:gravity="center_vertical">

                <ImageView
                    android:layout_width="15dp"
                    android:layout_height="15dp"
                    android:src="@mipmap/edit" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="33dp"
                    android:layout_marginLeft="3dp"
                    android:textSize="15sp"
                    android:gravity="center_vertical"
                    android:text="说些什么..."
                    android:textColor="#4C4C4C" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="right">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_vertical"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:src="@mipmap/love_black" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="2dp"
                        android:text="150"
                        android:textColor="#323131" />
                </LinearLayout>

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:gravity="center_vertical"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:src="@mipmap/sc_black" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="2dp"
                        android:text="收藏"
                        android:textColor="#323131" />
                </LinearLayout>

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:gravity="center_vertical"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:src="@mipmap/msg_black" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="2dp"
                        android:text="10"
                        android:textColor="#323131" />
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

DetailActivity

package com.coral3.ah.ui.activity;

import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.coral3.ah.R;
import com.coral3.ah.adapter.DetailAdapter;
import com.coral3.ah.data.DataDetail;
import com.coral3.ah.data.DataOther;
import com.coral3.common_module.base.BaseActivity;
import com.coral3.common_module.utils.GlideUtil;
import com.coral3.common_module.utils.StatusBarUtil;
import com.coral3.common_module.utils.SysManager;

public class DetailActivity extends BaseActivity {

    private ImageView userLogo;
    private View vStatusSeat;
    private ImageView ivBack;
    private RecyclerView recyclerView;
    private DetailAdapter detailAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        StatusBarUtil.setLightStatusBar(this, true, true);
        initView();
        initListener();
    }

    @Override
    protected void initView() {
        ivBack = findViewById(R.id.iv_back);
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new GridLayoutManager(this, 6, GridLayoutManager.VERTICAL, false));
        detailAdapter = new DetailAdapter(this);
        recyclerView.setAdapter(detailAdapter);
        detailAdapter.addData(DataDetail.getData());
        userLogo = findViewById(R.id.iv_ta_logo);
        GlideUtil.loadImgCircle(this, R.mipmap.ic_head_default_girl, userLogo);
        vStatusSeat = findViewById(R.id.v_status_seat);
        int height = SysManager.getInstance().getStatusBarHeight(this);
        ViewGroup.LayoutParams params = vStatusSeat.getLayoutParams();
        params.height = height;
        vStatusSeat.setLayoutParams(params);
    }

    @Override
    protected void initListener() {
        ivBack.setOnClickListener(this);
        // 滑动监听
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                // 判断是否到底部, offset是滑动距离, range是总的内容高度, Extent是控件高度
                if (recyclerView.getChildCount() > 0
                        && recyclerView.computeVerticalScrollOffset() + recyclerView.computeVerticalScrollExtent()
                        >= recyclerView.computeVerticalScrollRange()) {
                    if(detailAdapter.getLoadStatus() == 2) return;
                    if(detailAdapter.getItemCount() < 25) {
                        detailAdapter.addData(DataOther.getOtherList());
                    }else {
                        detailAdapter.setLoadStatus(2);
                        detailAdapter.addData("没有更多数据");
                    }
                }
            }
        });
    }

    @Override
    public void onClick(View view) {
        if(view.getId() == R.id.iv_back) {
            finish();
        }
    }
}

DetailAdapter

package com.coral3.ah.adapter;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.coral3.ah.R;
import com.coral3.ah.bean.BeanDetail;
import com.coral3.common_module.components.LayoutForTextView;
import com.coral3.common_module.components.TalkChildList;
import com.coral3.common_module.entity.bo.ListBO;
import com.coral3.common_module.base.BaseBuildInfo;
import com.coral3.common_module.utils.AppManager;
import com.coral3.common_module.utils.GlideUtil;
import com.coral3.common_module.utils.LogUtil;
import com.coral3.common_module.utils.WinManagerUtil;
import com.wang.avi.AVLoadingIndicatorView;
import com.youth.banner.Banner;
import com.youth.banner.indicator.CircleIndicator;
import java.util.ArrayList;
import java.util.List;

/**
 * 复制型的Adapter
 */

public class DetailAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    // 头部
    public static final int ITEM_HEAD = 0;
    // 信息
    public static final int ITEM_MESSAGE = 1;
    // 聊天列表
    public static final int ITEM_TALK = 2;
    // 没有更多
    public static final int ITEM_NO_MORE = 3;
    
    private int status;
    private Context context;
    private List<Object> datas = new ArrayList<>();

    public DetailAdapter(Context context) {
        this.context = context;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return 6;
                }
            });
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == ITEM_HEAD) {
            return new HeadViewHolder(LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.layout_recyclerview_item_talk_banner, parent, false));
        } else if (viewType == ITEM_MESSAGE) {
            return new MessageViewHolder(LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.layout_recyclerview_item_talk_center, parent, false));
        } else if (viewType == ITEM_TALK) {
            return new TalkViewHolder(LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.layout_recyclerview_item_talk_list, parent, false));
        } else if (viewType == ITEM_NO_MORE) {
            return new NoMoreViewHolder(LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.layout_no_more, parent, false));
        } else {
            return null;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //头部
        if (holder instanceof HeadViewHolder) {
            BeanDetail beanDetail = (BeanDetail) datas.get(position);
            Banner banner = ((HeadViewHolder) holder).banner;
            List<String> images = new ArrayList<>();
            //通过Glide获取网络图片宽高
            Glide.with(context)
                    .asBitmap()
                    .load(BaseBuildInfo.BASE_URL + "/" + BaseBuildInfo.CONTEXT + "/userFile/image/test_xhs.jpg")
                    .into(new CustomTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(@NonNull Bitmap bitmap, @Nullable Transition<? super Bitmap> transition) {
                            int width = bitmap.getWidth();
                            int height = bitmap.getHeight();
                            int screenW = WinManagerUtil.getWidth(AppManager.getInstance().getTopActivity());
                            int bh = screenW * height / width;
                            ViewGroup.LayoutParams params = banner.getLayoutParams();
                            params.height = bh;
                            banner.setLayoutParams(params);
                        }

                        @Override
                        public void onLoadCleared(@Nullable Drawable drawable) {

                        }
                    });
            images.add(BaseBuildInfo.BASE_URL + "/" + BaseBuildInfo.CONTEXT + "/userFile/image/test_xhs.jpg");
            images.add(BaseBuildInfo.BASE_URL + "/" + BaseBuildInfo.CONTEXT + "/userFile/image/test_xhs2.jpg");
            images.add(BaseBuildInfo.BASE_URL + "/" + BaseBuildInfo.CONTEXT + "/userFile/image/test_xhs1.jpg");
            banner.setAdapter(new ImageAdapter(images, context)).setIndicator(new CircleIndicator(context)).isAutoLoop(false);
            banner.setIndicatorSelectedColor(context.getResources().getColor(R.color.banner_Indicator_select));
        }
        //信息
        else if (holder instanceof MessageViewHolder) {
            BeanDetail beanDetail = (BeanDetail) datas.get(position);
            MessageViewHolder messageViewHolder = (MessageViewHolder) holder;
            GlideUtil.loadImgCircle(context, R.mipmap.ic_head_default, messageViewHolder.senderAvatar);
        }
        // 聊天列表
        else if (holder instanceof TalkViewHolder) {
            ListBO listBO = (ListBO) datas.get(position);
            TalkViewHolder talkViewHolder = (TalkViewHolder) holder;
            GlideUtil.loadImgCircle(context, R.mipmap.ic_head_default, talkViewHolder.ivAvatar);
            talkViewHolder.tvTalkContent.setText(listBO.getTalkContent());
            talkViewHolder.tvExpand.setOnClickListener(view -> {
                LogUtil.d("展开");
                talkViewHolder.tvExpand.setVisibility(View.GONE);
                talkViewHolder.tclList.addData(false);
                talkViewHolder.llExpandLoading.setVisibility(View.VISIBLE);
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        ((Activity)context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                talkViewHolder.tvExpand.setText("展开更多回复");
                                talkViewHolder.tvExpand.setVisibility(View.VISIBLE);
                                talkViewHolder.llExpandLoading.setVisibility(View.GONE);
                            }
                        });
                    }
                }).start();
            });
            talkViewHolder.tvExpand.setVisibility(View.VISIBLE);
            LayoutForTextView lf = talkViewHolder.layoutForTextView;
            LinearLayout parent = (LinearLayout) lf.getParent();
            parent.getViewTreeObserver().addOnPreDrawListener(
                    new ViewTreeObserver.OnPreDrawListener() {
                        @Override
                        public boolean onPreDraw() {
                            parent.getViewTreeObserver().removeOnPreDrawListener(this);
                            ViewGroup.LayoutParams layoutParams = (ViewGroup.LayoutParams) lf.getLayoutParams();
                            layoutParams.width = parent.getWidth();
                            lf.setLayoutParams(layoutParams);
                            return true;
                        }
                    });
        }
    }

    @Override
    public int getItemCount() {
        return datas.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            //确定第一个是头部
            return ITEM_HEAD;
        } else if (position == 1) {
            //确定第二个是信息
            return ITEM_MESSAGE;
        } else if (datas.get(position) instanceof ListBO) {
            return ITEM_TALK;
        } else {
            //确定String用户商品头部
            return ITEM_NO_MORE;
        }
    }

    /**
     * 头部
     */
    public class HeadViewHolder extends RecyclerView.ViewHolder {
        public Banner banner;

        public HeadViewHolder(View itemView) {
            super(itemView);
            banner = itemView.findViewById(R.id.talk_banner);
        }
    }

    /**
     * 信息
     */
    public class MessageViewHolder extends RecyclerView.ViewHolder {
        public ImageView senderAvatar;

        public MessageViewHolder(View itemView) {
            super(itemView);
            senderAvatar = itemView.findViewById(R.id.iv_my_logo);
        }
    }

    /**
     * 评论列表
     */
    public class TalkViewHolder extends RecyclerView.ViewHolder {

        public ImageView ivAvatar;
        public TextView tvTalkContent, tvExpand;
        public TalkChildList tclList;
        public AVLoadingIndicatorView aviLoading;
        public LinearLayout llExpandLoading;
        public LayoutForTextView layoutForTextView;

        public TalkViewHolder(View itemView) {
            super(itemView);
            ivAvatar = itemView.findViewById(R.id.iv_user_avatar);
            tvTalkContent = itemView.findViewById(R.id.tv_talk_content);
            tclList = itemView.findViewById(R.id.tcl_list);
            tvExpand = itemView.findViewById(com.coral3.common_module.R.id.tv_expand);
            aviLoading = itemView.findViewById(com.coral3.common_module.R.id.avi_loading);
            llExpandLoading = itemView.findViewById(R.id.ll_expand_loading);
            layoutForTextView = itemView.findViewById(R.id.lf_talk_text);
        }

    }

    /**
     * 其他
     */
    public class NoMoreViewHolder extends RecyclerView.ViewHolder {
        public TextView tv_name;

        public NoMoreViewHolder(View itemView) {
            super(itemView);
            tv_name = itemView.findViewById(R.id.tv_load_end);
        }
    }

    /**
     * 添加数据
     */
    public void addData(BeanDetail detail) {
        //确定前两个的数据,就可以这样写
        datas.add(detail);
        datas.add(detail);
        datas.addAll(detail.getTalkList());
        notifyDataSetChanged();
    }

    /**
     * 添加数据
     */
    public void addData(List<ListBO> others) {
        datas.addAll(others);
        notifyDataSetChanged();
    }

    /**
     * 添加数据
     */
    public void addData(String noMore) {
        datas.add(noMore);
        notifyDataSetChanged();
    }

    public void setLoadStatus(int status){
        this.status = status;
    }

    public int getLoadStatus(){
        return status;
    }

    /**
     * 清除数据
     */
    public void clearData() {
        datas.clear();
        notifyDataSetChanged();
    }
}

layout_recyclerview_item_talk_banner.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_height="wrap_content">
        <com.youth.banner.Banner
            android:id="@+id/talk_banner"
            app:banner_indicator_selected_color="#03A9F4"
            android:layout_width="match_parent"
            android:layout_height="400dp" />
</LinearLayout>

layout_recyclerview_item_talk_center.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:layout_height="wrap_content">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="15dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="趁年轻 多去经历吧"
            android:textColor="#F3000000"
            android:textSize="18sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="编辑于 2023-03-02 11:38 广东"
            android:textColor="#919191"
            android:textSize="10sp" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="15dp"
            android:background="#F0F0F0" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:textSize="12sp"
            android:text="共6条评论"
            android:textColor="#676666" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/iv_my_logo"
                android:layout_width="35dp"
                android:layout_height="35dp"
                android:src="@mipmap/ic_head_default" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:layout_marginLeft="10dp"
                android:textSize="15sp"
                android:background="@drawable/bg_radius_100_light_gray"
                android:gravity="center_vertical"
                android:text="爱评论的人总是热情的~"
                android:textColor="#717070" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

layout_recyclerview_item_talk_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="horizontal"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:id="@+id/ll_talk_item"
    android:layout_height="wrap_content">
    <LinearLayout
        android:layout_width="wrap_content"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/iv_user_avatar"
            android:src="@mipmap/ic_head_default"
            android:layout_width="35dp"
            android:layout_height="35dp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="wrap_content">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <LinearLayout
                android:layout_width="0dp"
                android:layout_weight="1"
                android:orientation="vertical"
                android:layout_height="wrap_content">
                <TextView
                    android:id="@+id/tv_username"
                    android:text="蓝之静云"
                    android:textColor="#919090"
                    android:textSize="12sp"
                    android:gravity="center_vertical"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
                <com.coral3.common_module.components.LayoutForTextView
                    android:layout_width="match_parent"
                    android:id="@+id/lf_talk_text"
                    android:layout_gravity="center_vertical"
                    android:layout_height="wrap_content">
                    <TextView
                        android:id="@+id/tv_talk_content"
                        android:textColor="#3E3E3E"
                        android:textSize="13sp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"/>
                    <TextView
                        android:text="16分钟前 广东"
                        android:paddingLeft="5dp"
                        android:textSize="11sp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"/>
                </com.coral3.common_module.components.LayoutForTextView>

            </LinearLayout>
            <LinearLayout
                android:layout_width="30dp"
                android:gravity="right"
                android:layout_height="wrap_content">
                <ImageView
                    android:src="@mipmap/love"
                    android:layout_width="25dp"
                    android:layout_height="25dp"/>
            </LinearLayout>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:orientation="vertical"
            android:layout_height="wrap_content">
            <com.coral3.common_module.components.TalkChildList
                android:id="@+id/tcl_list"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </LinearLayout>
        <TextView
            android:id="@+id/tv_expand"
            android:text="展开26条回复"
            android:visibility="gone"
            android:layout_marginTop="10dp"
            android:textColor="#1C3D57"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="25dp"/>
        <LinearLayout
            android:id="@+id/ll_expand_loading"
            android:orientation="horizontal"
            android:layout_marginTop="10dp"
            android:visibility="gone"
            android:gravity="center_vertical"
            android:layout_gravity="center_vertical"
            android:layout_width="wrap_content"
            android:layout_height="25dp">
            <com.wang.avi.AVLoadingIndicatorView
                android:id="@+id/avi_loading"
                android:layout_width="20dp"
                android:layout_height="20dp"
                app:indicatorColor="#A8A7A7"
                app:indicatorName="BallRotateIndicator"/>
            <TextView
                android:text="努力加载中..."
                android:layout_marginLeft="10dp"
                android:textSize="12sp"
                android:textColor="#A8A7A7"
                android:paddingTop="1dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </LinearLayout>
        <TextView
            android:background="#F0F0F0"
            android:layout_marginTop="15dp"
            android:layout_marginBottom="15dp"
            android:layout_width="match_parent"
            android:layout_height="1dp"/>
    </LinearLayout>
</LinearLayout>

layout_recyclerview_item_talk_list_child.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:id="@+id/ll_talk_item"
    android:layout_marginTop="15dp"
    android:layout_height="wrap_content">
    <LinearLayout
        android:layout_width="wrap_content"
        android:orientation="vertical"
        android:paddingRight="5dp"
        android:gravity="center_horizontal"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/iv_user_avatar"
            android:src="@mipmap/ic_head_default"
            android:layout_width="20dp"
            android:layout_height="20dp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="wrap_content">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <LinearLayout
                android:layout_width="0dp"
                android:layout_weight="1"
                android:orientation="vertical"
                android:layout_height="wrap_content">
                <TextView
                    android:id="@+id/tv_username"
                    android:text="蓝之静云"
                    android:textColor="#919090"
                    android:textSize="12sp"
                    android:gravity="center_vertical"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
                <com.coral3.common_module.components.LayoutForTextView
                    android:layout_width="match_parent"
                    android:id="@+id/lf_talk_text"
                    android:layout_gravity="center_vertical"
                    android:layout_height="wrap_content">
                    <TextView
                        android:id="@+id/tv_talk_content"
                        android:textColor="#3E3E3E"
                        android:textSize="13sp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"/>
                    <TextView
                        android:text="4天前 广东"
                        android:paddingLeft="5dp"
                        android:textSize="11sp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"/>
                </com.coral3.common_module.components.LayoutForTextView>

            </LinearLayout>
            <LinearLayout
                android:layout_width="30dp"
                android:gravity="right"
                android:layout_marginRight="0dp"
                android:layout_height="wrap_content">
                <ImageView
                    android:src="@mipmap/love"
                    android:layout_width="25dp"
                    android:layout_height="25dp"/>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

TalkListChildAdapter

package com.coral3.common_module.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.coral3.common_module.R;
import com.coral3.common_module.components.LayoutForTextView;
import com.coral3.common_module.entity.bo.ListBO;
import com.coral3.common_module.utils.GlideUtil;
import com.coral3.common_module.utils.LogUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 复制型的Adapter
 */

public class TalkListChildAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    // 聊天列表
    public static final int ITEM_TALK = 2;
    private Context context;
    private List<Object> datas = new ArrayList<>();

    public TalkListChildAdapter(Context context) {
        this.context = context;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return 6;
                }
            });
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == ITEM_TALK) {
            return new TalkViewHolder(LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.layout_recyclerview_item_talk_list_child, parent, false));
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if(holder instanceof TalkViewHolder) {
            TalkViewHolder talkViewHolder = (TalkViewHolder) holder;
            if (listener != null) {
                talkViewHolder.llTalkItem.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        listener.myClick(v,position);
                    }
                });
                // set LongClick
                talkViewHolder.llTalkItem.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        listener.mLongClick(v,position);
                        return true;
                    }
                });
            }
            ListBO listBO = (ListBO) datas.get(position);
            GlideUtil.loadImgCircle(context, R.mipmap.ic_head_default, talkViewHolder.ivAvatar);
            talkViewHolder.tvTalkContent.setText(listBO.getTalkContent());
            LayoutForTextView lf = talkViewHolder.layoutForTextView;
            LinearLayout parent = (LinearLayout) lf.getParent();
            parent.getViewTreeObserver().addOnPreDrawListener(
                    new ViewTreeObserver.OnPreDrawListener() {
                        @Override
                        public boolean onPreDraw() {
                            parent.getViewTreeObserver().removeOnPreDrawListener(this);
                            ViewGroup.LayoutParams layoutParams = (ViewGroup.LayoutParams) lf.getLayoutParams();
                            layoutParams.width = parent.getWidth();
                            lf.setLayoutParams(layoutParams);
                            return true;
                        }
                    });
        }
    }

    private OnMyItemClickListener listener;
    public void setOnMyItemClickListener(OnMyItemClickListener listener){
        this.listener = listener;
    }

    public interface OnMyItemClickListener{
        void myClick(View v,int pos);
        void mLongClick(View v,int pos);
    }

    @Override
    public int getItemCount() {
        return datas.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (datas.get(position) instanceof ListBO) {
            return ITEM_TALK;
        }
        return 0;
    }

    /**
     * 评论列表
     */
    public class TalkViewHolder extends RecyclerView.ViewHolder {

        public ImageView ivAvatar;
        public TextView tvTalkContent;
        public LinearLayout llTalkItem;
        public LayoutForTextView layoutForTextView;

        public TalkViewHolder(View itemView) {
            super(itemView);
            ivAvatar = itemView.findViewById(R.id.iv_user_avatar);
            tvTalkContent = itemView.findViewById(R.id.tv_talk_content);
            llTalkItem = itemView.findViewById(R.id.ll_talk_item);
            layoutForTextView = itemView.findViewById(R.id.lf_talk_text);
        }
    }

    /**
     * 添加数据
     */
    public void addData(ListBO listBO) {
        datas.add(listBO);
        notifyDataSetChanged();
    }

    /**
     * 清除数据
     */
    public void clearData() {
        datas.clear();
        notifyDataSetChanged();
    }
}

TalkChildList

package com.coral3.common_module.components;

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.coral3.common_module.R;
import com.coral3.common_module.adapter.TalkListChildAdapter;
import com.coral3.common_module.entity.bo.ListBO;
import com.coral3.common_module.utils.LogUtil;

public class TalkChildList extends LinearLayout{

    private Context mContext;
    private View view;
    // 列表相关
    private RecyclerView rv;
    private TalkListChildAdapter rvAdapter;

    public TalkChildList(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        initView();
        initListener();
        addData(true);
    }

    private void initView() {
        view = LayoutInflater.from(mContext).inflate(R.layout.layout_list, this);
        initRv();
    }

    private void initListener(){
        rvAdapter.setOnMyItemClickListener(new TalkListChildAdapter.OnMyItemClickListener() {
            @Override
            public void myClick(View v, int pos) {
                LogUtil.d("onClick " + pos);
            }

            @Override
            public void mLongClick(View v, int pos) {
                LogUtil.d("onClick " + pos);
            }
        });
    }

    private void initRv() {
        rv = view.findViewById(R.id.recyclerview);
        rv.setLayoutManager(new GridLayoutManager(mContext, 6, GridLayoutManager.VERTICAL, false));
        rvAdapter = new TalkListChildAdapter(mContext);
        rv.setAdapter(rvAdapter);
    }

    public void addData(Boolean isFirstLoad){
        if(isFirstLoad){
            rvAdapter.addData(new ListBO("牡丹的我 何必在意"));
        }else{
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ((Activity)mContext).runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            rvAdapter.addData(new ListBO("喜欢有时候不能超越一切"));
                            rvAdapter.addData(new ListBO("总在不经意之间想起了你"));
                            rvAdapter.addData(new ListBO("世间万物 春风细雨 开心你我"));
                            rvAdapter.addData(new ListBO("总在寻找一个人 那人也在寻找我"));
                            rvAdapter.addData(new ListBO("世间很多东西不是靠等 而是主动去把握 若喜欢大胆去追求吧 若竭尽所能未如愿 也无憾"));
                            rvAdapter.notifyDataSetChanged();
                        }
                    });
                }
            }).start();
        }
    }
}

LayoutForTextView

package com.coral3.common_module.components;

import android.content.Context;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * Created by 蓝之静云 on 2023/03/10
 */
public class LayoutForTextView extends ViewGroup {
    //单行显示
    private static final int SINGLE_LINE = 0x01;
    //多行显示
    private static final int MULTI_LINE = 0x02;
    //显示到下一行
    private static final int NEXT_LINE = 0x03;
    //显示样式
    private int type;
    //绘制文字最后一行的顶部坐标
    private int lastLineTop;
    //绘制文字最后一行的右边坐标
    private float lastLineRight;

    public LayoutForTextView(Context context) {
        super(context);
    }

    public LayoutForTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public LayoutForTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int childCount = getChildCount();
        int w = MeasureSpec.getSize(widthMeasureSpec);
        if (childCount == 2) {
            TextView tv = null;
            if(getChildAt(0) instanceof  TextView){
                tv = (TextView) getChildAt(0);
                initTextParams(tv.getText(), tv.getMeasuredWidth(), tv.getPaint());
            }else{
                throw new RuntimeException("LayoutForTextView first child view not a TextView");
            }

            View sencodView = getChildAt(1);

            //测量子view的宽高
            measureChildren(widthMeasureSpec, heightMeasureSpec);

            //两个子view宽度相加小于该控件宽度的时候
            if (tv.getMeasuredWidth() + sencodView.getMeasuredWidth() <= w) {
                int width = tv.getMeasuredWidth()+sencodView.getMeasuredWidth();
                //计算高度
                int height = Math.max(tv.getMeasuredHeight(), sencodView.getMeasuredHeight());
                //设置该viewgroup的宽高
                setMeasuredDimension(width, height);
                type = SINGLE_LINE;
                return;
            }
            if (getChildAt(0) instanceof TextView) {
                //最后一行文字的宽度加上第二个view的宽度大于viewgroup宽度时第二个控件换行显示
                if (lastLineRight + sencodView.getMeasuredWidth() > w) {
                    setMeasuredDimension(tv.getMeasuredWidth(), tv.getMeasuredHeight() + sencodView.getMeasuredHeight());
                    type = NEXT_LINE;
                    return;
                }

                int height = Math.max(tv.getMeasuredHeight(), lastLineTop + sencodView.getMeasuredHeight());
                setMeasuredDimension(tv.getMeasuredWidth(), height);
                type = MULTI_LINE;
            }
        } else {
            throw new RuntimeException("LayoutForTextView child count must is 2");
        }

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (type == SINGLE_LINE || type == MULTI_LINE) {
            TextView tv = (TextView) getChildAt(0);
            View v1 = getChildAt(1);
            //设置第二个view在Textview文字末尾位置
            tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
            int left = (int) lastLineRight;
            int top  = lastLineTop;
            //最后一行的高度 注:通过staticLayout得到的行高不准确故采用这种方式
            int lastLineHeight = tv.getBottom()-tv.getPaddingBottom() -lastLineTop;
            //当第二view高度小于单行文字高度时竖直居中显示
            if(v1.getMeasuredHeight() < lastLineHeight){
                top = lastLineTop + (lastLineHeight - v1.getMeasuredHeight())/2;
            }
            v1.layout(left, top, left + v1.getMeasuredWidth(), top+v1.getMeasuredHeight());
        } else if (type == NEXT_LINE) {
            View v0 = getChildAt(0);
            View v1 = getChildAt(1);
            //设置第二个view换行显示
            v0.layout(0, 0, v0.getMeasuredWidth(), v0.getMeasuredHeight());
            v1.layout(0, v0.getMeasuredHeight(), v1.getMeasuredWidth(), v0.getMeasuredHeight() + v1.getMeasuredHeight());
        }
    }

    /**
     * 得到Textview绘制文字的基本信息
     * @param text Textview的文字内容
     * @param maxWidth Textview的宽度
     * @param paint 绘制文字的paint
     */
    private void initTextParams(CharSequence text, int maxWidth, TextPaint paint) {
        StaticLayout staticLayout = new StaticLayout(text, paint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
        int lineCount = staticLayout.getLineCount();
        lastLineTop = staticLayout.getLineTop(lineCount - 1);
        lastLineRight = staticLayout.getLineRight(lineCount - 1);
    }

}


推荐的一款开源加载动画插件

https://gitcode.net/mirrors/81813780/avloadingindicatorview?utm_source=csdn_github_accelerator

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值