当前位置: 首页 > news >正文

Android 解决TextView多行滑动与NestedScrollView嵌套滑动冲突的问题

关键计算地方:

1.当前是上滑动还是下滑动(相对于屏幕) ,使用ev.getRawY()获得当前滑动位置在屏幕哪个地方

2.  计算文本客滑动到哪里即可停止, (行高*总文本行数)- (行高 * 最多显示行数)   int sum = getLineHeight() * getLineCount() - getLineHeight() * getMaxLines();

代码:

import android.content.Context;
import android.text.method.ScrollingMovementMethod;
import android.util.AttributeSet;
import android.view.MotionEvent;/*** @Description: 可滑动的TextView, 并且解决了与 ScrollView等的滑动冲突*/
public class ScrollTextView extends android.support.v7.widget.AppCompatTextView {public ScrollTextView(Context context) {super(context);setMovementMethod(ScrollingMovementMethod.getInstance());}public ScrollTextView(Context context, AttributeSet attrs) {super(context, attrs);setMovementMethod(ScrollingMovementMethod.getInstance());}public ScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);setMovementMethod(ScrollingMovementMethod.getInstance());}float lastScrollY = 0;@Overridepublic boolean onTouchEvent(MotionEvent ev) {if (getLineCount() > getMaxLines()) {if (ev.getAction() == MotionEvent.ACTION_DOWN) {lastScrollY = ev.getRawY();} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {//滑动到头并且还在继续上滑动,或者滑动到底部就不要再拦截了(有误差)int sum = getLineHeight() * getLineCount() - getLineHeight() * getMaxLines();//计算上次与本次差float diff = lastScrollY - ev.getRawY();if (diff>0){//下滑动并且到达了底部也不要处理了//底部这里用abs的原因是,因为计算sum的时候有些误差if (Math.abs(sum - getScrollY())<5) {getParent().requestDisallowInterceptTouchEvent(false);} else {getParent().requestDisallowInterceptTouchEvent(true);}}else if (diff<0){//上滑动if (getScrollY() == 0) {//上滑动并且已经到达了顶部就不要在处理了getParent().requestDisallowInterceptTouchEvent(false);} else {getParent().requestDisallowInterceptTouchEvent(true);}}lastScrollY = ev.getRawY();} else {getParent().requestDisallowInterceptTouchEvent(false);}}return super.onTouchEvent(ev);}
}

如果上面方法不能解决你的问题,那就参考下面的文章,让textview实现 NestedScroolChild3 接口,并重写相应的方法,从而实现TextView嵌套滑动。

WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X5 webview

我使用的代码:

package com.**.view;
import android.annotation.SuppressLint;
import android.text.StaticLayout;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Layout;
import android.text.TextPaint;
import android.text.method.ScrollingMovementMethod;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewParent;
import android.widget.OverScroller;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.NestedScrollingChild3;
import androidx.core.view.NestedScrollingChildHelper;
import androidx.core.view.ViewCompat;public class JustifyTextView extends androidx.appcompat.widget.AppCompatTextView implements NestedScrollingChild3 {private static final String TAG = "JustifyTextView";private int mLineY;private int mViewWidth;private static final int INVALID_POINTER = -1;private final int[] mScrollOffset = new int[2];private final int[] mScrollConsumed = new int[2];private int mLastMotionY;private NestedScrollingChildHelper mChildHelper;private boolean mIsBeingDragged = false;private VelocityTracker mVelocityTracker;private int mTouchSlop;private int mActivePointerId = INVALID_POINTER;private int mNestedYOffset;private OverScroller mScroller;private int mMinimumVelocity;private int mMaximumVelocity;private int mLastScrollerY;public JustifyTextView(Context context) {super(context);init();}public JustifyTextView(Context context, AttributeSet attrs) {super(context, attrs);init();}public JustifyTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {mScroller = new OverScroller(getContext());setMovementMethod(ScrollingMovementMethod.getInstance());setOverScrollMode(TextView.OVER_SCROLL_NEVER);mChildHelper = new NestedScrollingChildHelper(this);setNestedScrollingEnabled(true);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);}@Overrideprotected void onDraw(Canvas canvas) {TextPaint paint = getPaint();paint.setColor(getCurrentTextColor());// 返回绘制状态的资源ID数组表示视图的当前状态paint.drawableState = getDrawableState();// 对View上的内容进行测量后得到的View内容占据的宽度// 前提是你必须在父布局的onLayout()方法或者此View的onDraw()方法里调用measure(0,0);// 否则你得到的结果和getWidth()得到的结果一样。mViewWidth = getMeasuredWidth();// 获取文本String text = getText().toString();mLineY = 0;mLineY += getTextSize();// 获取用于显示当前文本的布局Layout layout = getLayout();if (layout == null) {return;}Paint.FontMetrics fm = paint.getFontMetrics();int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout.getSpacingAdd());for (int i = 0; i < layout.getLineCount(); i++) {// 返回文本中的指定行开头的偏移int lineStart = layout.getLineStart(i);// 返回文本中的指定行最后一个字符的偏移int lineEnd = layout.getLineEnd(i);float width = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, getPaint());String line = text.substring(lineStart, lineEnd);if (line.equals("")) {break;}if (i < layout.getLineCount() - 1) {if (needScale(line)) {drawScaledText(canvas, lineStart, line, width);} else {
//                    canvas.drawText(line.replace("%", ""), 0, mLineY, paint);canvas.drawText(line, 0, mLineY, paint);}} else {canvas.drawText(line, 0, mLineY, paint);}// 增加行高mLineY += textHeight;}}private void drawScaledText(Canvas canvas, int lineStart, String line,float lineWidth) {float x = 0;if (isFirstLineOfParagraph(lineStart, line)) {String blanks = "  ";canvas.drawText(blanks, x, mLineY, getPaint());float bw = StaticLayout.getDesiredWidth(blanks, getPaint());x += bw;line = line.substring(3);}int gapCount = line.length() - 1;int i = 0;if (line.length() > 2 && line.charAt(0) == 12288&& line.charAt(1) == 12288) {String substring = line.substring(0, 2);float cw = StaticLayout.getDesiredWidth(substring, getPaint());canvas.drawText(substring, x, mLineY, getPaint());x += cw;i += 2;}float d = (mViewWidth - lineWidth) / gapCount;for (; i < line.length(); i++) {String c = String.valueOf(line.charAt(i));float cw = StaticLayout.getDesiredWidth(c, getPaint());canvas.drawText(c, x, mLineY, getPaint());x += cw + d;}}private boolean isFirstLineOfParagraph(int lineStart, String line) {return line.length() > 3 && line.charAt(0) == ' ' && line.charAt(1) == ' ';}private boolean needScale(String line) {if (line.length() == 0) {return false;} else {
//            return line.charAt(line.length() - 1) != '%';return line.charAt(line.length() - 1) != '\n';}}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent ev) {initVelocityTrackerIfNotExists();MotionEvent vtev = MotionEvent.obtain(ev);final int actionMasked = ev.getActionMasked();if (actionMasked == MotionEvent.ACTION_DOWN) {mNestedYOffset = 0;}vtev.offsetLocation(0, mNestedYOffset);switch (actionMasked) {case MotionEvent.ACTION_DOWN:if ((mIsBeingDragged = !mScroller.isFinished())) {final ViewParent parent = getParent();if (parent != null) {parent.requestDisallowInterceptTouchEvent(true);}}if (!mScroller.isFinished()) {abortAnimatedScroll();}mLastMotionY = (int) ev.getY();mActivePointerId = ev.getPointerId(0);startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL, ViewCompat.TYPE_TOUCH);break;case MotionEvent.ACTION_MOVE:final int activePointerIndex = ev.findPointerIndex(mActivePointerId);if (activePointerIndex == -1) {Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");break;}final int y = (int) ev.getY(activePointerIndex);int deltaY = mLastMotionY - y;if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset,ViewCompat.TYPE_TOUCH)) {deltaY -= mScrollConsumed[1];mNestedYOffset += mScrollOffset[1];}if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {final ViewParent parent = getParent();if (parent != null) {parent.requestDisallowInterceptTouchEvent(true);}mIsBeingDragged = true;if (deltaY > 0) {deltaY -= mTouchSlop;} else {deltaY += mTouchSlop;}}if (mIsBeingDragged) {mLastMotionY = y - mScrollOffset[1];final int oldY = getScrollY();final int range = getScrollRange();// Calling overScrollByCompat will call onOverScrolled, which// calls onScrollChanged if applicable.if (overScrollByCompat(0, deltaY, 0, oldY, 0, range, 0,0, true) && !hasNestedScrollingParent(ViewCompat.TYPE_TOUCH)) {mVelocityTracker.clear();}final int scrolledDeltaY = getScrollY() - oldY;final int unconsumedY = deltaY - scrolledDeltaY;mScrollConsumed[1] = 0;dispatchNestedScroll(0, scrolledDeltaY, 0, unconsumedY, mScrollOffset,ViewCompat.TYPE_TOUCH, mScrollConsumed);mLastMotionY -= mScrollOffset[1];mNestedYOffset += mScrollOffset[1];}break;case MotionEvent.ACTION_UP:final VelocityTracker velocityTracker = mVelocityTracker;velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);if ((Math.abs(initialVelocity) > mMinimumVelocity)) {if (!dispatchNestedPreFling(0, -initialVelocity)) {dispatchNestedFling(0, -initialVelocity, true);fling(-initialVelocity);}} else if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0,getScrollRange())) {ViewCompat.postInvalidateOnAnimation(this);}mActivePointerId = INVALID_POINTER;endDrag();break;case MotionEvent.ACTION_CANCEL:if (mIsBeingDragged) {if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0,getScrollRange())) {ViewCompat.postInvalidateOnAnimation(this);}}mActivePointerId = INVALID_POINTER;endDrag();break;case MotionEvent.ACTION_POINTER_DOWN:final int index = ev.getActionIndex();mLastMotionY = (int) ev.getY(index);mActivePointerId = ev.getPointerId(index);break;case MotionEvent.ACTION_POINTER_UP:onSecondaryPointerUp(ev);mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId));break;}if (mVelocityTracker != null) {mVelocityTracker.addMovement(vtev);}vtev.recycle();return super.onTouchEvent(ev);}private void abortAnimatedScroll() {mScroller.abortAnimation();stopNestedScroll(ViewCompat.TYPE_NON_TOUCH);}private void endDrag() {mIsBeingDragged = false;recycleVelocityTracker();stopNestedScroll();}private void onSecondaryPointerUp(MotionEvent ev) {final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;final int pointerId = ev.getPointerId(pointerIndex);if (pointerId == mActivePointerId) {final int newPointerIndex = pointerIndex == 0 ? 1 : 0;mLastMotionY = (int) ev.getY(newPointerIndex);mActivePointerId = ev.getPointerId(newPointerIndex);if (mVelocityTracker != null) {mVelocityTracker.clear();}}}private void fling(int velocityY) {int height = getHeight();mScroller.fling(getScrollX(), getScrollY(), // start0, velocityY, // velocities0, 0, // xInteger.MIN_VALUE, Integer.MAX_VALUE, // y0, height / 2);runAnimatedScroll(true);}private void runAnimatedScroll(boolean participateInNestedScrolling) {if (participateInNestedScrolling) {startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL, ViewCompat.TYPE_NON_TOUCH);} else {stopNestedScroll(ViewCompat.TYPE_NON_TOUCH);}mLastScrollerY = getScrollY();ViewCompat.postInvalidateOnAnimation(this);}private void initOrResetVelocityTracker() {if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();} else {mVelocityTracker.clear();}}private void initVelocityTrackerIfNotExists() {if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();}}private void recycleVelocityTracker() {if (mVelocityTracker != null) {mVelocityTracker.recycle();mVelocityTracker = null;}}@Overrideprotected boolean overScrollBy(int deltaX, int deltaY,int scrollX, int scrollY,int scrollRangeX, int scrollRangeY,int maxOverScrollX, int maxOverScrollY,boolean isTouchEvent) {// this is causing double scroll call (doubled speed), but this WebView isn't overscrollable// all overscrolls are passed to appbar, so commenting this out during dragif (!mIsBeingDragged)overScrollByCompat(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY,maxOverScrollX, maxOverScrollY, isTouchEvent);// without this call webview won't scroll to top when url change or when user pick input// (webview should move a bit making input still in viewport when "adjustResize")return true;}int getScrollRange() {//Using scroll range of webview instead of childs as NestedScrollView does.return computeVerticalScrollRange();}@Overridepublic boolean isNestedScrollingEnabled() {return mChildHelper.isNestedScrollingEnabled();}@Overridepublic void setNestedScrollingEnabled(boolean enabled) {mChildHelper.setNestedScrollingEnabled(enabled);}@Overridepublic boolean startNestedScroll(int axes, int type) {return mChildHelper.startNestedScroll(axes, type);}@Overridepublic boolean startNestedScroll(int axes) {return startNestedScroll(axes, ViewCompat.TYPE_TOUCH);}@Overridepublic void stopNestedScroll(int type) {mChildHelper.stopNestedScroll(type);}@Overridepublic void stopNestedScroll() {stopNestedScroll(ViewCompat.TYPE_TOUCH);}@Overridepublic boolean hasNestedScrollingParent(int type) {return mChildHelper.hasNestedScrollingParent(type);}@Overridepublic boolean hasNestedScrollingParent() {return hasNestedScrollingParent(ViewCompat.TYPE_TOUCH);}@Overridepublic boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed,int[] offsetInWindow) {return dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,offsetInWindow, ViewCompat.TYPE_TOUCH);}@Overridepublic boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed,int[] offsetInWindow, int type) {return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,offsetInWindow, type);}@Overridepublic void dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed,@Nullable int[] offsetInWindow, int type, @NonNull int[] consumed) {mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,offsetInWindow, type, consumed);}@Overridepublic boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {return dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, ViewCompat.TYPE_TOUCH);}@Overridepublic boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow, int type) {return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, type);}@Overridepublic boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {return mChildHelper.dispatchNestedFling(velocityX, velocityY, false);}@Overridepublic boolean dispatchNestedPreFling(float velocityX, float velocityY) {return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);}@Overridepublic void computeScroll() {if (mScroller.isFinished()) {return;}mScroller.computeScrollOffset();final int y = mScroller.getCurrY();int unconsumed = y - mLastScrollerY;mLastScrollerY = y;// Nested Scrolling Pre PassmScrollConsumed[1] = 0;dispatchNestedPreScroll(0, unconsumed, mScrollConsumed, null,ViewCompat.TYPE_NON_TOUCH);unconsumed -= mScrollConsumed[1];if (unconsumed != 0) {// Internal Scrollfinal int oldScrollY = getScrollY();overScrollByCompat(0, unconsumed, getScrollX(), oldScrollY, 0, getScrollRange(),0, 0, false);final int scrolledByMe = getScrollY() - oldScrollY;unconsumed -= scrolledByMe;// Nested Scrolling Post PassmScrollConsumed[1] = 0;dispatchNestedScroll(0, 0, 0, unconsumed, mScrollOffset,ViewCompat.TYPE_NON_TOUCH, mScrollConsumed);unconsumed -= mScrollConsumed[1];}if (unconsumed != 0) {abortAnimatedScroll();}if (!mScroller.isFinished()) {ViewCompat.postInvalidateOnAnimation(this);}}// copied from NestedScrollView exacly as it looks, leaving overscroll related code, maybe future useprivate boolean overScrollByCompat(int deltaX, int deltaY,int scrollX, int scrollY,int scrollRangeX, int scrollRangeY,int maxOverScrollX, int maxOverScrollY,boolean isTouchEvent) {final int overScrollMode = getOverScrollMode();final boolean canScrollHorizontal =computeHorizontalScrollRange() > computeHorizontalScrollExtent();final boolean canScrollVertical =computeVerticalScrollRange() > computeVerticalScrollExtent();final boolean overScrollHorizontal = overScrollMode == View.OVER_SCROLL_ALWAYS|| (overScrollMode == View.OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal);final boolean overScrollVertical = overScrollMode == View.OVER_SCROLL_ALWAYS|| (overScrollMode == View.OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollVertical);int newScrollX = scrollX + deltaX;if (!overScrollHorizontal) {maxOverScrollX = 0;}int newScrollY = scrollY + deltaY;if (!overScrollVertical) {maxOverScrollY = 0;}// Clamp values if at the limits and recordfinal int left = -maxOverScrollX;final int right = maxOverScrollX + scrollRangeX;final int top = -maxOverScrollY;final int bottom = maxOverScrollY + scrollRangeY;boolean clampedX = false;if (newScrollX > right) {newScrollX = right;clampedX = true;} else if (newScrollX < left) {newScrollX = left;clampedX = true;}boolean clampedY = false;if (newScrollY > bottom) {newScrollY = bottom;clampedY = true;} else if (newScrollY < top) {newScrollY = top;clampedY = true;}if (clampedY && !hasNestedScrollingParent(ViewCompat.TYPE_NON_TOUCH)) {mScroller.springBack(newScrollX, newScrollY, 0, 0, 0, getScrollRange());}onOverScrolled(newScrollX, newScrollY, clampedX, clampedY);return clampedX || clampedY;}
}

分享:

定时垂直滚动的textview:GitHub - paradoxie/AutoVerticalTextview: 垂直滚动的textview,继承自TextSwitcher,抽出一个依赖库供以后备用

左右对齐的TextView

GitHub - Giftedcat/JustifyTextView: 左右对齐的TextView,适配各种分辨率,完美实现UI需求

