自定义view之无限滚动的刻度尺

2023-11-19

具体思路是把一个view分成三段,当总长度>=40个刻度向左滚动,滚动到2/3的时候view移动到1/3出然后刷新显示的刻度这时为第一页,一次更新页数,当向右滚动的时候滚动且不为第一页则每滚动到1/3处view移动到2/3处。之后在添加一些首页和最后一页的判断。
这一次除了无限滚动还比我上一次写的多了手指滑动速度的判断,去掉了滚动结束自动归位到对应刻度的效果,代码中除了极端情况默认使用的view显示的刻度为30个,也就是说除了开始和结束,显示的位置始终在10~20之间,向右拖动图示:
无标题.png

效果展示:
GIF.gif

核心代码

package com.zqb.scrolldividingrule;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.Scroller;
import java.util.ArrayList;

/**
 * 横向滚动的刻度尺
 * Created by zhangqingbin on 2018/1/5.
 */

public class ScrollDividingRuleView extends View {

  private Scroller mScroller;
  private Paint mPaint;
  private VelocityTracker mVelocityTracker;
  private OnScrollListener mListener;
  private int mScaleMargin; //刻度间距
  private float mScaleWidth; //总刻度宽度
  private float mTextSize;//文字大小
  private ArrayList<String> mTextList;//刻度文字
  private ArrayList<String> mTotalTextList;//所有的刻度
  private float mLineHeight;//线高度
  private int mRectHeight;//总高度
  private int mScrollLastX;
  private int mInitDistance;//初始距离
  private int mInitPosition;//初始位置
  private int mTextLineMargin;//文字距线的距离
  private int mPage;//当前为复用所在页
  private long mLastInstance;//余数刻度
  private long mStartMoney;//开始金额
  private int mUnit;//每个小格的单位
  private long mFinalMoney;//结束金额

  public ScrollDividingRuleView(Context context) {
    this(context, null);
  }

