Android进阶之路 - EditText输入字体自适应

news2024/9/20 13:17:49

遇到这么一个需求:“控件宽度有限,随着输入内容,动态修改字体大小”,如果是你,只如何来实现?又有几种方式?

嗯,就是这么一个简单的需求,让我记录了俩篇blog
在这里插入图片描述

  • Android进阶之路 - 去除EditText内边距
  • Android进阶之路 - EditText输入字体自适应

起初我曾尝试通过监听TextChanged + 字体自适应 的方式,来实现 输入字体自适应 ,但是效果并不理想 ,所以最终换了别的方式

    • 简单、直接、有点low
    • AutoAdjustSizeEditText
    • AutoAdaptSizeEditText

该篇通过我所使用的几种方式,看看能否帮助大家,具体采用了以下几种方式,先简单介绍一下

  • 监听TextChanged,在一定规则内直接设置字体大小(字体过度不自然)
  • AutoAdjustSizeEditText 自定义控件(基本满足场景,不过单行可支持无线输入,可无限滑动)
  • AutoAdaptSizeEditText 控件借鉴于前者,稍加修改,用于满足某一场景(设置单行场景,超过固定宽度,则不可继续输入)

AutoAdjustSizeEditText、AutoAdaptSizeEditText 效果与布局引入

效果

请添加图片描述

布局引入

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat 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:orientation="vertical"
    tools:context=".MainActivity">

    <com.example.edittextdemo.AutoAdjustSizeEditText
        android:layout_width="230dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:hint="AutoAdjustSizeEditText"
        android:textSize="20sp"
        app:maxTextSize="30sp"
        app:minTextSize="15sp" />

    <com.example.edittextdemo.AutoAdaptSizeEditText
        android:layout_width="230dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"
        android:hint="AutoAdaptSizeEditText"
        android:singleLine="true"
        android:textSize="20sp"
        app:maxSize="30sp"
        app:minSize="15sp" />
</androidx.appcompat.widget.LinearLayoutCompat>

简单、直接、有点low

这种方式就想我说的使用起来很简单,唯一不足可能在于首先需要了解输入规则的要求,同时字体适应时会生硬一些(目前因为框架原因,我先使用了该方式)

因为框架原因,我直接提供伪代码用于各位借鉴吧

EditText - addTextChangedListener

在这里插入图片描述

通过规则,自行定义字体大小

在这里插入图片描述

splitties框架EditText.setTextIfDifferent扩展函数,内部会自行设置焦点位置

在这里插入图片描述


AutoAdjustSizeEditText

我看了很多篇关于 EditText 输入字体自适应 Blog,大多好像都脱胎于早期这款 AutoAdjustSizeEditText 自定义控件,我直接将源码跑完后发现基本可以适用于大部分场景,其中有优点有不足(仅个人认为),但依旧不可否认可以从前辈的代码中学习和成长(为表尊重,源码不做任何修改)

适用大部分场景,如果对单行显示长度有限定或许不太满足

自定义属性(之前一直没记录过自定义属性的相关blog,等有时间我必须补充一篇)

    <!-- 文本自动调整大小显示自定义属性 -->
    <declare-styleable name="AutoAdjustTextSize">
        <attr name="minTextSize" format="dimension" />
        <attr name="maxTextSize" format="dimension" />
    </declare-styleable>

AutoAdjustSizeEditText

package com.example.edittextdemo;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.EditText;
import android.widget.TextView;


/**
 * 自动调整字体文本输入框
 * 
 * @author 蒋庆意
 * @date 2015-11-4
 * @time 上午11:02:32
 */
@SuppressLint("AppCompatCustomView")
public class AutoAdjustSizeEditText extends EditText {
    /**
     * 默认文字字体大小最小值(单位:像素)
     */
    private static final float DEFAULT_TEXT_SIZE_MIN = 20;

    /**
     * 默认文字字体大小最大值(单位:像素)(貌似用不上)
     */
    @SuppressWarnings("unused")
    private static final float DEFAULT_TEXT_SIZE_MAX = 60;

    /**
     * 画笔(用来测量已输入文字的长度)
     */
    private Paint paint;

    /**
     * 文字字体大小最小值
     */
    private float minTextSize = 0;

    /**
     * 文字字体大小最大值
     */
    private float maxTextSize = 0;

    /**
     * 判断输入文本字体是否变小过
     */
    private boolean hasScaleSmall = false;

    public AutoAdjustSizeEditTextBefore(Context context) {
        super(context);
        paint = new Paint();
    }

