【Android】画面卡顿优化列表流畅度五之下拉刷新上拉加载更多组件RefreshLayout修改

news2024/11/26 1:57:13

之前也写过类似组件的介绍:
地址:下拉刷新&上拉加载更多组件SmartRefreshLayout
在这里插入图片描述
本来打算用这个替换的,但在进行仔细研究发现不太合适。功能都很好,但嵌入不了当前的工程体系里。原因就是那啥体制懂的都懂。这样的组件需要改的工程配置参数会有不兼容。所以也就暂时用不了。
如果能用这个替换也不会组件问题了,大概是这样吧。
当前也是一款开源组件
回顾一下列表布局和逻辑处理:
xml布局

 <android.support.v4.widget.NestedScrollView
            android:id="@+id/nestedScrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <live.bingoogolapple.refreshlayout.BGARefreshLayout
                android:id="@+id/mRefreshLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/recycleView_playback"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="#FFFFFFFF"
                    android:nestedScrollingEnabled="false"
                    android:paddingLeft="20dp"
                    android:paddingRight="10dp"
                    android:paddingBottom="8dp"
                    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
            </live.bingoogolapple.refreshlayout.BGARefreshLayout>
        </android.support.v4.widget.NestedScrollView>

java逻辑处理:

 BGARefreshViewHolder bgaNormalRefreshViewHolder = new BGANormalRefreshViewHolder(this, true);
        mRefreshLayout.setRefreshViewHolder(bgaNormalRefreshViewHolder);

        nestedScrollView = findViewById(R.id.nestedScrollView);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            nestedScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
                @Override
                public void onScrollChange(View view, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                    NestedScrollView toNesstedScrollView = (NestedScrollView) view;
                   
                    if (scrollY < 5
                            || toNesstedScrollView.getChildAt(0).getMeasuredHeight()
                            == view.getMeasuredHeight()) {
                        return;
                    }
                    int height = toNesstedScrollView.getChildAt(0).getMeasuredHeight()
                            - view.getMeasuredHeight();
                    if (scrollY == height) {
                        // 为BGARefreshLayout 设置代理
                        if(mRefreshLayout.getDelegate()==null){
                             mRefreshLayout.setDelegate(XXXXActivity.this);
                        }
                        mRefreshLayout.beginLoadingMore();
                    }
                }
            });
        }

这个布局是为了达到类似如下图这样的头部效果的:
在这里插入图片描述
这个之前也有过这样布局的博客介绍:【Android】折叠效果CoordinatorLayout+AppBarLayout首页效果&& CoordinatorLayout抖动问题解决方案–100个经典UI设计模板(95/100)

问题症结点

NestedScrollView嵌套子组件BGARefreshLayout;BGARefreshLayout嵌套子组件:RecyclerView;
滑动控制监听器是NestedScrollView组件里的OnScrollChangeListener:

nestedScrollView = findViewById(R.id.nestedScrollView);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            nestedScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
                @Override
                public void onScrollChange(View view, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                    NestedScrollView toNesstedScrollView = (NestedScrollView) view;
                  
                    if (scrollY < 5
                            || toNesstedScrollView.getChildAt(0).getMeasuredHeight()
                            == view.getMeasuredHeight()) {
                        return;
                    }
                    int height = toNesstedScrollView.getChildAt(0).getMeasuredHeight()
                            - view.getMeasuredHeight();
                    if (scrollY == height) {
                        // 为BGARefreshLayout 设置代理
                        if(mRefreshLayout.getDelegate()==null){
                             mRefreshLayout.setDelegate(XXXXActivity.this);
                            mRefreshLayout.setParentView(nestedScrollView);
                        }
                        mRefreshLayout.beginLoadingMore();
                    }
                }
            });
        }

导致了上拉刷新和下拉加载更多出现了监听问题
BGARefreshLayout里监听逻辑如下:

@Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        // 被添加到窗口后再设置监听器,这样开发者就不必烦恼先初始化RefreshLayout还是先设置自定义滚动监听器
        if (!mIsInitedContentViewScrollListener && mLoadMoreFooterView != null) {
            setRecyclerViewOnScrollListener();
            setAbsListViewOnScrollListener();

            addView(mLoadMoreFooterView, getChildCount());

            mIsInitedContentViewScrollListener = true;
        }
    }

