android实现评论区功能
效果
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"><LinearLayoutandroid:id="@+id/fl_top"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#fff"android:gravity="center_vertical"android:orientation="vertical"><Viewandroid:id="@+id/v_status_seat"android:layout_width="match_parent"android:layout_height="0dp"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:padding="5dp"><ImageViewandroid:layout_width="23dp"android:id="@+id/iv_back"android:layout_height="wrap_content"android:src="@mipmap/title_left" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="15dp"android:gravity="center_vertical"><ImageViewandroid:id="@+id/iv_ta_logo"android:layout_width="35dp"android:layout_height="35dp"android:src="@mipmap/ic_head_default" /><TextViewandroid: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.RecyclerViewandroid: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>--><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="#fff"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="#F0F0F0" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:orientation="horizontal"android:paddingLeft="15dp"android:paddingRight="15dp"><LinearLayoutandroid: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"><ImageViewandroid:layout_width="15dp"android:layout_height="15dp"android:src="@mipmap/edit" /><TextViewandroid: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><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="right"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center_vertical"android:orientation="horizontal"><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@mipmap/love_black" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="2dp"android:text="150"android:textColor="#323131" /></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:gravity="center_vertical"android:orientation="horizontal"><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@mipmap/sc_black" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="2dp"android:text="收藏"android:textColor="#323131" /></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:gravity="center_vertical"android:orientation="horizontal"><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@mipmap/msg_black" /><TextViewandroid: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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_detail);StatusBarUtil.setLightStatusBar(this, true, true);initView();initListener();}@Overrideprotected 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);}@Overrideprotected void initListener() {ivBack.setOnClickListener(this);// 滑动监听recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic 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("没有更多数据");}}}});}@Overridepublic 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;}@Overridepublic 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() {@Overridepublic int getSpanSize(int position) {return 6;}});}}@Overridepublic 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;}}@Overridepublic 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>() {@Overridepublic 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);}@Overridepublic 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() {@Overridepublic void run() {try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}((Activity)context).runOnUiThread(new Runnable() {@Overridepublic 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() {@Overridepublic boolean onPreDraw() {parent.getViewTreeObserver().removeOnPreDrawListener(this);ViewGroup.LayoutParams layoutParams = (ViewGroup.LayoutParams) lf.getLayoutParams();layoutParams.width = parent.getWidth();lf.setLayoutParams(layoutParams);return true;}});}}@Overridepublic int getItemCount() {return datas.size();}@Overridepublic 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.Bannerandroid: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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:padding="15dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="趁年轻 多去经历吧"android:textColor="#F3000000"android:textSize="18sp" /><TextViewandroid: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" /><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:layout_marginTop="15dp"android:background="#F0F0F0" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:textSize="12sp"android:text="共6条评论"android:textColor="#676666" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="15dp"android:gravity="center_vertical"android:orientation="horizontal"><ImageViewandroid:id="@+id/iv_my_logo"android:layout_width="35dp"android:layout_height="35dp"android:src="@mipmap/ic_head_default" /><TextViewandroid: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"><LinearLayoutandroid:layout_width="wrap_content"android:orientation="vertical"android:gravity="center_horizontal"android:paddingLeft="5dp"android:paddingRight="5dp"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/iv_user_avatar"android:src="@mipmap/ic_head_default"android:layout_width="35dp"android:layout_height="35dp"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:orientation="vertical"android:layout_height="wrap_content"><LinearLayoutandroid:orientation="horizontal"android:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="0dp"android:layout_weight="1"android:orientation="vertical"android:layout_height="wrap_content"><TextViewandroid: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.LayoutForTextViewandroid:layout_width="match_parent"android:id="@+id/lf_talk_text"android:layout_gravity="center_vertical"android:layout_height="wrap_content"><TextViewandroid:id="@+id/tv_talk_content"android:textColor="#3E3E3E"android:textSize="13sp"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid: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><LinearLayoutandroid:layout_width="30dp"android:gravity="right"android:layout_height="wrap_content"><ImageViewandroid:src="@mipmap/love"android:layout_width="25dp"android:layout_height="25dp"/></LinearLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:orientation="vertical"android:layout_height="wrap_content"><com.coral3.common_module.components.TalkChildListandroid:id="@+id/tcl_list"android:layout_width="match_parent"android:layout_height="wrap_content"/></LinearLayout><TextViewandroid: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"/><LinearLayoutandroid: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.AVLoadingIndicatorViewandroid:id="@+id/avi_loading"android:layout_width="20dp"android:layout_height="20dp"app:indicatorColor="#A8A7A7"app:indicatorName="BallRotateIndicator"/><TextViewandroid: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><TextViewandroid: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"><LinearLayoutandroid:layout_width="wrap_content"android:orientation="vertical"android:paddingRight="5dp"android:gravity="center_horizontal"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/iv_user_avatar"android:src="@mipmap/ic_head_default"android:layout_width="20dp"android:layout_height="20dp"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:orientation="vertical"android:layout_height="wrap_content"><LinearLayoutandroid:orientation="horizontal"android:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="0dp"android:layout_weight="1"android:orientation="vertical"android:layout_height="wrap_content"><TextViewandroid: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.LayoutForTextViewandroid:layout_width="match_parent"android:id="@+id/lf_talk_text"android:layout_gravity="center_vertical"android:layout_height="wrap_content"><TextViewandroid:id="@+id/tv_talk_content"android:textColor="#3E3E3E"android:textSize="13sp"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid: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><LinearLayoutandroid:layout_width="30dp"android:gravity="right"android:layout_marginRight="0dp"android:layout_height="wrap_content"><ImageViewandroid: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;}@Overridepublic 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() {@Overridepublic int getSpanSize(int position) {return 6;}});}}@Overridepublic 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;}@Overridepublic void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {if(holder instanceof TalkViewHolder) {TalkViewHolder talkViewHolder = (TalkViewHolder) holder;if (listener != null) {talkViewHolder.llTalkItem.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {listener.myClick(v,position);}});// set LongClicktalkViewHolder.llTalkItem.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic 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() {@Overridepublic 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);}@Overridepublic int getItemCount() {return datas.size();}@Overridepublic 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() {@Overridepublic void myClick(View v, int pos) {LogUtil.d("onClick " + pos);}@Overridepublic 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() {@Overridepublic void run() {try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}((Activity)mContext).runOnUiThread(new Runnable() {@Overridepublic 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);}@Overrideprotected 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");}}@Overrideprotected 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
相关文章:

