Parcourir la source

ncse量表开发

hurixing il y a 1 an
Parent
commit
7a01cb7ee8

+ 50 - 0
ncse/src/main/java/com/yingyangfly/ncse/entity/MyLine.java

@@ -0,0 +1,50 @@
+package com.yingyangfly.ncse.entity;
+
+public class MyLine {
+
+    int startx;
+    int starty;
+    int endx;
+    int endy;
+    String anwer;
+
+    public int getStartx() {
+        return startx;
+    }
+
+    public void setStartx(int startx) {
+        this.startx = startx;
+    }
+
+    public int getStarty() {
+        return starty;
+    }
+
+    public void setStarty(int starty) {
+        this.starty = starty;
+    }
+
+    public int getEndx() {
+        return endx;
+    }
+
+    public void setEndx(int endx) {
+        this.endx = endx;
+    }
+
+    public int getEndy() {
+        return endy;
+    }
+
+    public void setEndy(int endy) {
+        this.endy = endy;
+    }
+
+    public String getAnwer() {
+        return anwer;
+    }
+
+    public void setAnwer(String anwer) {
+        this.anwer = anwer;
+    }
+}

+ 6 - 3
ncse/src/main/java/com/yingyangfly/ncse/fragment/IdentifyImageResultFragment.kt