预期setRecyclerViewOnScrollListener()里的设置就没有生效:

/**
     *
     * 具体效果要看xml布局结构
     * 比如下面这样的就不适用:
     * NestedScrollView
     *          BGARefreshLayout
     *                  RecyclerView
     *
     * */
    private void setRecyclerViewOnScrollListener() {
        if (mRecyclerView != null) {
            mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    if ((newState == RecyclerView.SCROLL_STATE_IDLE
                            || newState == RecyclerView.SCROLL_STATE_SETTLING)
                            && shouldHandleRecyclerViewLoadingMore(mRecyclerView)) {
                        beginLoadingMore();
                        return;
                    }

                }

                /**
                 * dx : 水平滚动距离
                 * dy : 垂直滚动距离
                 * */
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
//                    Log.d(TAG, "dx = " + dx + " ,dy= " + dy);
                    if (dy < 0) {//时为手指向下滚动,列表滚动显示上面的内容
                        mLoadMoreFooterView.setVisibility(GONE);
                    }
                }
            });
        }
    }

找谁说理去,不生效就算了,问题是如果不留意。根本就发现不了这样的组件问题
NestedScrollView组件里的OnScrollChangeListener和RecyclerView.OnScrollListener效果是一致的都是开始加载更多逻辑beginLoadingMore():

/**
     * 开始上拉加载更多,会触发delegate的onBGARefreshLayoutBeginRefreshing方法
     */
    public void beginLoadingMore() {
        Log.d(TAG, "beginLoadingMore: called!");
        if (!mIsLoadingMore && mLoadMoreFooterView != null
                && mDelegate != null
                && mDelegate.onBGARefreshLayoutBeginLoadingMore(this)) {
            mIsLoadingMore = true;
            Log.d(TAG, "run:mIsLoadingMore=" + mIsLoadingMore);
            if (mIsShowLoadingMoreView) {
                showLoadingMoreView();
            }
        }
    }

/**
     * 显示上拉加载更多控件
     */
    public void showLoadingMoreView() {
        mRefreshViewHolder.changeToLoadingMore();
        mLoadMoreFooterView.setVisibility(VISIBLE);
        mLoadMoreFooterView.findViewById(R.id.layout_loading).setVisibility(VISIBLE);
        mLoadMoreFooterView.findViewById(R.id.tv_normal_refresh_footer_status_finish).setVisibility(GONE);

      BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView);
        BGARefreshScrollingUtil.scrollToBottom(mScrollView);
        BGARefreshScrollingUtil.scrollToBottom(mRecyclerView);
        BGARefreshScrollingUtil.scrollToBottom(mAbsListView);
        if (mStickyNavLayout != null) {
            mStickyNavLayout.scrollToBottom();
        }
    }

BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView) 这个是优化后新加的;
如果没有这个就会出现了滑到底部就直接进行加载更多了,不会出现加载更多进度条的提示。需要在滑动到列表底部后再次向上拉一下才能有提示UI画面。这个太隐蔽了,每次感觉怪怪的,但就是没有发现这个交互画面有情况。主要是也不会朝这方面去想。因为看上去都很自然且正常。

showLoadingMoreView里这句代码
BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView)是告诉列表当滑动到底部的时候显示提示mLoadMoreFooterView视图后再自动的向上滑动一下,把LoadMoreFooterView显示在屏幕里。

BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView)逻辑如下:

 /**
     * nestedScrollView 滚动组件设置滚动到底部
     * 采用post(new runnable)方式在滚动组件渲染完成之后滚动到底部
     *
     * @param nestedScrollView 滚动组件
     * */
    public static void scrollToBottom(final NestedScrollView nestedScrollView) {
        if (nestedScrollView != null) {
            nestedScrollView.post(new Runnable() {
                @Override
                public void run() {
                    nestedScrollView.fullScroll(ScrollView.FOCUS_DOWN);
                }
            });
        }
    }