    public AutoAdjustSizeEditTextBefore(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        //读取自定义属性, 获取设置的字体大小范围
        if (null != attrs) {
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AutoAdjustTextSize);
            if (null != array) {
                minTextSize = array.getDimension(R.styleable.AutoAdjustTextSize_minTextSize, DEFAULT_TEXT_SIZE_MIN);
                //如果未设置字体最大值,则使用当前字体大小作为最大值
                maxTextSize = array.getDimension(R.styleable.AutoAdjustTextSize_maxTextSize, this.getTextSize());
                //回收 TypedArray
                array.recycle();
            }
        }
        //未设置字体最小值,则使用默认最小值
        if (0 == minTextSize) {
            minTextSize = DEFAULT_TEXT_SIZE_MIN;
        }
        //未设置字体最大值,则使用当前字体大小作为最大值
        if (0 == maxTextSize) {
            //            maxTextSize = DEFAULT_TEXT_SIZE_MAX;
            maxTextSize = this.getTextSize();
        }
        //如果设置的值不正确(例如minTextSize>maxTextSize),则互换
        if (minTextSize > maxTextSize) {
            float minSize = maxTextSize;
            maxTextSize = minTextSize;
            minTextSize = minSize;
        }
        Log.d("AutoScaleSizeEditText",
                "minTextSize=" + String.valueOf(minTextSize));
        Log.d("AutoScaleSizeEditText",
                "maxTextSize=" + String.valueOf(maxTextSize));
    }

    @Override
    protected void onTextChanged(CharSequence text, int start,
                                 int lengthBefore, int lengthAfter) {
        // 根据需要调整字体大小
        adjustTextSize(this);
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // 根据需要调整字体大小
        if (w != oldw) {
            adjustTextSize(this);
        }
        super.onSizeChanged(w, h, oldw, oldh);
    }

    /**
     * 调整文本的显示
     */
    private void adjustTextSize(TextView textView) {
        if (null == textView) {
            //参数错误,不与处理
            return;
        }
        //已输入文本
        String text = textView.getText().toString();
        //已输入文本长度
        int textWidth = textView.getWidth();
        if (null == text || text.isEmpty() || textWidth <= 0) {
            return;
        }
        //获取输入框总的可输入的文本长度
        float maxInputWidth = textView.getWidth() - textView.getPaddingLeft() - textView.getPaddingRight();
        //获取当前文本字体大小
        float currentTextSize = textView.getTextSize();
        Log.d("AutoScaleSizeEditText","currentTextSize=" + String.valueOf(currentTextSize));
        //设置画笔的字体大小
        paint.setTextSize(currentTextSize);
        /*
         * 循环减小字体大小
         * 当  1、文本字体小于最大值
         *     2、可输入文本长度小于已输入文本长度
         * 时
         */
        while ((currentTextSize > minTextSize) && (maxInputWidth < paint.measureText(text))) {
            hasScaleSmall = true;
            Log.d("AutoScaleSizeEditText","TextSizeChange=" + String.valueOf(currentTextSize));
            --currentTextSize;
            if (currentTextSize < minTextSize) {
                currentTextSize = minTextSize;
                break;
            }
            //设置画笔字体大小
            paint.setTextSize(currentTextSize);
        }
        /*
         * 循环增大字体大小
         * 当  1、文本字体小于默认值
         *     2、可输入文本长度大于已输入文本长度
         * 时
         */
        while (hasScaleSmall && (currentTextSize < maxTextSize)
                && (maxInputWidth > paint.measureText(text))) {
            Log.d("AutoScaleSizeEditText",
                    "TextSizeChangeSmall=" + String.valueOf(currentTextSize));
            ++currentTextSize;
            if (currentTextSize > maxTextSize) {
                currentTextSize = maxTextSize;
                break;
            }
            //设置画笔字体大小
            paint.setTextSize(currentTextSize);
        }
        //设置文本字体(单位为像素px)
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, currentTextSize);
        Log.d("AutoScaleSizeEditText",
                "currentTextSize2=" + String.valueOf(currentTextSize));
    }
}

AutoAdaptSizeEditText

之所以修改原始 AutoAdjustSizeEditText 控件,主要是考虑到我当前场景为单行场景,且宽度固定,如果一直对输入内容不做限制,用户体验上可能不太好(感觉部分朋友应该也会遇到类似场景)

