效果
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);
}
}