@@ -148,11 +148,14 @@ class IdentifyImageResultFragment : BaseFragment<FragmentIdentifyImageResultBind
      */
     private fun nextPage(v: View) {
         if (judge()) {
+            val controller = Navigation.findNavController(v)
+            val bundle = bundleOf("questionId" to questionId+4)
             if (questionId == 124){
-
+                controller.navigate(
+                    R.id.action_identifyImageResultFragment_to_structureOrganizationFragment,
+                    bundle
+                )
             } else {
-                val controller = Navigation.findNavController(v)
-                val bundle = bundleOf("questionId" to questionId+4)
                 controller.navigate(
                     R.id.action_identifyImageResultFragment_to_namingAbilityFragment,
                     bundle

+ 142 - 0
ncse/src/main/java/com/yingyangfly/ncse/fragment/PictureRecognitionJudgmentFragment.kt

@@ -0,0 +1,142 @@
+package com.yingyangfly.ncse.fragment
+
+import android.annotation.SuppressLint
+import android.graphics.Bitmap
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.view.MotionEvent
+import android.view.View
+import androidx.core.os.bundleOf
+import androidx.navigation.Navigation
+import com.yingyangfly.baselib.base.BaseFragment
+import com.yingyangfly.baselib.db.QuestionsBean
+import com.yingyangfly.baselib.ext.getEndAnimation
+import com.yingyangfly.baselib.ext.getScaleAnimation
+import com.yingyangfly.baselib.utils.ImageUtil
+import com.yingyangfly.ncse.R
+import com.yingyangfly.ncse.databinding.FragmentPictureRecognitionJudgmentBinding
+
+/**
+ * 视结构 结果判断
+ */
+class PictureRecognitionJudgmentFragment : BaseFragment<FragmentPictureRecognitionJudgmentBinding>(),View.OnTouchListener {
+
+    private var questionId = 0
+    private var bitmap: Bitmap? = null
+    private var question: QuestionsBean? = null
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        questionId = arguments?.getInt("questionId") ?: 128
+        bitmap = arguments?.getParcelable("bitmap")
+        super.onCreate(savedInstanceState)
+    }
+
+    override fun initViews() {
+    }
+
+    @SuppressLint("ClickableViewAccessibility")
+    override fun initListener() {
+        binding {
+            btnPrevious.setOnTouchListener(this@PictureRecognitionJudgmentFragment)
+            btnNext.setOnTouchListener(this@PictureRecognitionJudgmentFragment)
+            judgeRadio.setOnCheckedChangeListener { _, checkedId ->
+                question!!.reviewId = question!!.id
+                question!!.reviewAnswer = ""
+                if (checkedId == R.id.btnDeny) {
+                    if (question != null && questionsDao != null) {
+                        question!!.inputString = "否"
+                        question!!.correct = "0"
+                        questionsDao?.update(question!!)
+                    }
+                } else if (checkedId == R.id.btnCorrect) {
+                    if (question != null && questionsDao != null) {
+                        question!!.inputString = "是"
+                        question!!.correct = "1"
+                        questionsDao?.update(question!!)
+                    }
+                }
+            }
+        }
+    }
+
+    override fun initData() {
+    }
+
+    @SuppressLint("ClickableViewAccessibility")
+    override fun onTouch(v: View, event: MotionEvent): Boolean {
+        when(event.action){
+            MotionEvent.ACTION_DOWN -> {
+                if (v.id == R.id.btnPrevious || v.id == R.id.btnNext) {
+                    v.startAnimation(getScaleAnimation())
+                }
+            }
+            MotionEvent.ACTION_UP ->{
+                v.startAnimation(getEndAnimation())
+                if (v.id == R.id.btnPrevious) {
+                    previousPage(v)
+                } else if (v.id == R.id.btnNext) {
+                    nextPage(v)
+                }
+            }
+            MotionEvent.ACTION_CANCEL ->{
+                if (v.id == R.id.btnPrevious || v.id == R.id.btnNext) {
+                    v.startAnimation(getEndAnimation())
+                }
+            }
+        }
+        return true
+    }
+
+
+    override fun onResume() {
+        super.onResume()
+        loadData()
+    }
+
+    /**
+     * 加载数据
+     */
+    private fun loadData() {
+        if (bitmap != null) {
+            val drawable: Drawable = BitmapDrawable(bitmap)
+            ImageUtil.loadUrl(mContext, drawable, binding.designsImage)
+        }
+        if (questionsDao != null) {
+            question = questionsDao?.getQuestion(questionId)
+            if (question != null) {
+                binding {
+                    data = question
+                }
+            }
+        }
+    }
+
+    /**
+     * 上一页
+     */
+    private fun previousPage(v: View) {
+        if(questionId == 128) {
+            val controller = Navigation.findNavController(v)
+            val bundle = bundleOf("questionId" to 128)
+            controller.navigate(
+                R.id.action_pictureRecognitionJudgmentFragment_to_structureOrganizationFragment,
+                bundle
+            )
+        }
+    }
+
+    /**
+     * 下一页
+     */
+    private fun nextPage(v: View) {
+        if(questionId == 128) {
+            val controller = Navigation.findNavController(v)
+            val bundle = bundleOf("questionId" to 129)
+            controller.navigate(
+                R.id.action_pictureRecognitionJudgmentFragment_to_structureOrganizationFragment,
+                bundle
+            )
+        }
+    }
+}

+ 156 - 0
ncse/src/main/java/com/yingyangfly/ncse/fragment/StructureOrganizationFragment.kt

@@ -0,0 +1,156 @@
+package com.yingyangfly.ncse.fragment
+
+import android.annotation.SuppressLint
+import android.graphics.Bitmap
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.view.MotionEvent
+import android.view.View
+import androidx.core.os.bundleOf
+import androidx.navigation.Navigation
+import com.yingyangfly.baselib.base.BaseFragment
+import com.yingyangfly.baselib.db.QuestionsBean
+import com.yingyangfly.baselib.ext.getEndAnimation
+import com.yingyangfly.baselib.ext.getScaleAnimation
+import com.yingyangfly.ncse.R
+import com.yingyangfly.ncse.databinding.FragmentStructureOrganizationBinding
+
+/**
+ * 看图画图
+ */
+class StructureOrganizationFragment : BaseFragment<FragmentStructureOrganizationBinding>(), View.OnTouchListener {
+
+    /**
+     * 原始问题id
+     */
+    private var questionId = 0
+    private var question: QuestionsBean? = null
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        questionId = arguments?.getInt("questionId") ?: 128
+        super.onCreate(savedInstanceState)
+    }
+    override fun initViews() {
+    }
+
+    @SuppressLint("ClickableViewAccessibility")
+    override fun initListener() {
+        binding {
+            rubberLayout.setOnTouchListener(this@StructureOrganizationFragment)
+            btnPrevious.setOnTouchListener(this@StructureOrganizationFragment)
+            btnNext.setOnTouchListener(this@StructureOrganizationFragment)
+            tvObservationTheSec.setOnTouchListener(this@StructureOrganizationFragment)
+            tvImmediateObservation.setOnTouchListener(this@StructureOrganizationFragment)
+        }
+    }
+
+    override fun initData() {
+
+    }
+
+    override fun onResume() {
+        super.onResume()
+        loadData()
+    }
+
+    private fun showImage() {
+        immediateShowImage()
+        Handler(Looper.getMainLooper()).postDelayed({
+            loadData()
+        }, 10000)
+    }
+
+    private fun immediateShowImage() {
+        if (questionsDao != null) {
+            question = questionsDao?.getQuestion(questionId)
+            if (question != null) {
+                binding {
+                    data = question
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 加载数据
+     */
+    private fun loadData() {
+        if (questionsDao != null) {
+            question = questionsDao?.getQuestion(questionId)
+            if (question != null) {
+                binding {
+                    question?.reviewDesc = ""
+                    data = question
+                }
+            }
+        }
+    }
+
+    @SuppressLint("ClickableViewAccessibility")
+    override fun onTouch(v: View, event: MotionEvent): Boolean {
+        when (event.action) {
+            MotionEvent.ACTION_DOWN -> {
+                if (v.id == R.id.btnPrevious || v.id == R.id.btnNext || v.id == R.id.rubberLayout) {
+                    v.startAnimation(getScaleAnimation())
+                }
+            }
+            MotionEvent.ACTION_UP -> {
+                v.startAnimation(getEndAnimation())
+                when (v.id) {
+                    R.id.btnPrevious -> {
+                        previousPage(v)
+                    }
+                    R.id.btnNext -> {
+                        nextPage(v)
+                    }
+                    R.id.rubberLayout -> {
+                        binding.signatureView.clear()
+                    }
+                    R.id.tvObservationTheSec -> {
+                        showImage()
+                    }
+                    R.id.tvImmediateObservation -> {
+                        immediateShowImage()
+                    }
+                }
+            }
+            MotionEvent.ACTION_CANCEL -> {
+                if (v.id == R.id.btnPrevious || v.id == R.id.btnNext || v.id == R.id.rubberLayout) {
+                    v.startAnimation(getEndAnimation())
+                }
+            }
+        }
+        return true
+    }
+
+    /**
+     * 上一页
+     */
+    private fun previousPage(v: View) {
+        if (questionId == 128) {
+            val controller = Navigation.findNavController(v)
+            val bundle = bundleOf("questionId" to 124)
+            controller.navigate(
+                R.id.action_structureOrganizationFragment_to_identifyImageResultFragment,
+                bundle
+            )
+        }
+    }
+
+    /**
+     * 下一页
+     */
+    private fun nextPage(v: View) {
+        val bundle = Bundle()
+        bundle.putInt("questionId", 128)
+        val bitmap: Bitmap = binding.signatureView.getCachebBitmaps()
+        bundle.putParcelable("bitmap", bitmap)
+        val controller = Navigation.findNavController(v)
+        controller.navigate(
+            R.id.action_structureOrganizationFragment_to_pictureRecognitionJudgmentFragment,
+            bundle
+        )
+    }
+}

+ 2 - 1
ncse/src/main/java/com/yingyangfly/ncse/fragment/startDNAPCFragment.kt

@@ -125,7 +125,8 @@ class startDNAPCFragment: BaseFragment<FragmentStartdnapcBinding>(),View.OnTouch
      */
     private fun pageUp(v: View) {
         if (questionId == 83){
-            Snackbar.make(v, "已经是第一题了", Snackbar.LENGTH_LONG).show();
+            val str = "这已经是第一题了"
+            str.toast()
         }else{
             if (questionId == 90){
                 questionId--

+ 90 - 0
ncse/src/main/java/com/yingyangfly/ncse/widget/DrawLineView.java

@@ -0,0 +1,90 @@
+package com.yingyangfly.ncse.widget;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.os.Build;
+import android.util.AttributeSet;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.yingyangfly.baselib.utils.ScreenUtil;
+import com.yingyangfly.ncse.R;
+import com.yingyangfly.ncse.entity.MyLine;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DrawLineView extends ConstraintLayout {
+
+    private Context context;
+    private boolean isReset = false;
+    private List<MyLine> linkLineBeanList = new ArrayList<>();
+
+    public DrawLineView(Context context) {
+        this(context, null);
+    }
+
+    public DrawLineView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public DrawLineView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(context);
+    }
+
+    private void init(Context context) {
+        this.context = context;
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.M)
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+        // 先清除掉原有绘制的线
+        if (isReset) {
+            for (MyLine item : linkLineBeanList) {
+                if (item != null) {
+                    Paint paint = new Paint();
+                    paint.setColor(Color.TRANSPARENT);
+                    paint.setStrokeWidth(ScreenUtil.INSTANCE.dip2px(context, 2));
+                    canvas.drawLine(item.getStartx(), item.getStarty(), item.getEndx(), item.getEndy(), paint);
+                }
+            }
+        } else {
+            for (MyLine item : linkLineBeanList) {
+                if (item != null) {
+                    Paint paint = new Paint();
+                    paint.setColor(context.getColor(R.color.color_FF4A76FF));
+                    paint.setStrokeWidth(ScreenUtil.INSTANCE.dip2px(context, 2));
+                    canvas.drawLine(item.getStartx(), item.getStarty(), item.getEndx(), item.getEndy(), paint);
+                }
+            }
+        }
+    }
+
+    /**
+     * 练习
+     *
+     * @param linkDataBeanList
+     */
+    public void setData(List<MyLine> linkDataBeanList) {
+        if (linkDataBeanList == null || linkDataBeanList.size() == 0) {
+            return;
+        }
+        isReset = false;
+        linkLineBeanList.clear();
+        linkLineBeanList.addAll(linkDataBeanList);
+        invalidate();
+    }
+
+    public void clearData() {
+        isReset = true;
+        invalidate();
+    }
+}

+ 363 - 0
ncse/src/main/java/com/yingyangfly/ncse/widget/DrawPathView.kt

@@ -0,0 +1,363 @@
+package com.yingyangfly.ncse.widget
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.PorterDuff
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.View
+import androidx.annotation.ColorInt
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.io.OutputStream
+import kotlin.math.max
+import kotlin.math.min
+
+class DrawPathView : View {
+
+    private var mContext: Context? = null
+
+    /**
+     * 笔画X坐标起点
+     */
+    private var mX = 0f
+
+    /**
+     * 笔画Y坐标起点
+     */
+    private var mY = 0f
+
+    /**
+     * 手写画笔
+     */
+    private val mGesturePaint = Paint()
+
+    /**
+     * 路径
+     */
+    private val mPath = Path()
+
+    /**
+     * 签名画笔
+     */
+    private var cacheCanvas: Canvas? = null
+
+    /**
+     * 签名画布
+     */
+    var cachebBitmap: Bitmap? = null
+
+    /**
+     * 是否有签名
+     *
+     * @return
+     */
+    /**
+     * 是否已经签名
+     */
+    var touched = false
+        private set
+
+    /**
+     * 画笔宽度 px;
+     */
+    private var mPaintWidth = 10
+
+    /**
+     * 前景色
+     */
+    private var mPenColor = Color.BLACK
+
+    /**
+     * 背景色(指最终签名结果文件的背景颜色,默认为透明色)
+     */
+    private var mBackColor = Color.TRANSPARENT
+
+    //签名开始与结束
+    var touch: Touch? = null
+
+    constructor(context: Context?) : super(context) {
+        init(context)
+    }
+
+    constructor(context: Context?, attrs: AttributeSet?) : super(
+        context,
+        attrs
+    ) {
+        init(context)
+    }
+
+    constructor(
+        context: Context?,
+        attrs: AttributeSet?,
+        defStyleAttr: Int
+    ) : super(context, attrs, defStyleAttr) {
+        init(context)
+    }
+
+    private fun init(context: Context?) {
+        mContext = context
+        //设置抗锯齿
+        mGesturePaint.isAntiAlias = true
+        //设置签名笔画样式
+        mGesturePaint.style = Paint.Style.STROKE
+        //设置笔画宽度
+        mGesturePaint.strokeWidth = mPaintWidth.toFloat()
+        //设置签名颜色
+        mGesturePaint.color = mPenColor
+    }
+
+    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
+        super.onSizeChanged(w, h, oldw, oldh)
+        //创建跟view一样大的bitmap,用来保存签名
+        cachebBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+        cacheCanvas = Canvas(cachebBitmap!!)
+        cacheCanvas!!.drawColor(mBackColor)
+        touched = false
+    }
+
+    override fun onTouchEvent(event: MotionEvent): Boolean {
+        if (touch != null) touch!!.OnTouch(true)
+        when (event.action) {
+            MotionEvent.ACTION_DOWN -> touchDown(event)
+            MotionEvent.ACTION_MOVE -> {
+                touched = true
+                if (touch != null) touch!!.OnTouch(false)
+                touchMove(event)
+            }
+            MotionEvent.ACTION_UP -> {
+                //将路径画到bitmap中,即一次笔画完成才去更新bitmap,而手势轨迹是实时显示在画板上的。
+                cacheCanvas!!.drawPath(mPath, mGesturePaint)
+                mPath.reset()
+            }
+        }
+        // 更新绘制
+        invalidate()
+        return true
+    }
+
+    override fun onDraw(canvas: Canvas) {
+        super.onDraw(canvas)
+        //画此次笔画之前的签名
+        canvas.drawBitmap(cachebBitmap!!, 0f, 0f, mGesturePaint)
+        // 通过画布绘制多点形成的图形
+        canvas.drawPath(mPath, mGesturePaint)
+    }
+
+    // 手指点下屏幕时调用
+    private fun touchDown(event: MotionEvent) {
+        // 重置绘制路线
+        mPath.reset()
+        val x = event.x
+        val y = event.y
+        mX = x
+        mY = y
+        // mPath绘制的绘制起点
+        mPath.moveTo(x, y)
+    }
+
+    // 手指在屏幕上滑动时调用
+    private fun touchMove(event: MotionEvent) {
+        val x = event.x
+        val y = event.y
+        val previousX = mX
+        val previousY = mY
+        val dx = Math.abs(x - previousX)
+        val dy = Math.abs(y - previousY)
+        // 两点之间的距离大于等于3时,生成贝塞尔绘制曲线
+        if (dx >= 3 || dy >= 3) {
+            // 设置贝塞尔曲线的操作点为起点和终点的一半
+            val cX = (x + previousX) / 2
+            val cY = (y + previousY) / 2
+            // 二次贝塞尔,实现平滑曲线;previousX, previousY为操作点,cX, cY为终点
+            mPath.quadTo(previousX, previousY, cX, cY)
+            // 第二次执行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值
+            mX = x
+            mY = y
+        }
+    }
+
+    /**
+     * 清除画板
+     */
+    fun clear() {
+        if (cacheCanvas != null) {
+            touched = false
+            //更新画板信息
+            mGesturePaint.color = mPenColor
+            cacheCanvas!!.drawColor(mBackColor, PorterDuff.Mode.CLEAR)
+            mGesturePaint.color = mPenColor
+            invalidate()
+        }
+    }
+
+    interface Touch {
+        fun OnTouch(isTouch: Boolean)
+    }
+
+    /**
+     * 保存画板
+     *
+     * @param path 保存到路径
+     */
+    @JvmOverloads
+    @Throws(IOException::class)
+    fun save(
+        path: String?,
+        clearBlank: Boolean = false,
+        blank: Int = 0
+    ) {
+        var bitmap = cachebBitmap
+        if (clearBlank) {
+            bitmap = clearBlank(bitmap, blank)
+        }
+        val bos = ByteArrayOutputStream()
+        bitmap!!.compress(Bitmap.CompressFormat.PNG, 100, bos)
+        val buffer = bos.toByteArray()
+        val file = File(path)
+        if (file.exists()) {
+            file.delete()
+        }
+        val outputStream: OutputStream = FileOutputStream(file)
+        outputStream.write(buffer)
+        outputStream.close()
+    }
+
+    fun getCachebBitmaps(): Bitmap {
+        val bitmap = cachebBitmap
+        val bos = ByteArrayOutputStream()
+        bitmap!!.compress(Bitmap.CompressFormat.PNG, 100, bos)
+        return bitmap
+    }
+
+    /**
+     * 获取画板的bitmap
+     *
+     * @return
+     */
+    val bitMap: Bitmap
+        get() {
+            isDrawingCacheEnabled = true
+            buildDrawingCache()
+            val bitmap = drawingCache
+            isDrawingCacheEnabled = false
+            return bitmap
+        }
+
+    /**
+     * 逐行扫描 清楚边界空白。
+     *
+     * @param bp
+     * @param blank 边距留多少个像素
+     * @return
+     */
+    private fun clearBlank(bp: Bitmap?, blank: Int): Bitmap {
+        var blank = blank
+        val HEIGHT = bp!!.height
+        val WIDTH = bp.width
+        var top = 0
+        var left = 0
+        var right = 0
+        var bottom = 0
+        var pixs = IntArray(WIDTH)
+        var isStop: Boolean
+        //扫描上边距不等于背景颜色的第一个点
+        for (y in 0 until HEIGHT) {
+            bp.getPixels(pixs, 0, WIDTH, 0, y, WIDTH, 1)
+            isStop = false
+            for (pix in pixs) {
+                if (pix != mBackColor) {
+                    top = y
+                    isStop = true
+                    break
+                }
+            }
+            if (isStop) {
+                break
+            }
+        }
+        //扫描下边距不等于背景颜色的第一个点
+        for (y in HEIGHT - 1 downTo 0) {
+            bp.getPixels(pixs, 0, WIDTH, 0, y, WIDTH, 1)
+            isStop = false
+            for (pix in pixs) {
+                if (pix != mBackColor) {
+                    bottom = y
+                    isStop = true
+                    break
+                }
+            }
+            if (isStop) {
+                break
+            }
+        }
+        pixs = IntArray(HEIGHT)
+        //扫描左边距不等于背景颜色的第一个点
+        for (x in 0 until WIDTH) {
+            bp.getPixels(pixs, 0, 1, x, 0, 1, HEIGHT)
+            isStop = false
+            for (pix in pixs) {
+                if (pix != mBackColor) {
+                    left = x
+                    isStop = true
+                    break
+                }
+            }
+            if (isStop) {
+                break
+            }
+        }
+        //扫描右边距不等于背景颜色的第一个点
+        for (x in WIDTH - 1 downTo 1) {
+            bp.getPixels(pixs, 0, 1, x, 0, 1, HEIGHT)
+            isStop = false
+            for (pix in pixs) {
+                if (pix != mBackColor) {
+                    right = x
+                    isStop = true
+                    break
+                }
+            }
+            if (isStop) {
+                break
+            }
+        }
+        if (blank < 0) {
+            blank = 0
+        }
+        //计算加上保留空白距离之后的图像大小
+        left = max(left - blank, 0)
+        top = max(top - blank, 0)
+        right = min(right + blank, WIDTH - 1)
+        bottom = min(bottom + blank, HEIGHT - 1)
+        return Bitmap.createBitmap(bp, left, top, right - left, bottom - top)
+    }
+
+    /**
+     * 设置画笔宽度 默认宽度为10px
+     *
+     * @param mPaintWidth
+     */
+    fun setPaintWidth(mPaintWidth: Int) {
+        mGesturePaint.strokeWidth = (if (mPaintWidth > 0) mPaintWidth else 10).toFloat()
+    }
+
+    fun setBackColor(@ColorInt backColor: Int) {
+        mBackColor = backColor
+    }
+
+    /**
+     * 设置画笔颜色
+     *
+     * @param mPenColor
+     */
+    fun setPenColor(mPenColor: Int) {
+        mGesturePaint.color = mPenColor
+    }
+}

+ 7 - 0
ncse/src/main/res/drawable/bg_rubber.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:ignore="ResourceName">
+    <corners android:radius="@dimen/divider_8px" />
+    <solid android:color="@color/color_FF4A76FF" />
+</shape>

+ 198 - 0
ncse/src/main/res/layout/fragment_picture_recognition_judgment.xml

@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout 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"
+    tools:ignore="ResourceName">
+
+    <data>
+
+        <variable
+            name="data"
+            type="com.yingyangfly.baselib.db.QuestionsBean" />
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <TextView
+            android:id="@+id/tvTitle1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/divider_27px"
+            android:layout_marginStart="@dimen/divider_154px"
+            android:text="@string/evaluation_artwork"
+            android:textColor="@color/color_FF222222"
+            android:textSize="@dimen/divider_34px"
+            android:textStyle="bold"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/tvTitle2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/divider_27px"
+            android:layout_marginEnd="@dimen/divider_250px"
+            android:text="@string/drawing_by_the_patient"
+            android:textColor="@color/color_FF222222"
+            android:textSize="@dimen/divider_34px"
+            android:textStyle="bold"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/tvPicture"
+            android:layout_width="@dimen/divider_448px"
+            android:layout_height="@dimen/divider_359px"
+            android:layout_marginTop="@dimen/divider_57px"
+            android:scaleType="centerInside"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/tvTitle1"
+            app:loadImg="@{data.reviewDesc}" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/designsImage"
+            android:layout_width="@dimen/divider_448px"
+            android:layout_height="@dimen/divider_359px"
+            android:layout_marginTop="@dimen/divider_57px"
+            android:layout_gravity="center"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/tvTitle2" />
+
+        <com.google.android.material.card.MaterialCardView
+            android:id="@+id/contentLayout"
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/divider_175px"
+            android:layout_marginTop="@dimen/divider_20px"
+            android:minWidth="@dimen/divider_620px"
+            android:theme="@style/Theme.MaterialComponents.NoActionBar"
+            app:cardBackgroundColor="@android:color/white"
+            app:cardCornerRadius="@dimen/divider_20px"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/designsImage"
+            app:strokeColor="@color/color_FF979797"
+            app:strokeWidth="@dimen/divider_1px">
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:gravity="center_vertical"
+                android:orientation="horizontal">
+
+                <LinearLayout
+                    android:layout_width="@dimen/divider_191px"
+                    android:layout_height="@dimen/divider_175px"
+                    android:background="@color/color_FF4A76FF"
+                    android:gravity="center_horizontal"
+                    android:orientation="vertical">
+
+                    <androidx.appcompat.widget.AppCompatImageView
+                        android:layout_width="@dimen/divider_65px"
+                        android:layout_height="@dimen/divider_86px"
+                        android:layout_gravity="center"
+                        android:layout_marginTop="@dimen/divider_21px"
+                        android:background="@mipmap/icon_doctor_head" />
+
+                    <androidx.appcompat.widget.AppCompatTextView
+                        android:id="@+id/tvYear"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="@dimen/divider_18px"
+                        android:background="@color/color_FF4A76FF"
+                        android:gravity="center_horizontal"
+                        android:text="@string/staff_judgment"
+                        android:textColor="@android:color/white"
+                        android:textSize="@dimen/divider_24px" />
+
+                </LinearLayout>
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/divider_57px"
+                    android:layout_gravity="center_vertical"
+                    android:gravity="center_vertical"
+                    android:orientation="horizontal">
+
+                    <androidx.appcompat.widget.AppCompatTextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginStart="@dimen/divider_33px"
+                        android:text="@string/determine_whether_subject_answer_correct"
+                        android:textColor="@color/color_FF333333"
+                        android:textSize="@dimen/divider_24px" />
+
+                    <RadioGroup
+                        android:id="@+id/judgeRadio"
+                        android:layout_width="match_parent"
+                        android:layout_height="match_parent"
+                        android:gravity="center_horizontal"
+                        android:orientation="horizontal"
+                        app:layout_constraintEnd_toEndOf="parent"
+                        app:layout_constraintStart_toStartOf="parent"
+                        app:layout_constraintTop_toBottomOf="@+id/contentLayout">
+
+                        <RadioButton
+                            android:id="@+id/btnCorrect"
+                            android:layout_width="wrap_content"
+                            android:layout_height="match_parent"
+                            android:layout_marginStart="@dimen/divider_20px"
+                            android:background="@drawable/selector_questions_choice"
+                            android:button="@null"
+                            android:text="@string/correct"
+                            android:textColor="@color/txt_radio_color"
+                            android:textSize="@dimen/divider_24px"
+                            android:textStyle="bold" />
+
+                        <RadioButton
+                            android:id="@+id/btnDeny"
+                            android:layout_width="wrap_content"
+                            android:layout_height="match_parent"
+                            android:layout_marginStart="@dimen/divider_12px"
+                            android:layout_marginEnd="@dimen/divider_19px"
+                            android:background="@drawable/selector_questions_choice"
+                            android:button="@null"
+                            android:text="@string/deny"
+                            android:textColor="@color/txt_radio_color"
+                            android:textSize="@dimen/divider_24px"
+                            android:textStyle="bold" />
+                    </RadioGroup>
+                </LinearLayout>
+            </LinearLayout>
+        </com.google.android.material.card.MaterialCardView>
+
+
+        <androidx.appcompat.widget.AppCompatButton
+            android:id="@+id/btnPrevious"
+            android:layout_width="@dimen/divider_240px"
+            android:layout_height="@dimen/divider_68px"
+            android:layout_marginStart="@dimen/divider_307px"
+            android:layout_marginBottom="@dimen/divider_60px"
+            android:background="@drawable/bg_previous_question"
+            android:gravity="center"
+            android:text="@string/previous_page"
+            android:textColor="@color/color_FF4A76FF"
+            android:textSize="@dimen/divider_28px"
+            android:textStyle="bold"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatButton
+            android:id="@+id/btnNext"
+            android:layout_width="@dimen/divider_240px"
+            android:layout_height="@dimen/divider_68px"
+            android:layout_marginEnd="@dimen/divider_305px"
+            android:layout_marginBottom="@dimen/divider_60px"
+            android:background="@drawable/bg_next_question"
+            android:gravity="center"
+            android:text="@string/continues"
+            android:textColor="@android:color/white"
+            android:textSize="@dimen/divider_28px"
+            android:textStyle="bold"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>

+ 172 - 0
ncse/src/main/res/layout/fragment_structure_organization.xml

@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout 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"
+    tools:ignore="ResourceName">
+
+    <data>
+
+        <variable
+            name="data"
+            type="com.yingyangfly.baselib.db.QuestionsBean" />
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <TextView
+            android:id="@+id/tvTitle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/divider_27px"
+            android:text="@{data.reviewItem}"
+            android:textColor="@color/color_FF222222"
+            android:textSize="@dimen/divider_34px"
+            android:textStyle="bold"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/imageTemplate"
+            android:layout_width="@dimen/divider_179px"
+            android:layout_height="@dimen/divider_179px"
+            android:layout_marginStart="@dimen/divider_63px"
+            android:layout_marginTop="@dimen/divider_149px"
+            android:scaleType="centerInside"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/tvTitle"
+            app:loadImg="@{data.reviewDesc}" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tvHintText"
+            android:layout_width="@dimen/divider_179px"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/divider_34px"
+            android:gravity="center_horizontal"
+            android:text="@string/subjects_can_also_draw_pictures_on_paper"
+            android:textColor="@color/color_FF4A76FF"
+            android:textSize="@dimen/divider_24px"
+            android:textStyle="bold"
+            app:layout_constraintEnd_toStartOf="@+id/drawLayout"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/imageTemplate" />
+
+        <androidx.appcompat.widget.AppCompatButton
+            android:id="@+id/tvObservationTheSec"
+            android:layout_width="@dimen/divider_104px"
+            android:layout_height="@dimen/divider_68px"
+            android:layout_marginTop="@dimen/divider_34px"
+            android:layout_marginStart="@dimen/divider_30px"
+            android:background="@drawable/bg_next_question"
+            android:gravity="center"
+            android:text="@string/observation_10_sec"
+            android:textColor="@android:color/white"
+            android:textSize="@dimen/divider_28px"
+            android:textStyle="bold"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/tvHintText"
+            />
+
+        <androidx.appcompat.widget.AppCompatButton
+            android:id="@+id/tvImmediateObservation"
+            android:layout_width="@dimen/divider_104px"
+            android:layout_height="@dimen/divider_68px"
+            android:layout_marginTop="@dimen/divider_34px"
+            android:layout_marginStart="@dimen/divider_154px"
+            android:background="@drawable/bg_next_question"
+            android:gravity="center"
+            android:text="@string/immediate_observation"
+            android:textColor="@android:color/white"
+            android:textSize="@dimen/divider_28px"
+            android:textStyle="bold"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/tvHintText"
+            />
+
+        <com.google.android.material.card.MaterialCardView
+            android:id="@+id/drawLayout"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginStart="@dimen/divider_38px"
+            android:layout_marginTop="@dimen/divider_45px"
+            android:layout_marginEnd="@dimen/divider_63px"
+            android:layout_marginBottom="@dimen/divider_30px"
+            android:theme="@style/Theme.MaterialComponents.NoActionBar"
+            app:cardBackgroundColor="@android:color/white"
+            app:cardCornerRadius="@dimen/divider_20px"
+            app:layout_constraintBottom_toTopOf="@+id/btnPrevious"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/imageTemplate"
+            app:layout_constraintTop_toBottomOf="@+id/tvTitle"
+            app:strokeColor="@color/color_FF979797"
+            app:strokeWidth="@dimen/divider_1px">
+
+            <com.yingyangfly.ncse.widget.DrawPathView
+                android:id="@+id/signatureView"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+
+            <LinearLayout
+                android:id="@+id/rubberLayout"
+                android:layout_width="@dimen/divider_105px"
+                android:layout_height="@dimen/divider_44px"
+                android:layout_gravity="top|end"
+                android:layout_marginTop="@dimen/divider_20px"
+                android:layout_marginEnd="@dimen/divider_20px"
+                android:background="@drawable/bg_rubber"
+                android:gravity="center_vertical"
+                android:orientation="horizontal">
+
+                <androidx.appcompat.widget.AppCompatImageView
+                    android:layout_width="@dimen/divider_21px"
+                    android:layout_height="@dimen/divider_23px"
+                    android:layout_marginStart="@dimen/divider_15px"
+                    android:background="@mipmap/icon_rubber" />
+
+                <androidx.appcompat.widget.AppCompatTextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginStart="@dimen/divider_8px"
+                    android:text="@string/erase"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/divider_20px" />
+
+            </LinearLayout>
+
+
+        </com.google.android.material.card.MaterialCardView>
+
+        <androidx.appcompat.widget.AppCompatButton
+            android:id="@+id/btnPrevious"
+            android:layout_width="@dimen/divider_240px"
+            android:layout_height="@dimen/divider_68px"
+            android:layout_marginStart="@dimen/divider_307px"
+            android:layout_marginBottom="@dimen/divider_60px"
+            android:background="@drawable/bg_previous_question"
+            android:gravity="center"
+            android:text="@string/previous_page"
+            android:textColor="@color/color_FF4A76FF"
+            android:textSize="@dimen/divider_28px"
+            android:textStyle="bold"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent" />
+
+        <androidx.appcompat.widget.AppCompatButton
+            android:id="@+id/btnNext"
+            android:layout_width="@dimen/divider_240px"
+            android:layout_height="@dimen/divider_68px"
+            android:layout_marginEnd="@dimen/divider_305px"
+            android:layout_marginBottom="@dimen/divider_60px"
+            android:background="@drawable/bg_next_question"
+            android:gravity="center"
+            android:text="@string/continues"
+            android:textColor="@android:color/white"
+            android:textSize="@dimen/divider_28px"
+            android:textStyle="bold"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>

BIN
ncse/src/main/res/mipmap-xxhdpi/icon_rubber.png


+ 24 - 0
ncse/src/main/res/navigation/nav_ncse.xml

@@ -86,6 +86,30 @@
         <action android:id="@+id/action_identifyImageResultFragment_to_namingAbilityFragment"
             app:destination="@+id/namingAbilityFragment"/>
 
+        <action android:id="@+id/action_identifyImageResultFragment_to_structureOrganizationFragment"
+            app:destination="@+id/structureOrganizationFragment"/>
+
+    </fragment>
+
+    <fragment android:id="@+id/structureOrganizationFragment"
+        android:name="com.yingyangfly.ncse.fragment.StructureOrganizationFragment"
+        android:label="StructureOrganizationFragment">
+
+        <action android:id="@+id/action_structureOrganizationFragment_to_identifyImageResultFragment"
+            app:destination="@+id/identifyImageResultFragment"/>
+
+        <action android:id="@+id/action_structureOrganizationFragment_to_pictureRecognitionJudgmentFragment"
+            app:destination="@+id/pictureRecognitionJudgmentFragment"/>
+
+
+    </fragment>
+
+    <fragment android:id="@+id/pictureRecognitionJudgmentFragment"
+        android:name="com.yingyangfly.ncse.fragment.PictureRecognitionJudgmentFragment"
+        android:label="PictureRecognitionJudgmentFragment">
+
+        <action android:id="@+id/action_pictureRecognitionJudgmentFragment_to_structureOrganizationFragment"
+            app:destination="@+id/structureOrganizationFragment"/>
     </fragment>
 
 

+ 6 - 0
ncse/src/main/res/values/strings.xml

@@ -16,4 +16,10 @@
     <string name="previous_page" tools:ignore="ResourceName">上一页</string>
     <string name="fragment_look_picture_input" tools:ignore="ResourceName">请工作人员记录患者的回应</string>
     <string name="notarize" tools:ignore="ResourceName">确认</string>
+    <string name="subjects_can_also_draw_pictures_on_paper" tools:ignore="ResourceName">注意:受试者也可在纸上画图</string>
+    <string name="erase" tools:ignore="ResourceName">擦除</string>
+    <string name="observation_10_sec" tools:ignore="ResourceName">显示观察10秒</string>
+    <string name="immediate_observation" tools:ignore="ResourceName">直接显示</string>
+    <string name="evaluation_artwork" tools:ignore="ResourceName">测评原图:</string>
+    <string name="drawing_by_the_patient" tools:ignore="ResourceName">患者所画图:</string>
 </resources>