android实现评论区功能
效果 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…...

Java每日一练(20230319)
目录 1. 最大矩形 🌟🌟🌟 2. 回文对 🌟🌟🌟 3. 给表达式添加运算符 🌟🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练…...

Redis缓存双写一致性
目录双写一致性Redis与Mysql双写一致性canal配置流程代码案例双写一致性理解缓存操作细分缓存一致性多种更新策略挂牌报错,凌晨升级先更新数据库,在更新缓存先删除缓存,在更新数据库先更新数据库,在删除缓存延迟双删策略总结双写一致性 Redis与Mysql双写一致性 canal 主要是…...

【2023-Pytorch-检测教程】手把手教你使用YOLOV5做交通标志检测
项目下载地址:YOLOV5交通标志识别检测数据集代码模型教学视频-深度学习文档类资源-CSDN文库 交通标志的目标检测算法在计算机视觉领域一直属于热点研究问题,改进的优化算法不断地被提出。国内外许多学者针对现有的目标检测方法中网络结构、目标定位、损…...

Java中的二叉树
文章目录前言一、树形结构(了解)1.1 概念1.2 概念(重要)1.3 树的表示形式(了解)1.4 树的应用二、二叉树(重点)2.1 概念2.2 两种特殊的二叉树2.3 二叉树的性质2.5 二叉树的存储2.5 二…...

基于 gma 绘制古代洛阳 5 大都城遗址空间分布地图
了解 gma gma 是什么? gma 是一个基于 Python 的地理、气象数据快速处理和数据分析函数包(Geographic and Meteorological Analysis,gma)。gma 网站:地理与气象分析库。 gma 的主要功能有哪些? 气候气象&a…...