自定义属性(因为我Demo中这俩款自定义控件都用到了自定义属性;而自定义属性不可重复,所以这里命名稍有改变)

    <!-- 文本自动调整大小显示自定义属性 -->
    <declare-styleable name="AutoAdaptTextSize">
        <attr name="minSize" format="dimension" />
        <attr name="maxSize" format="dimension" />
    </declare-styleable>

AutoAdaptSizeEditText (感觉改的还行,不过还能优化一些写法,有时间再说吧)

package com.example.edittextdemo;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.EditText;
import android.widget.TextView;


/**
 * 自动调整字体文本输入框,限制单行输入宽度
 *
 * @author ly
 * @date 2023
 */
@SuppressLint("AppCompatCustomView")
public class AutoAdaptSizeEditText extends EditText {
    /**
     * 默认文字字体大小最小值(单位:像素)
     */
    private static final float DEFAULT_TEXT_SIZE_MIN = 20;

    /**
     * 默认文字字体大小最大值(单位:像素)(貌似用不上)
     */
    @SuppressWarnings("unused")
    private static final float DEFAULT_TEXT_SIZE_MAX = 60;

    /**
     * 画笔(用来测量已输入文字的长度)
     */
    private Paint paint;

    /**
     * 文字字体大小最小值
     */
    private float minTextSize = 0;

    /**
     * 文字字体大小最大值
     */
    private float maxTextSize = 0;

    /**
     * 判断输入文本字体是否变小过
     */
    private boolean hasScaleSmall = false;

    /**
     * 可输出文本的最大长度
     */
    private int length = 0;
    /**
     * 可编辑状态
     */
    private boolean editState = false;


    public AutoAdaptTextSize(Context context) {
        super(context);
        paint = new Paint();
    }

    public AutoAdaptTextSize(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public void init(Context context, AttributeSet attrs) {
        paint = new Paint();
        editState = true;
        //读取自定义属性, 获取设置的字体大小范围
        if (null != attrs) {
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AutoAdaptTextSize);
            if (null != array) {
                minTextSize = array.getDimension(R.styleable.AutoAdaptTextSize_minSize, DEFAULT_TEXT_SIZE_MIN);
                //如果未设置字体最大值,则使用当前字体大小作为最大值
                maxTextSize = array.getDimension(R.styleable.AutoAdaptTextSize_maxSize, this.getTextSize());
                //回收 TypedArray
                array.recycle();
            }
        }
        //未设置字体最小值,则使用默认最小值
        if (0 == minTextSize) {
            minTextSize = DEFAULT_TEXT_SIZE_MIN;
        }
        //未设置字体最大值,则使用当前字体大小作为最大值
        if (0 == maxTextSize) {
            //            maxTextSize = DEFAULT_TEXT_SIZE_MAX;
            maxTextSize = this.getTextSize();
        }
        //如果设置的值不正确(例如minTextSize>maxTextSize),则互换
        if (minTextSize > maxTextSize) {
            float minSize = maxTextSize;
            maxTextSize = minTextSize;
            minTextSize = minSize;
        }
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        // 根据需要调整字体大小
        autoAdaptTextSize(this);
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // 对比前后输入前后字体大小
        if (w != oldw) {
            autoAdaptTextSize(this);
        }
        super.onSizeChanged(w, h, oldw, oldh);
    }