小结一下

就是因为这个滑动效果不兼容所以导致了后面一系列的魔幻情况:
1、加载更多上拉交互的时候看不到加载更多提示UI,因为没有自动向上滑动到底;所以很多时候是没有看到
在这里插入图片描述
2、然后就会导致发起新一页数据的api请求调用的间隔时间混乱,有在短时间内多次调用的情况发生,然后再这个时间段内加载了大量的数据导致了页面卡住了。页面越卡,发起请求连续性导致的问题就越严重。然后用户会滑动更多次。陷入了死循环里了。检测到的某次调试的时候发起的连续的和预期不符的api数据请求记录如下图。
在这里插入图片描述
3、然后必然的内存消耗急剧加大,内存压力在很短的时间陡然上升(事实上优化到最后和内存的关系不是特别大,优化完以后也不过是使用了clearMemory

以上这些问题都是RefreshLayout使用不当导致的。但不投入大量的精力去仔细的分析网络数据、内存、交互等几乎发现不了。因为手机画面表现的很像是内存问题,因此在内存上折腾了两三天也没起到缓解卡顿的预期。

解决方案

最后附上优化后的RefreshLayout逻辑处理:



import live.bingoogolapple.refreshlayout.util.BGARefreshScrollingUtil;

/**
 * 作者:王浩 邮件:bingoogolapple@gmail.com
 * 创建时间:15/5/21 22:35
 * 描述:下拉刷新、上拉加载更多、可添加自定义(固定、可滑动)头部控件(例如慕课网app顶部的广告位)
 */
public class BGARefreshLayout extends LinearLayout {
  
    /**
     * 目前已经适配的滚动组件有:
     *  AbsListView
     *  ScrollView
     *  NestedScrollView
     *  RecyclerView
     *
     *  在滚动到底部时自动在底部增加弹出"正在加载中的"进度条提示
     * */
    private AbsListView mAbsListView;
    private ScrollView mScrollView;
    private NestedScrollView mParentNestedScrollView;// 外层父组件嵌套 NestedScrollView
    private RecyclerView mRecyclerView;
    private View mNormalView;
    private WebView mWebView;
    private BGAStickyNavLayout mStickyNavLayout;
    private View mContentView;

    private float mInterceptTouchDownX = -1;
    private float mInterceptTouchDownY = -1;
    /**
     * 按下时整个头部控件的paddingTop
     */
    private int mWholeHeaderViewDownPaddingTop = 0;
    /**
     * 记录开始下拉刷新时的downY
     */
    private int mRefreshDownY = -1;

    /**
     * 是否已经设置内容控件滚动监听器
     */
。。。

    /**
     * xml布局中构造
     * */
    public BGARefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOrientation(LinearLayout.VERTICAL);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mHandler = new Handler(Looper.getMainLooper());
        initWholeHeaderView();
    }

  。。。
    /**
     * {@link BGARefreshLayout} 外层嵌套一个父滚动组件适配
     * 目前适配了NestedScrollView 作为父组件
     *
     * */
    public void setParentView(View view) {

        if (null == view)
            return;
        /**
         * 布局嵌套为
         * NestedScrollView
         *          BGARefreshLayout
         *                  RecyclerView
         * */
        if (view instanceof NestedScrollView) {
            mParentNestedScrollView = (NestedScrollView) view;
        }
    }

   
    /**
     * 初始化上拉加载更多控件
     *
     * @return
     */
    private void initLoadMoreFooterView() {
        mLoadMoreFooterView = mRefreshViewHolder.getLoadMoreFooterView();
        if (mLoadMoreFooterView != null) {
            // 测量上拉加载更多控件的高度
            mLoadMoreFooterView.measure(0, 0);
            mLoadMoreFooterViewHeight = mLoadMoreFooterView.getMeasuredHeight();
            mLoadMoreFooterView.setVisibility(GONE);
            mLoadMoreFooterView.findViewById(R.id.layout_loading).setVisibility(GONE);
            mLoadMoreFooterView.findViewById(R.id.tv_normal_refresh_footer_status_finish).setVisibility(GONE);
        }
    }



    /**
     *
     * 具体效果要看xml布局结构
     * 比如下面这样的就不适用:
     * NestedScrollView
     *          BGARefreshLayout
     *                  RecyclerView
     *
     * */
    private void setRecyclerViewOnScrollListener() {
        if (mRecyclerView != null) {
            mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    if ((newState == RecyclerView.SCROLL_STATE_IDLE
                            || newState == RecyclerView.SCROLL_STATE_SETTLING)
                            && shouldHandleRecyclerViewLoadingMore(mRecyclerView)) {
                        beginLoadingMore();
                        return;
                    }

                }

                /**
                 * dx : 水平滚动距离
                 * dy : 垂直滚动距离
                 * */
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
//                    Log.d(TAG, "dx = " + dx + " ,dy= " + dy);
                    if (dy < 0) {//时为手指向下滚动,列表滚动显示上面的内容
                        mLoadMoreFooterView.setVisibility(GONE);
                    }
                }
            });
        }
    }

 

    /**
  
    /**
     * 开始上拉加载更多,会触发delegate的onBGARefreshLayoutBeginRefreshing方法
     */
    public void beginLoadingMore() {
        Log.d(TAG, "beginLoadingMore: called!");
        if (!mIsLoadingMore && mLoadMoreFooterView != null
                && mDelegate != null
                && mDelegate.onBGARefreshLayoutBeginLoadingMore(this)) {
            mIsLoadingMore = true;
            Log.d(TAG, "run:mIsLoadingMore=" + mIsLoadingMore);
            if (mIsShowLoadingMoreView) {
                showLoadingMoreView();
            }
        }
    }

    /**
     * 显示上拉加载更多控件
     */
    public void showLoadingMoreView() {
        mRefreshViewHolder.changeToLoadingMore();
        mLoadMoreFooterView.setVisibility(VISIBLE);
        mLoadMoreFooterView.findViewById(R.id.layout_loading).setVisibility(VISIBLE);
        mLoadMoreFooterView.findViewById(R.id.tv_normal_refresh_footer_status_finish).setVisibility(GONE);

        BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView);
        BGARefreshScrollingUtil.scrollToBottom(mScrollView);
        BGARefreshScrollingUtil.scrollToBottom(mRecyclerView);
        BGARefreshScrollingUtil.scrollToBottom(mAbsListView);
        if (mStickyNavLayout != null) {
            mStickyNavLayout.scrollToBottom();
        }
    }

    /**
     * 结束上拉加载更多
     */
    public void endLoadingMore() {
        if (mIsShowLoadingMoreView) {
            // 避免WiFi环境下请求数据太快,加载更多控件一闪而过
            mRecyclerView.postDelayed(mDelayHiddenLoadingMoreViewTask, 300);
        }
    }
    public void setStatusFinish() {
        mLoadMoreFooterView.setVisibility(VISIBLE);
        mLoadMoreFooterView.findViewById(R.id.tv_normal_refresh_footer_status_finish)
                .setVisibility(VISIBLE);
        BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView);
        BGARefreshScrollingUtil.scrollToBottom(mScrollView);
        BGARefreshScrollingUtil.scrollToBottom(mRecyclerView);
        BGARefreshScrollingUtil.scrollToBottom(mAbsListView);
        if (mStickyNavLayout != null) {
            mStickyNavLayout.scrollToBottom();
        }
    }

    