分析 Spring 的依赖注入模式
一、依赖注入二、Field Injection优点缺点三、Constructor Injection优点1. 容易发现 code smell优点2. 容易厘清依赖关系优点3. 容易写单元测试优点4. Immutable Object缺点:循环依赖四、总结一、依赖注入 依赖注入 (Dependency Injection,…...

IntelliJ IDEA创建Servlet
目录 ——————————————————————————————— 一、创建Java项目 1、创建java项目 2、选择java 3、next 4、给项目命名 5、新创建完java项目的目录结构 二、变java为servlet项目 1、变servlet项目 2、选择Web Application 3、更新完成后的目录…...

Spring Boot如何让自己的bean优先加载
背景介绍 在一些需求中,可能存在某些场景,比如先加载自己的bean,然后自己的bean做一些DB操作,初始化配置问题,然后后面的bean基于这个配置文件,继续做其他的业务逻辑。因此有了本文的这个题目。 实现方法…...

LeetCode分类刷题----动态规划
动态规划509.斐波那契数列70.爬楼梯746.使用最小花费怕楼梯62.不同路径63.不同路径||343.整数拆分96.不同的二叉搜索树01背包问题416.分割等和子集1049.最后一块石头的重量||494.目标和474.一和零完全背包问题518.零钱兑换||377.组合总和IV322.零钱兑换279.完全平方数139.单词拆…...

今年好像没有金三银四了?
大家好,我是记得诚。 金三银四,是换工作的高峰期,新的一年结束了,在年前拿完年终奖,在年后3月和4月换个满意的工作。 单从我公司来看,目前还没有一个人离职,往年离职率是要高一些的。 还有我…...

【C++】入门知识之 函数重载
前言提到重载这个词,我们会想到什么呢?重载有一种一词多义的意思,中华文化博大精深,之前有一个笑话,中国的乒乓球谁都打不过,男足谁都打不过,哈哈哈这也是非常有意思的,但是今天我们…...

文心一言发布,你怎么看?chatGPT
百度全新一代知识增强大语言模型“文心一言”于2021年3月16日正式发布,作为一款自然语言处理技术,它引起了广泛的关注和讨论。 首先,文心一言是一款具有重大意义的自然语言处理技术。在人工智能领域,自然语言处理技术一直是一个难…...

字符函数和字符串函数【上篇】
文章目录🎖️1.函数介绍📬1.1. strlen📬1.2. strcpy📬1.3. strcat📬1.4. strcmp📬1.5. strncpy📬1.6. strncat📬1.7. strncmp🎖️1.函数介绍 📬1.1. strlen …...

list的模拟实现(模仿STL)
目录 一、模拟实现前的准备 1.list结构认识 2.迭代器的实现不同 3.如何实现需要的功能 二.结点类实现 三.迭代器实现 1.实现前的问题 2._list_iterator类的成员变量和构造函数 3.*和->运算符重载 4.前置和后置的实现 5.前置--和后置-- 6.和!运算符重载 四.list类的实现 1.li…...

05-STM32F1 - 串行通信SPI
SPI STM-SPI作为主机,从机 SPI的时钟,最高为Pclk/2,SPI1最高为36Mhz,SPI2最高为18Mhz。 SPI的四种模式 CPOL CPHA,数据帧8~16位,LSB,MSB 全双工,双向单线,单线 物理层 接口标准…...

【Pytorch】Tensor的分块、变形、排序、极值与in-place操作
本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052 这是目录Tensor的分块Tensor的变形Tensor的排序Tensor的极值Tensor的in-place操作Tensor是PyTorch中用于存储和处理多维数据的基本数据结构,它类似于NumPy中的ndarray&…...

数组栈的实现
个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【数据结构初阶(C实现)】 目录所有接口函数栈的初始化在栈顶放数据释放数据删除数据取栈顶的数据判断栈取区是否为…...

*p++,*(p++),*++p,(*p)++区别?
*p++:等同于:*p; p += 1; 解析:由于和++的运算优先级一样,且是右>结合。故p++相当于*(p++),p先与++结合,>然后p++整体再与结合。前面陈述是一种最 常见的错误,很多初学者也是这么理解的。 但是,因为++后置的时候,本身含义就是先 运算后增加1(运算指的是p++作为…...

又一个线上偶发问题-系统短暂无法获取到Redis连接
概述 最近不知道咋回事,老是在线上遇到偶发的故障,它突然出现,又很快消失了。 在2023年3月11下午差不多六点左右,我正在工位上喝着香味扑鼻的金骏眉红茶,突然接到了一个电话,拿起手机一看,是阿里…...

[ 系统安全篇 ] 拉黑IP - 火绒安全软件设置IP黑名单 windows使用系统防火墙功能设置IP黑名单
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...

MongoDB【部署 01】mongodb最新版本6.0.5安装部署配置使用及mongodb-shell1.8.0安装使用(云盘分享安装文件)
云盘分享文件: 链接:https://pan.baidu.com/s/11sbj1QgogYHPM4udwoB1rA 提取码:l2wz 1.mongodb简单介绍 MongoDB的 官网 内容还是挺丰富的。 是由 C语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下&…...

算法竞赛必考算法——动态规划(01背包和完全背包)
动态规划(一) 目录动态规划(一)1.01背包问题1.1题目介绍1.2思路一介绍(二维数组)1.3思路二介绍(一维数组) 空间优化1.4思路三介绍(输入数据优化)2.完全背包问题2.1题目描述:2.2思路一(朴素算法)2.3思路二(将k优化处理掉)2.4思路三(优化j的初始条件)总结1.01背包问题…...

基于深度学习的农作物叶片病害检测系统(UI界面+YOLOv5+训练数据集)
摘要:农作物叶片病害检测系统用于智能检测常见农作物叶片病害情况,自动化标注、记录和保存病害位置和类型,辅助作物病害防治以增加产值。本文详细介绍基于YOLOv5深度学习模型的农作物叶片病害检测系统,在介绍算法原理的同时&#…...

QT入门Item Views之QListView
目录 一、QListView界面相关 1、布局介绍 二、代码展示 1、创建模型,导入模型 2、 设置隔行背景色 3、删除选中行 三、源码下载 此文为作者原创,创作不易,转载请标明出处! 一、QListView界面相关 1、布局介绍 先看下界面…...

GEE:计算1990-2021年的指数最大值和最小值,并根据最大最小值对每一副影像归一化
本文记录了在GEE平台上计算影像集合中所有像素的最大值和最小值。并且根据该最大最小值对所有影像进行最大最小值归一化。以SAVI为例,记录了主要函数的使用方法和代码。 结果如图所示, 文章目录 一、计算每一副影像的最大值或者最小值,并将最值保存在 List 中二、计算 Lis…...

LeetCode KMP 算法
可以参考https://www.bilibili.com/video/BV1AY4y157yL/kmp 主要做的就是子串匹配,类似C程序的 strstr() 函数记录一下,也防止我自己忘记传统暴力求解算法是源串 ssssssssa 子串 sssa(下面暴力求解) 先 (子串从 0 位置匹配&#x…...

全面剖析OpenAI发布的GPT-4比其他GPT模型强在哪里
最强的文本生成模型GPT-4一、什么是GPT-4二、GPT-4的能力三、和其他GPT模型比较3.1、增加了图像模态的输入3.2、可操纵性更强3.3、复杂任务处理能力大幅提升3.4、幻觉、安全等局限性的改善3.6、风险和缓解措施改善更多安全特性3.7、可预测的扩展四、与之前 GPT 系列模型比较五、…...

leetcode——26. 删除有序数组中的重复项
文章目录🐨1. 题目🏹2. 思路🪃3. 代码实现🐨1. 题目 给你一个升序排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致。 由…...

基于springboot垃圾分类网站设计实现【毕业论文、源码】
摘要本论文主要论述了如何使用JAVA语言开发一个垃圾分类网站,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述垃圾分类网站的当前背景以及系统开发的目的&#x…...