    /**
     * 调整文本的显示
     */
    private void autoAdaptTextSize(TextView textView) {
        if (null == textView) {
            //参数错误,不与处理
            return;
        }
        //已输入文本
        String text = textView.getText().toString();
        //已输入文本长度
        int textWidth = textView.getWidth();
        if (text.isEmpty() || textWidth <= 0) {
            return;
        }
        //获取输入框总的可输入的文本长度
        float maxInputWidth = textView.getWidth() - textView.getPaddingLeft() - textView.getPaddingRight();
        //获取当前文本字体大小
        float currentTextSize = textView.getTextSize();
        Log.d("AutoScaleSizeEditText", "currentTextSize=" + String.valueOf(currentTextSize));
        //设置画笔的字体大小
        paint.setTextSize(currentTextSize);
        /*
         * 循环减小字体大小,条件如下
         * 1、文本字体小于最大值
         * 2、可输入文本长度小于已输入文本长度
         */
        while ((currentTextSize > minTextSize) && (paint.measureText(text) > maxInputWidth)) {
            Log.e("tag", "paint.measureText(text)=" + paint.measureText(text) + "maxInputWidth:" + maxInputWidth);
            hasScaleSmall = true;
            --currentTextSize;
            if (currentTextSize < minTextSize) {
                currentTextSize = minTextSize;
                break;
            }
            //设置画笔字体大小
            paint.setTextSize(currentTextSize);
        }
        /*
         * 循环增大字体大小,条件如下
         * 1、文本字体小于默认值
         * 2、可输入文本长度大于已输入文本长度
         */
        while (hasScaleSmall && (currentTextSize < maxTextSize) && (maxInputWidth > paint.measureText(text))) {
            ++currentTextSize;
            if (currentTextSize > maxTextSize) {
                currentTextSize = maxTextSize;
                break;
            }
            //设置画笔字体大小
            paint.setTextSize(currentTextSize);
        }

        /*
         * 限制输入,条件如下
         * 1、当前字体大小已经为我们设置的最小字体(兼容最小值)
         * 2、所有字体的宽度对比控件的最大宽度
         */
        Log.e("tag", "当前字体Size=" + currentTextSize + "最小字体Size:" + minTextSize);
        Log.e("tag", "字体宽度=" + paint.measureText(text) + "控件宽度:" + maxInputWidth);
        if (currentTextSize <= minTextSize && paint.measureText(text) > maxInputWidth) {
            Log.e("tag", "超过预设值,不支持继续输入");
            if (editState) {
                editState = false;
                length = text.length();
            }
            if (text.length() > length) {
                this.setText(text.substring(0, length));
                this.setSelection(length); //光标位于尾部
            }
            //最大可输出入字符数,限制输入的关键点
            this.setEms(length);
        } else {
            editState = true;
        }
        //设置文本字体(单位为像素px)
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, currentTextSize);
    }

}

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

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

相关文章

商城-学习整理-高级-消息队列(十七)

目录 一、RabbitMQ简介(消息中间件)1、RabbitMQ简介&#xff1a;2、核心概念1、Message2、Publisher3、Exchange4、Queue5、Binding6、Connection7、Channel8、Consumer9、Virtual Host10、Broker 二、一些概念1、异步处理2、应用解耦3、流量控制5、概述 三、Docker安装RabbitM…

开源全球地理空间数据可视化框架——Cesium学习(2023.8.21)

Cesium学习 2023.8.21 1、Cesium简介1.1 Github上的Cesium 2、Cesium下载安装使用2.1 方式一&#xff1a;页面在线引用2.2 方式二&#xff1a;页面离线使用2.3 方式三&#xff1a;完整项目使用 3、CesiumJS学习教程&#xff08;快速上手 API文档&#xff09;3、Cesium官方示例…

EasyCode代码生成MybatisPlus