主要是新增了对NestedScrollView的处理逻辑;也是为了适配如下这样的xml布局:

 /**
         * 布局嵌套为
         * NestedScrollView
         *          BGARefreshLayout
         *                  RecyclerView
         * */

再加上 BGARefreshScrollingUtil.scrollToBottom(mParentNestedScrollView);处理完成了这个上拉加载更多的数据分页加载逻辑衔接处理。
优化这个组件之后加载顺滑度立马就干到数据量800条以内滑动和加载都没有明显的卡顿感了。
但问题还没有彻底解决,因为数据量干到1000条左右就出现了ANR问题和OOM内存问题了。虽然这两个问题没有得到彻底的解决,但大致的解决方案也有方向。
先到这里歇一歇,后面还有一篇

smartApi接口开发工具推荐

历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:

  • api参数填写
  • api请求响应数据展示
  • PDF形式的分享文档
  • Mock本地化解决方案
  • api列表数据本地化处理
  • 再加上UI方面的打磨

下面是一段smartApi使用介绍:
在这里插入图片描述

下载地址:

https://pan.baidu.com/s/1kFAGbsFIk3dDR64NwM5y2A?pwd=csdn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1208330.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣 225. 用队列实现栈(C语言实现)

目录 1.解题思路2.代码实现 1.解题思路 这道题如果使用C会好写的多&#xff0c;因为可以使用C提供的队列来实现&#xff0c;但如果使用C语言则必须手写一个队列来实现&#xff0c;在这里我用了我前面文章中实现好的队列来解答&#xff0c;首先因为队列是先进先出&#xff0c;而…