  public ScrollDividingRuleView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public ScrollDividingRuleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setWillNotDraw(false);
    init(context, attrs);
  }

  private void init(Context context, @Nullable AttributeSet attrs) {
    if (attrs != null) {
      for (int i = 0; i < attrs.getAttributeCount(); i++) {
        String name = attrs.getAttributeName(i);
        if ("layout_width".equals(name)) {
          String value = attrs.getAttributeValue(i);
          if (value.length() > 2) {
            if (value.endsWith("dp")) {
              float margin = Float.valueOf(value.substring(0, value.length() - 2));
              mScaleWidth = Utils.dp2px(context, margin);
            } else {
              mScaleWidth = Float.valueOf(value.substring(0, value.length() - 2));
            }
          } else if (value.equals("-1") || value.equals("-2") || value.equals("0")) {
            mScaleWidth = 0;
          }
        } else if ("line_height".equals(name)) {
          String value = attrs.getAttributeValue(i);
          if (value.length() > 2) {
            if (value.endsWith("dp")) {
              mLineHeight =
                  Utils.dp2px(context, Float.valueOf(value.substring(0, value.length() - 2)));
            } else {
              mLineHeight = Float.valueOf(value.substring(0, value.length() - 2));
            }
          } else {
            mLineHeight = 50;
          }
        } else if ("dividing_text_size".equals(name)) {
          String value = attrs.getAttributeValue(i);
          if (value.length() > 2) {
            if (value.endsWith("sp")) {
              mTextSize =
                  Utils.sp2px(context, Float.valueOf(value.substring(0, value.length() - 2)));
            } else {
              mTextSize = Float.valueOf(value.substring(0, value.length() - 2));
            }
          } else {
            mTextSize = 32;
          }
        }
      }
    }
    // 画笔
    mPaint = new Paint();
    //总的高度,因为text的高度和设置的textSize会有误差所以加上20的高度
    mRectHeight = (int) (mLineHeight + mTextSize + mTextLineMargin + 20);
    //初始设置每个刻度间距为30px
    mScaleMargin = 20;
    mTextList = new ArrayList<>();
    mTotalTextList = new ArrayList<>();
    mScroller = new Scroller(context);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    mPaint.setColor(Color.GRAY);
    // 抗锯齿
    mPaint.setAntiAlias(true);
    // 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
    mPaint.setDither(true);
    // 空心
    mPaint.setStyle(Paint.Style.STROKE);
    // 文字居中
    mPaint.setTextAlign(Paint.Align.CENTER);
    onDrawScale(canvas, mPaint); //画刻度
    onDrawLine(canvas, mPaint);//画刻度中间横线
    super.onDraw(canvas);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int height = MeasureSpec.makeMeasureSpec(mRectHeight, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, height);
    //初始化开始位置
    mInitDistance = getMeasuredWidth() / 2 - mInitPosition * mScaleMargin * 10;
  }

  @SuppressLint("ClickableViewAccessibility")
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (mVelocityTracker == null) {
      mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(event);
    int x = (int) event.getX();
    int startX = 0;
    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        if (mScroller != null) {//重新初始化fling效果,防止下一次移动有初始速度
          mScroller.fling(mScroller.getFinalX(), mScroller.getFinalY(), 0, 0, 0,
              (int) (mScaleWidth - mInitPosition * mScaleMargin * 10), 0, 0);
          mScroller.abortAnimation();
        }
        startX = x;
        mScrollLastX = x;
        return true;
      case MotionEvent.ACTION_MOVE:
        int dataX = mScrollLastX - x;
        smoothScrollBy(dataX, 0);
        mScrollLastX = x;
        return true;
      case MotionEvent.ACTION_CANCEL:
      case MotionEvent.ACTION_UP:
        dealActionUp(x - startX);
        return true;
    }
    return super.onTouchEvent(event);
  }

  /**
   * 处理手势抬起之后的操作
   *
   * @param i 根据正负判断方向
   */
  private void dealActionUp(int i) {
    mVelocityTracker.computeCurrentVelocity(1000);
    if (mScroller.getFinalX() >= mScaleMargin * 10 * 10 * 2 - 10 * mScaleMargin && i > 0) {
      if (!notifyDataChanged(0)) {
        dealFling();
      }
    } else if (mScroller.getFinalX() <= mScaleMargin * 10 * 10 - 10 * mScaleMargin && i < 0) {
      if (!notifyDataChanged(1)) {
        dealFling();
      }
    } else {
      dealFling();
    }
    long i1 = mPage > 0 ? mPage * 100 : 0;
    if (mListener != null) {
      mListener.onScaleScrollChanged(
          mScroller.getFinalX() / mScaleMargin + mInitPosition * 10 + i1 + mStartMoney);//返回滚动选中的位置
    }
    mVelocityTracker.clear();
    mVelocityTracker.recycle();
    mVelocityTracker = null;
  }

  /**
   * 处理手指抬起之后的减速滚动
   */
  private void dealFling() {
    int minX;//最小值
    if (mPage == 0) {
      minX = -mInitPosition * mScaleMargin * 10;
    } else {
      minX = -mInitPosition * mScaleMargin * 10 + mScaleMargin * 10 * 10 - mScaleMargin * 10;
    }
    int maxX;//最大值 根据位置和总数改变
    if (mPage == (mTotalTextList.size() - 20) / 10 - 1 || mTotalTextList.size() < 40) {
      maxX = (int) (mScaleWidth - mInitPosition * mScaleMargin * 10);
    } else {
      maxX = mScaleMargin * 10 * 20 - mScaleMargin * 10;
    }
    mScroller.fling(mScroller.getFinalX(), mScroller.getFinalY(),
        -(int) mVelocityTracker.getXVelocity(), 0, minX, maxX, 0, 0);
  }

  private void onDrawScale(Canvas canvas, Paint paint) {
    paint.setAntiAlias(true);
    paint.setTextSize(mTextSize);
    paint.setStyle(Paint.Style.FILL);
    for (int i = 0, k = 0; i < mTextList.size() * 10; i++) {
      if (i < mTextList.size() * 10 - 9) {
        if (i % 10 == 0) { //整值
          paint.setColor(Color.GRAY);
          canvas.drawLine(i * mScaleMargin + mInitDistance, mRectHeight,
              i * mScaleMargin + mInitDistance, mRectHeight - mLineHeight - mTextLineMargin + 20,
              paint);
          //整值文字
          paint.setColor(Color.GRAY);
          canvas.drawText(mTextList.get(k), i * mScaleMargin + mInitDistance,
              mRectHeight - mLineHeight - mTextLineMargin, paint);
          k++;
        } else {
          paint.setColor(Color.GRAY);
          canvas.drawLine(i * mScaleMargin + mInitDistance, mRectHeight,
              i * mScaleMargin + mInitDistance, mRectHeight - mLineHeight / 2 - mTextLineMargin,
              paint);
        }
      } else {//画滚动到末尾余数 30200
        if (mPage == (mTotalTextList.size() - 20) / 10 - 1 || mTotalTextList.size() < 40) {
          if ((mLastInstance / mScaleMargin) > 0
              && (mLastInstance / mScaleMargin) > i - (mTextList.size() * 10 - 9)) {
            paint.setColor(Color.GRAY);
            canvas.drawLine(i * mScaleMargin + mInitDistance, mRectHeight,
                i * mScaleMargin + mInitDistance, mRectHeight - mLineHeight / 2 - mTextLineMargin,
                paint);
          }
        }
      }
    }
  }

  private void onDrawLine(Canvas canvas, Paint paint) {
    paint.setStrokeWidth(2);
    canvas.drawLine(mInitDistance, mRectHeight, mScaleWidth + mInitDistance, mRectHeight, paint);
  }

  /**
   * 使用Scroller的时候需要重写该方法
   */
  @Override
  public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
      scrollTo(mScroller.getCurrX(), 0);
      postInvalidate();
    }
  }

  private void smoothScrollBy(int dx, int dy) {
    if (mScroller.getFinalX() >= mScaleMargin * 10 * 10 * 2 - 10 * mScaleMargin
        && dx > 0) {//向左滚动,判断是否滚动到第三部分起始位置
      if (!notifyDataChanged(0)) {
        mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);
      }
    } else if (mScroller.getFinalX() <= mScaleMargin * 10 * 10 - 10 * mScaleMargin
        && dx < 0) {///向右滚动,判断是否滚动到第二部分开始位置
      if (!notifyDataChanged(1)) {
        mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);
      }
    } else {//否则根据手指滚动
      mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);
    }
    postInvalidate();
  }

  public interface OnScrollListener {
    void onScaleScrollChanged(long scale);
  }

  /**
   * 设置当前位置
   *
   * @param scale 刻度
   */
  public void setNowScale(float scale) {
    float i = scale * mScaleMargin;
    int maxPage = (mTotalTextList.size() - 20) / 10 - 1;
    mPage = 0;
    if (mTotalTextList.size() < 40) {//如果总数小于40 不需要处理多页
      mPage = 0;
      smoothScrollBy((int) (i - mScroller.getFinalX()), 0);
      return;
    } else if (i < mScaleMargin * 10 * 10 * 2 - mScaleMargin * 10) {//判断刻度是否在第一页
      mPage = 0;
    } else if (scale >= 10 * 10 + maxPage * 10 * 10) {//判断刻度是否在最后一页
      mPage = maxPage;
    } else {
      mPage = (int) (scale / 100 - 1);
    }
    if (scale * mUnit >= mFinalMoney) {//如果要设置的刻度大于集合里的最大值 则只滚动到末尾
      mPage = maxPage;
      mTextList.clear();
      for (int j = mPage * 10; j < mTotalTextList.size(); j++) {
        mTextList.add(mTotalTextList.get(j));
      }
      mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin + mLastInstance;
      smoothScrollBy((int) (mScaleWidth - mScroller.getFinalX()), 0);
    } else {
      if (mPage == (mTotalTextList.size() - 20) / 10 - 1) {//判断是否是最后一页
        if (mTotalTextList.size() >= mPage * 10 + 30) {
          mTextList.clear();
          for (int j = mPage * 10; j < mTotalTextList.size(); j++) {//更新刻度
            mTextList.add(mTotalTextList.get(j));
          }
          mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin + mLastInstance;//加上余数的宽度
          smoothScrollBy((int) (i - ((mPage + 1) * 10 * 10 * mScaleMargin) + 10 * 10 * mScaleMargin
              - mScroller.getFinalX()), 0);
        }
      } else {
        if (mTotalTextList.size() >= mPage * 10 + 30) {
          mTextList.clear();
          for (int j = mPage * 10; j < mPage * 10 + 30; j++) {//更新刻度
            mTextList.add(mTotalTextList.get(j));
          }
          mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin;
          smoothScrollBy((int) (i - ((mPage + 1) * 10 * 10 * mScaleMargin) + 10 * 10 * mScaleMargin
              - mScroller.getFinalX()), 0);
        }
      }
    }
  }

  /**
   * 初始化数据
   *
   * @param startMoney 开始金额
   * @param finalMoney 最终金额
   * @param unit 每个刻度单位
   * @param listener 滚动监听
   */
  public void bindMoneyData(int startMoney, int finalMoney, int unit, OnScrollListener listener) {
    if (mTotalTextList != null && mTotalTextList.size() > 0) {
      refresh(startMoney, finalMoney);
    } else {
      mPage = 0;
      mUnit = unit;
      mStartMoney = startMoney / unit;
      mTextList = new ArrayList<>();
      mTotalTextList = new ArrayList<>();
      mFinalMoney = finalMoney;
      for (int i = 0; i < (finalMoney - startMoney) / (unit * 10) + 1; i++) {
        if (i < 30 || (finalMoney - startMoney) / (unit * 10) + 1 < 40) {//当前显示刻度数
          mTextList.add(String.valueOf(i * unit * 10 + startMoney));
        }
        mTotalTextList.add(String.valueOf(i * unit * 10 + startMoney));//总共刻度数
      }
      mLastInstance = ((finalMoney - startMoney) % (unit * 10)) / 100 * mScaleMargin;//余数刻度
      if (mTotalTextList.size() < 40) {
        mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin + mLastInstance;
      } else {
        mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin;
      }
      mListener = listener;
      postInvalidate();
    }
  }

  /**
   * 判断更新当前页
   *
   * @param type 0左滑  1右滑
   * @return 是否处理了滚动到对应页
   */
  private boolean notifyDataChanged(int type) {
    if (mTotalTextList.size() < 40) {
      return false;
    }
    if (type == 0) {//向前移动
      if ((mTotalTextList.size() - 20) / 10 - 1 == 0) {
        return false;
      }
      if (mPage < (mTotalTextList.size() - 20) / 10 - 1) {
        mPage++;
        if (mPage == (mTotalTextList.size() - 20) / 10 - 1) {
          if (mTotalTextList.size() >= mPage * 10 + 30) {
            mTextList.clear();
            for (int i = mPage * 10; i < mTotalTextList.size(); i++) {
              mTextList.add(mTotalTextList.get(i));
            }
            mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin + mLastInstance;
            mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(),
                -mScroller.getFinalX() + mScaleMargin * 10 * 10 - 10 * mScaleMargin,
                mScroller.getFinalY());
            return true;
          }
        } else {
          if (mTotalTextList.size() >= mPage * 10 + 30) {
            mTextList.clear();
            for (int i = mPage * 10; i < mPage * 10 + 30; i++) {
              mTextList.add(mTotalTextList.get(i));
            }
            mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin;
            mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(),
                -mScroller.getFinalX() + mScaleMargin * 10 * 10 - 10 * mScaleMargin,
                mScroller.getFinalY());
            return true;
          }
        }
      }
    } else {//向后移动
      if (mPage > 0) {
        mPage--;
        if (mTotalTextList.size() > mPage * 10 + 30) {
          mTextList.clear();
          for (int i = mPage * 10; i < mPage * 10 + 30; i++) {
            mTextList.add(mTotalTextList.get(i));
          }
          mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin;
          mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(),
              mScaleMargin * 10 * 10, mScroller.getFinalY());
          return true;
        }
      }
    }
    return false;
  }

  /**
   * 刷新操作
   */
  public void refresh(final int startMoney, final int finalMoney) {
    new Thread(new Runnable() {//防止数据量过多导致阻塞主线程
      @Override
      public void run() {
        mPage = 0;
        mStartMoney = startMoney / mUnit;
        mFinalMoney = finalMoney;
        mTextList.clear();
        mTotalTextList.clear();
        for (int i = 0; i < (finalMoney - startMoney) / (mUnit * 10) + 1; i++) {
          if (i < 30 || (finalMoney - startMoney) / (mUnit * 10) + 1 < 40) {//当前显示刻度数
            mTextList.add(String.valueOf(i * mUnit * 10 + startMoney));
          }
          mTotalTextList.add(String.valueOf(i * mUnit * 10 + startMoney));//总共刻度数
        }
        mLastInstance = ((finalMoney - startMoney) % (mUnit * 10)) / 100 * mScaleMargin;//余数刻度
        if (mTotalTextList.size() < 40) {
          mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin + mLastInstance;
        } else {
          mScaleWidth = (mTextList.size() * 10 - 10) * mScaleMargin;
        }
        new Handler(Looper.getMainLooper()).post(new Runnable() {
          @Override
          public void run() {
            postInvalidate();
          }
        });
      }
    });
  }

  /**
   * 设置每个刻度间距
   *
   * @param margin 间距
   * @return 返回当前view 链式编程
   */
  public ScrollDividingRuleView setScaleMargin(int margin) {
    mScaleMargin = margin;
    mRectHeight = (int) (mLineHeight + mTextSize + mTextLineMargin + 20);
    return this;
  }

  /**
   * 设置文字和刻度线的间距
   */
  public ScrollDividingRuleView setTextLineMargin(int textLineMargin) {
    mTextLineMargin = textLineMargin;
    mRectHeight = (int) (mLineHeight + mTextSize + mTextLineMargin + 20);
    return this;
  }

  /**
   * 设置文字和刻度线的间距(滚动有问题)
   */
  public ScrollDividingRuleView setInitPosition(int position) {
    mInitPosition=position;
    return this;
  }
}