 JustifyTextView 自定义TextView解决中文排版-CSDN博客

相关文章:

Android 解决TextView多行滑动与NestedScrollView嵌套滑动冲突的问题

关键计算地方: 1.当前是上滑动还是下滑动(相对于屏幕) ,使用ev.getRawY()获得当前滑动位置在屏幕哪个地方 2. 计算文本客滑动到哪里即可停止, (行高*总文本行数)- (行高 * 最多显示行数) int sum getLineHeight() * getLineCount() - getLineHeight() * getMaxLines(); …...

Laravel 开发Api规范

一&#xff0c;修改时区 配置 config/app.php 文件 // 时区修改&#xff0c;感觉两者皆可&#xff0c;自己根据实际情况定义 timezone > PRC, // 大陆时间二&#xff0c;设置 Accept 头中间件 accept头即为客户端请求头&#xff0c;做成中间件来使用。Accept 决定了响应返…...

蓝色wordpress外贸建站模板

蓝色wordpress外贸建站模板 https://www.mymoban.com/wordpress/7.html...

windos环境,使用docker容器运行项目的,新增外部访问地址配置

对于运行在 Docker 容器中的项目&#xff0c;你需要在容器内部编辑 resolv.conf 文件。以下是一种常见的方法&#xff1a; 进入正在运行的 Docker 容器&#xff1a;docker exec -it [container_id] bash其中 [container_id] 是你正在运行的 Docker 容器的 ID。 在容器内部使…...

设计模式:生活中的组合模式

想象一下&#xff0c;你正在组织一个大型的家庭聚会。在这个聚会中&#xff0c;你需要准备各种菜肴&#xff0c;每个菜肴又包含不同的食材。你的目标是能够以统一的方式处理整个聚会的准备工作&#xff0c;不论是处理单个食材还是一整道菜肴。 在这个场景中&#xff0c;我们可…...

WPF OnStartup

在Windows Presentation Foundation (WPF)框架中&#xff0c;OnStartup 是 System.Windows.Application 类的一个受保护的虚方法&#xff0c;它是应用程序启动过程中的一个重要环节。当一个 WPF 应用程序启动时&#xff0c;其入口点通常是 App.xaml 文件和对应的后台代码文件 A…...

docker-相关

打镜像 1、编写dockfile文件&#xff0c;请自行百度 2、docker build -t 镜像名称:版本号 dockerFile路径 3、docker save -o 镜像压缩包名称.tar 镜像名称:镜像版本号 部署镜像 1、将镜像tar包放到部署机器上 2、加载镜像&#xff1a;docker load -i 镜像tar包路径 3、dock…...

二十、Rust AOP 切面增强

用过 java spring 的同学&#xff0c;应该会对 AspectJ 的 前置、后置、环绕 增强 念念不忘&#xff0c;巧了 rust 也有类似能力&#xff0c;稍显不同的是&#xff0c;为了向 “零成本抽象” 靠齐&#xff0c;Rust 的 “增强” 是在编译期 完成的。 编译期生成&#xff0c;则离…...

掌握Go语言:Go语言精细错误,清晰、高效的错误处理实践(32)

错误处理是任何编程语言中都至关重要的一部分&#xff0c;Go 语言提供了一套简单而强大的错误处理机制&#xff0c;使得处理错误变得高效而清晰。 Go 错误类型 在 Go 中&#xff0c;错误是一个普通的接口类型&#xff0c;即 error 接口&#xff0c;其定义如下&#xff1a; t…...

Spring与Web环境的集成

1. ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的&#xff0c;但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) &#xff0c;这样的弊端是配置文件加载多…...

二叉树的遍历——bfs广度优先搜索

1、BinNode类的创建 &#xff08;1&#xff09;代码总览 ##&#xff08;2&#xff09;测试示例 2、二叉树的遍历 &#xff08;1&#xff09;图示 &#xff08;2&#xff09;代码总览 &#xff08;3&#xff09;测试示例...

飞鸟写作可靠吗 #职场发展#经验分享#经验分享

飞鸟写作是一个非常便捷的论文写作工具&#xff0c;不仅可以帮助用户高效地完成论文写作&#xff0c;还可以提供查重降重的功能&#xff0c;帮助用户确保论文的原创性。那么&#xff0c;飞鸟写作到底可靠吗&#xff1f;答案是肯定的。 首先&#xff0c;飞鸟写作提供的查重降重功…...

Java 实现自定义注解

一、interface 关键字 我们想定义一个自己的注解 需要使用 interface 关键字来定义。 如定义一个叫 MyAnnotation 的注解&#xff1a; public interface MyAnnotation { } 二、元注解 光加上 interface 关键字 还不够&#xff0c;我们还需要了解5大元注解 RetentionTargetDo…...

代码随想录Day48

Day 48 动态规划part09 今日任务 198.打家劫舍213.打家劫舍II337.打家劫舍III 代码实现 基础打家劫舍 class Solution {public static int rob(int[] nums) {if (nums null || nums.length 0) return 0;if (nums.length 1) return nums[0];int[] dp new int[nums.leng…...

Web 后台项目,权限如何定义、设置、使用:菜单权限、按钮权限 ts element-ui-Plus

Web 后台项目&#xff0c;权限如何定义、设置、使用&#xff1a;菜单权限、按钮权限 ts element-ui-Plus 做一个后台管理项目&#xff0c;里面需要用到权限管理。这里说一下权限定义的大概&#xff0c;代码不多&#xff0c;主要讲原理和如何实现它。 一、权限管理的原理 权限…...

ADB 操作命令及其详细用法

adb devices 用途&#xff1a;列出连接到计算机的所有 Android 设备。详解&#xff1a;执行该命令后&#xff0c;ADB 将扫描连接到计算机的所有 Android 设备&#xff0c;并列出它们的序列号。 adb connect <device> 用途&#xff1a;连接到指定 IP 地址的 Android 设备。…...

类的函数成员(三):拷贝构造函数

一.什么是拷贝构造函数&#xff1f; 1.1 概念 同一个类的对象在内存中有完全相同的结构&#xff0c;如果作为一个整体进行复制或称拷贝是完全可行的。这个拷贝过程只需要拷贝数据成员&#xff0c;而函数成员是共用的&#xff08;只有一份拷贝&#xff09;。 在建立对象…...

C#操作MySQL从入门到精通(8)——对查询数据进行高级过滤

前言 我们在查询数据库中数据的时候,有时候需要剔除一些我们不想要的数据,这时候就需要对数据进行过滤,比如学生信息中,我只需要年龄等于18的,同时又要家乡地址是安徽的,类似这种操作专栏第7篇的C#操作MySQL从入门到精通(7)——对查询数据进行简单过滤简单过滤方法就无法…...

Centos 7 安装通过yum安装google浏览器

在CentOS 7上使用yum安装Google Chrome浏览器稍微复杂一些&#xff0c;因为Chrome并不直接包含在默认的Yum仓库中。按照以下步骤来操作&#xff1a; 1、添加Google Chrome仓库 首先&#xff0c;您需要手动添加Google Chrome的Yum仓库。打开终端&#xff0c;并使用文本编辑器&a…...

题目:学习使用按位与 。

题目&#xff1a;学习使用按位与 & 。   There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated shoul…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...