揭秘视频号创作者分成计划,带你玩赚视频号流量主,保姆级教程

项目介绍 今天给大家分享一个视频号流量主的一个项目&#xff0c;也就是视频号创作者广告分成计划。这个项目在目前来说是一个蓝海赛道&#xff0c;做的人是比较少&#xff0c;作为副业来说还是非常适合个人来做的。如果大家有工作室的话&#xff0c;也可以进行批量操作&#…

2021年06月 Scratch(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题(共25题,每题2分,共50分) 第1题 小猫位置在舞台中心,点击一次小猫后能前进10步的程序为? A: B: C: D: 答案:B 第2题 快速切换到下一个背景图片应该使用哪个积木? A: B:

MySQL库的操作『增删改查 ‖ 编码问题 ‖ 备份与恢复』

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; MySQL 学习 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 &#x1f381;软件版本&#xff1a; MySQL 5.7.44 文章目录 1.创建数据库2.数据库中的编码问题2.1.字符集与校验集2.3.支持的字符…

环保气膜建筑的运维成本在哪几个方面

作为一种环保建筑&#xff0c;气膜结构在工业和文体领域得到了广泛认可。尽管气膜建筑在经济上具有明显的优势&#xff0c;但对于不了解它的人来说&#xff0c;他们可能会下意识地认为在运营和维护过程中会产生大量费用。今天&#xff0c;让我们一起了解一下气膜建筑在运营维护…

【蓝桥杯选拔赛真题68】Scratch打地鼠游戏 少儿编程scratch图形化编程 蓝桥杯创意编程选拔赛真题解析

目录 scratch打地鼠游戏 一、题目要求 编程实现 二、案例分析 1、角色分析

未来之路:大模型技术在自动驾驶的应用与影响

本文深入分析了大模型技术在自动驾驶领域的应用和影响&#xff0c;万字长文&#xff0c;慢慢观看~ 文中首先概述了大模型技术的发展历程&#xff0c;自动驾驶模型的迭代路径&#xff0c;以及大模型在自动驾驶行业中的作用。接着&#xff0c;详细介绍了大模型的基本定义、基础功…

【论文阅读】(CTGAN)Modeling Tabular data using Conditional GAN

论文地址&#xff1a;[1907.00503] Modeling Tabular data using Conditional GAN (arxiv.org) 摘要 对表格数据中行的概率分布进行建模并生成真实的合成数据是一项非常重要的任务&#xff0c;有着许多挑战。本文设计了CTGAN&#xff0c;使用条件生成器解决挑战。为了帮助进行公…

数据同步到Redis消息队列,并实现消息发布/订阅

一、假设需求&#xff1a; 某系统在MySQL某表中操作了一条数据在其他系统中&#xff0c;实时获取最新被操作数据的数据库名、数据表名、操作类型、数据内容 应用场景&#xff1a; 按最近项目的一个需求来说&#xff1a; 1.当某子系统向报警表中新增了一条报警数据&#xff1b;…

外包能做多久?这才是掩藏在虚假繁荣后的真实

讲一下我的故事和想法&#xff0c;你们自己寻思一下 我25岁&#xff0c;中级测试&#xff0c;外包&#xff0c;薪资13.5k&#xff0c;人在上海。 内卷什么的就不说了&#xff0c;而且人在外包那些高级精英年薪大几十的咱也接触不到&#xff0c;就说说外包吧。 假设以我为界限…

2023年亚太杯数学建模思路 - 案例:ID3-决策树分类算法

文章目录 0 赛题思路1 算法介绍2 FP树表示法3 构建FP树4 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模…

GB28181/GB35114国标平台LiveGBS适配国产信创环境,使用国产数据库达梦数据库、高斯数据库、瀚高数据库的配置方法...

1、如何配置切换信创达梦数据库&#xff1f; livecms.ini -> [db]下面添加配置如&#xff1a; ... [db] dialectdm url dm://SYSDBA:Aa12345678localhost:5236/livegbs 2、如何配置切换高斯数据库&#xff1f; livecms.ini -> [db]下面添加配置如&#xff1a; ... [db] d…

【论文阅读】CTAB-GAN: Effective Table Data Synthesizing

论文地址&#xff1a;[2102.08369] CTAB-GAN: Effective Table Data Synthesizing (arxiv.org) 介绍 虽然数据共享对于知识发展至关重要&#xff0c;但遗憾的是&#xff0c;隐私问题和严格的监管&#xff08;例如欧洲通用数据保护条例 GDPR&#xff09;限制了其充分发挥作用。…

爱上C语言:整型和浮点型在内存中的存储(进制转换,原码,反码,补码以及大小端)

&#x1f680; 作者&#xff1a;阿辉不一般 &#x1f680; 你说呢&#xff1a;生活本来沉闷&#xff0c;但跑起来就有风 &#x1f680; 专栏&#xff1a;爱上C语言 &#x1f680;作图工具&#xff1a;draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话&#xff0c;还请…

深度学习之基于YoloV5钢材表面缺陷检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 深度学习技术在计算机视觉领域的应用为表面缺陷检测系统的发展提供了强大的推动力。本文将介绍基于YoloV5的钢材表面…

算法训练 第七周

一、最小栈 本题要求我们实现一个最小栈数据结构&#xff0c;要求它可以实现栈的基本功能&#xff0c;并且还能使用常数时间复杂度来获取栈中的最小值。 1.辅助栈 我们可以在普通栈的基础上再添加一个维护最小值的辅助栈来实现这个数据结构&#xff0c;我们先创建一个普通的栈…

李想「避战」后,问界的下一个对手是谁?

作者 | 魏启扬 来源 | 洞见新研社 10月份&#xff0c;理想卖出了40422台车&#xff0c;又一次刷新了自己的历史纪录。 饶是如此&#xff0c;一向锋芒毕露的理想汽车创始人李想面对华为时&#xff0c;还是选择了“避战”&#xff0c;“不和华为吵架&#xff0c;实在吵不过”。…

请求头,响应头

目录 常见的请求方式 GET/POST HEAD&#xff08;报文首部&#xff0c;验证URI有效性&#xff09; PUT/DELETE(报文文件) OPTIONS&#xff08;查询URI支持的HTTP方法&#xff09; Connection: keep-alive TCP 就会一直保持连接。 Cache-Control public&#xff1a;响应…

vscode删除后重装还有原来的配置问题,彻底删除vscode,删除vscode安装过的插件和缓存

VSCode卸载后进行重新安装&#xff0c;发现新安装的还有原来的一些配置&#xff0c;卸载的不彻底&#xff0c;有时候也容易出问题&#xff0c;可按照如下方法卸载干净&#xff1a; 1.进入控制面板卸载VSCode&#xff0c;也可以在VSCode的安装目录下用程序自带的卸载程序 2.这…

视频直播点播平台EasyDSS无法删除分组,如何解决?

EasyDSS视频推拉流平台可支持用户自行上传视频文件&#xff0c;也可将上传的点播文件作为虚拟直播进行播放。平台能支持多屏播放&#xff0c;可兼容Windows、Android、iOS、Mac等操作系统&#xff0c;还能支持CDN转推&#xff0c;具备较强的可拓展性与灵活性。 有用户反馈&…