调用代码:

final ScrollDividingRuleView scrollDividingRuleView = findViewById(R.id.scroll_dividing_rule_view);
    editText = findViewById(R.id.edit_text);
    scrollDividingRuleView.bindMoneyData(0, 100000, 100,
        new ScrollDividingRuleView.OnScrollListener() {
          @Override public void onScaleScrollChanged(long scale) {
            isDividingScroll=true;//防止滚动的时候和edittext绑定数据出问题
            editText.setText(String.valueOf(scale*100));
            editText.setSelection(String.valueOf(scale*100).length());
          }
        });

    scrollDividingRuleView.setScaleMargin(30)
        .setTextLineMargin(30);

    editText.addTextChangedListener(new TextWatcher() {
      @Override
      public void beforeTextChanged(CharSequence s, int start, int count, int after) {
      }

      @Override
      public void onTextChanged(CharSequence s, int start, int before, int count) {
      }

      @Override
      public void afterTextChanged(Editable s) {
        String money = s.toString().trim();
        if (money.length() > 0 && !TextUtils.isEmpty(money)) {
          float i = Float.parseFloat(money);
            if (!isDividingScroll) {
              scrollDividingRuleView.setNowScale(i >= 100? i / 100 : 0);
            } else {
              isDividingScroll = false;
            }
          }
      }
    });