先安装插件 导入 { "author" : "wangyujie", "version" : "1.2.8", "userSecure" : "", "currTypeMapperGroupName" : "Default", "currTemplateGroupName" : "01-Mybatis-Pl…

HTML a标签

<a>标签定义一个超链接。它有如下主要属性&#xff1a; href&#xff1a;指定链接的地址&#xff0c;可以是一个URL、文件路径或锚点。target&#xff1a;指定链接在何处打开。其值包括&#xff1a; _blank&#xff1a;在新窗口或新标签页打开链接。_self&#xff1a;在…

【笔记】Spark3 AQE(Adaptive Query Execution)

提效 7 倍&#xff0c;Apache Spark 自适应查询优化在网易的深度实践及改进 Performance Tuning 配置Spark SQL开启Adaptive Execution特性 How To Use Spark Adaptive Query Execution (AQE) in Kyuubi 【spark系列3】spark 3.0.1 AQE(Adaptive Query Exection)分析 玩转Spark…

jmeter入门:接口压力测试全解析

一.对接口压力测试 1.配置 1.添加线程组&#xff08;参数上文有解释 这里不介绍&#xff09; 2.添加取样器 不用解释一看就知道填什么。。。 3.添加头信息&#xff08;否则请求头对不上&#xff09; 也不用解释。。。 4.配置监听器 可以尝试使用这几个监听器。 2.聚合结果…

MySQL 字符集概念、原理及如何配置 — 图文详解

目录 一、字符集概念 1、字符&#xff08;Character&#xff09; 2、字符编码 3、字符集&#xff08;Character set&#xff09; 二、字符集原理 1. ASCII字符集 2、GB2312 3、GBK 4、GB18030 5、BIG5 6、Unicode 编码 三、字符序 四、MySQL字符集 & 字符序 …

web基础+HTTP协议+httpd详细配置

目目录录 一、Web基础1.1 HTML概述1.1.1 HTML的文件结构1.1.2 HTML中的部分基本标签 1.3 MIME1.4 URI 和 URL1.4 定义1.4.2 URI 和 URL 的区别 二、静态资源和动态资源2.1 静态资源2.2 动态资源 三、HTTP协议3.1 HTTP协议简介3.2 HTTP协议版本3.2 HTTP方法3.3 HTTP请求访问的完…

李宏毅机器学习笔记:结构学习,HMM,CRF

李宏毅机器学习笔记&#xff1a;结构学习&#xff0c;HMM&#xff0c;CRF 1、隐马尔可夫模型HMM1.1Sequence2Sequence1.2 HMM1.3 Viterbi算法1.3 HMM模型的缺点 1、隐马尔可夫模型HMM 1.1Sequence2Sequence 什么是Seq2Seq问题呢&#xff1f;简单来说&#xff0c;就是输入是一…

RTSP/Onvif视频服务器EasyNVR安防视频云服务调用接口录像会被自动删除的问题解决方案

EasyNVR安防视频云服务是基于RTSP/Onvif协议接入的视频平台&#xff0c;可支持将接入的视频流进行全平台、全终端的分发&#xff0c;分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等。平台丰富灵活的视频能力&#xff0c;可应用在智慧校园、智慧工厂、智慧水利等…

Python“牵手”京东商品详情数据采集方法,京东API申请步骤说明

京东平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范。 京东API接口是指通过编程的方式&#xff0c;让开发者能够通过HTTP协议直接访问京东平台的数据&#xff0c;包括商品信息、店铺信息、物流信息等&#xff0c;从而实现京东平台的数据开…

自动驾驶合成数据科普一:不做真实数据的“颠覆者”,做“杠杆”

前言&#xff1a; 在7月底的一篇文章中&#xff0c;九章智驾提到&#xff0c;数据闭环能力是自动驾驶下半场的“入场券”&#xff0c;这一观点在行业内引起了广泛共鸣。 在数据闭环体系中&#xff0c;仿真技术无疑是非常关键的一环。仿真的起点是数据&#xff0c;而数据又分为真…

回归预测 | MATLAB实现WOA-RBF鲸鱼优化算法优化径向基函数神经网络多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现WOA-RBF鲸鱼优化算法优化径向基函数神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现WOA-RBF鲸鱼优化算法优化径向基函数神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#…

短视频seo源码矩阵系统开源---代码php分享

前言&#xff1a;短视频seo源码 短视频seo矩阵系统源码私有化部署 短视频seo源码 短视频seo矩阵系统源码私有化怎么部署&#xff1f; 首先我们来给大家普及一下什么是短视频seo矩阵系统&#xff1f;视频矩阵分为多平台矩阵与一个平台多账号矩阵&#xff0c;加上seo排名优化&…

EasyPOI 实战总结

EasyPOI实战总结 简介 easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法 使用EasyPOI 环境搭建 # 1.引入相关依…

R包开发一:R与Git版本控制

目录 1.安装Git 2-配置Git&#xff08;只需配置一次&#xff09; 3-用SSH连接GitHub(只需配置一次) 4-创建Github远程仓库 5-克隆仓库到本地 目标&#xff1a;创建的R包&#xff0c;包含Git版本控制&#xff0c;并且能在远程Github仓库同步&#xff0c;相当于发布在Github。…

基于Spring Boot的游泳馆管理系统的设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的游泳馆管理系统的设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java spring…

R语言机器学习方法在生态经济学领域

近年来&#xff0c;人工智能领域已经取得突破性进展&#xff0c;对经济社会各个领域都产生了重大影响&#xff0c;结合了统计学、数据科学和计算机科学的机器学习是人工智能的主流方向之一&#xff0c;目前也在飞快的融入计量经济学研究。表面上机器学习通常使用大数据&#xf…

HarmonyOS学习路之方舟开发框架—学习ArkTS语言(状态管理 四)

Observed装饰器和ObjectLink装饰器&#xff1a;嵌套类对象属性变化 上文所述的装饰器仅能观察到第一层的变化&#xff0c;但是在实际应用开发中&#xff0c;应用会根据开发需要&#xff0c;封装自己的数据模型。对于多层嵌套的情况&#xff0c;比如二维数组&#xff0c;或者数…

pycharm远程连接docker容器

pycharm远程连接docker容器 1.根据镜像创建容器2.进入容器3.修改容器的root密码4. 容器安装openssh-server和openssh-client5.修改SSH配置文件6.重启ssh服务7. 退出测试8.配置pycharm并连接docker容器9. 选择docker环境 1.根据镜像创建容器 sudo docker run -itd --nameconn_t…