布局代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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"
    tools:context="com.zqb.scrolldividingrule.MainActivity">
    <com.zqb.scrolldividingrule.ScrollDividingRuleView
        android:layout_marginTop="50px"
        android:id="@+id/scroll_dividing_rule_view"
        android:layout_width="match_parent"
        android:layout_marginLeft="30px"
        android:layout_marginRight="30px"
        android:layout_height="wrap_content"
        app:line_height="80px"
        app:dividing_text_size="30px"/>
    <View
        android:layout_marginTop="90px"
        android:background="@color/colorAccent"
        android:layout_centerHorizontal="true"
        android:layout_width="1px"
        android:layout_height="120px"/>
    <EditText
        android:inputType="number"
        android:id="@+id/edit_text"
        android:layout_marginLeft="10dp"
        android:textSize="25sp"
        android:layout_marginTop="300px"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>

下载地址

如果显示30个有卡顿的话,可以自己调整。
注:paint.setStyle(Paint.Style.FILL); 防止画出来的文字带空心
paint.measureText(“123”); 获取文字显示的宽度

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义view之无限滚动的刻度尺 的相关文章

随机推荐

  • 在Windows下使用vs2019编译libjpeg库

    一 库的编译 1 下载 libjpeg 源码 这里我下载的是 jpegsr9e zip 2 解压源码 3 进入解压后的目录 找到 makefile vs 文件 用文本编辑器打开并编辑 找到 语句 include
  • 设备管理过程

    复杂度2 5 机密度2 5 最后更新2021 04 19 AIX中对设备会有如下五个操作 define aix下能看到设备的定义 但驱动程序并没有加载或初始化 该设备不可用 lsdev看到设备时defined 很多逻辑设备 vg lv等 只
  • CTF练题(5)word隐写基础题,jpg图片隐写,敲击码解密

    2022 11 2 两道misc题目 题目一 word隐写基础 题目信息如下 以及一个无法打开的word文档 解题步骤 1 将该word文档拖入010Editor中进行分析 发现文件头显示为PK 压缩文件 将该文档后缀改为 zip 保存到桌
  • go-zero使用Etcd进行服务注册代码分析

    代码分析 github com tal tech go zero v1 2 3 core discov publisher go package discov import github com tal tech go zero core
  • ld链接器的--start-group和--end-group参数说明

    start group archives end group The archives should be a list of archive files They may be either explicit file names or
  • OpenLayers与Bootstrap样式冲突的解决

    在引入Bootstrap响应式布局样式后 OpenLayers图层瓦片会显示异常 在页面中加入以下样式可以解决 参见 http openlayers org dev examples bootstrap html
  • linux网络95值工具,Linux下网络故障排查工具之ping

    服务器运维人员在日常运维服务器的过程中经常会遇到服务器网络故障 有服务器硬件造成的 也有服务商网络问题造成的 也有区域网络问题造成的 这个时候就需要用到ping traceroute mtr这三个命令 1 ping 最简单的网络请求反馈命令
  • 粒子群算法优化的最小二乘支持向量机分类代码

    粒子群算法优化的最小二乘支持向量机分类代码 在数据挖掘和机器学习领域中 分类是一个非常基础而重要的问题 其中最小二乘支持向量机 LSSVM 是一种有效的分类方法 经常被应用于实际问题中 而粒子群算法 PSO 是一种优化算法 也可以用来优化L
  • C++之函数模板

    1 什么是模板 模板有什么作用 模板分为函数模板和类模板 函数模板是对函数功能框架的描述 具体功能由实际传递的参数决定 有了函数模板 编译器就会根据模板自动生成多个函数名相同 参数列表不同的函数 不需要手动写 例 求一个矩形面积 当传入的长
  • Tensorflow之Estimator(二)实践

    1 前言 这篇文章介绍Tensorflow的高级API 模型的建立和简化过程 2 Estimator优势 本文档介绍了Estimator一种可极大地简化机器学习编程的高阶TensorFlow API 用了Estimator你会得到数不清的好
  • 一些JDK自带的性能分析利器

    有时候碰到服务器CPU飙升或者程序卡死之类的问题 一般都不太好定位 这类bug一般都隐藏的比较深并且还可能是偶发性的 比较棘手 对于此类问题 一般我们都有固定的分析流程 借助于JDK自带的一些分析工具 比如jstack jmap jstat
  • 超全汇总,性能测试常用指标大全(重要)

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • 三相桥式全控整流电路仿真--(Matlab仿真2)

    仿真环境 Matlab 2018a 使用模块 1 Three Phase V I Measurement1 2 Multimeter 3 Universal Bridge 4 Selector 5 Mean 测量平均电压 6 Pulse G
  • pycharm如何连接数据库并往数据库插入内容

    1 创建connection对象 2 创建cursor对象 游标对象 主要用于操作数据库 3 执行查询 4 关闭cursor对象 5 关闭connection 首先要先安装pumysql库 pip install pymysql 连接测试
  • 微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人...

    微服务应用大行其道 我提供一个dto和entity转换工具类 方便大家做转换 少写机械代码 多陪陪家人 该工具类主要是对dozer进行了封装 使用过程代码量极少 废话少说 贴代码了 import java util ArrayList im
  • 使用vscode编辑和提交github仓库代码

    写在前面 在github上想删除仓库中的某个文件或文件夹 亦或是重命名操作都很麻烦 这里提供一种vscode的解决方案 在vscode中克隆远程github仓库 然后对代码或文件进行编辑 最后提交即可 就和管理本地文件一样方便 准备工作 下
  • react.js的介绍

    关于React React部分的内容包含了所有授课的思路 React的起源和发展 React 起源于 Facebook 的内部项目 因为该公司对市场上所有 JavaScript MVC 框架 都不满意 就决定自己写一套 用来架设Instag
  • 计算机网络之数据链路层协议总结

    数据链路层 1 数据链路层介绍 2 ARP协议 2 1 ARP的工作流程 2 2 ARP数据报格式 3 NAT技术 3 1 NAT转换过程 3 2 NAPT技术 动态NAT重载 4 DNS技术 4 1 域名层级关系 4 2 域名解析流程 5
  • 程序员如何认识自己? 怎么知道自己适合做什么?人生路上的困惑 应不应该转行

    这个问题其实从毕业工作后就开始思考了 到底什么才是自己适合的工作 怎么才能从自己的工作当中找到兴趣 有朋友吐槽不喜欢现在的生活 不喜欢现在的工作 感觉不合适 如果被吐槽之后 我真的是按照套路去回答 嗯 我理解你 你现在肯定因为自己的生活和工
  • 自定义view之无限滚动的刻度尺

    具体思路是把一个view分成三段 当总长度 gt 40个刻度向左滚动 滚动到2 3的时候view移动到1 3出然后刷新显示的刻度这时为第一页 一次更新页数 当向右滚动的时候滚动且不为第一页则每滚动到1 3处view移动到2 3处 之后在添加