Forráskód Böngészése

feat 绘制对象与管道

lihao1 3 éve
szülő
commit
d830332343
24 módosított fájl, 1001 hozzáadás és 30 törlés
  1. 3 0
      cadengine/src/main/java/cn/sagacloud/android/cadengine/FloorScene.kt
  2. 1 1
      cadengine/src/main/java/cn/sagacloud/android/cadengine/Opt.kt
  3. 2 0
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/EquipItem.kt
  4. 7 0
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/PipeLineItem.kt
  5. 79 9
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/TunableSpaceItem.kt
  6. BIN
      demo/libs/armeabi-v7a/libzbar.so
  7. BIN
      demo/libs/armeabi/liblocSDK8a.so
  8. BIN
      demo/libs/armeabi/libzbar.so
  9. 159 2
      demo/src/main/java/com/sybotan/android/demo/activities/GraphyActivity.kt
  10. 347 0
      demo/src/main/java/com/sybotan/android/demo/adapter/BaseRecyclerViewAdapter.java
  11. 53 0
      demo/src/main/java/com/sybotan/android/demo/adapter/PipeAdapter.java
  12. 17 0
      demo/src/main/java/com/sybotan/android/demo/bean/request/ReqAddPipe.kt
  13. 8 0
      demo/src/main/java/com/sybotan/android/demo/bean/request/ReqPipeList.java
  14. 10 0
      demo/src/main/java/com/sybotan/android/demo/bean/request/ReqSpacePipe.kt
  15. 8 0
      demo/src/main/java/com/sybotan/android/demo/bean/result/AddPipeModel.java
  16. 4 0
      demo/src/main/java/com/sybotan/android/demo/bean/result/Children.java
  17. 17 0
      demo/src/main/java/com/sybotan/android/demo/bean/result/ChildrenZ.java
  18. 15 0
      demo/src/main/java/com/sybotan/android/demo/bean/result/PipeListModel.java
  19. 16 0
      demo/src/main/java/com/sybotan/android/demo/bean/result/SpacePipeModel.kt
  20. 22 0
      demo/src/main/java/com/sybotan/android/demo/retrofit/API.java
  21. 4 4
      demo/src/main/java/com/sybotan/android/demo/tools/WordWrapView.java
  22. 65 3
      demo/src/main/java/com/sybotan/android/demo/viewmodel/GraphyVM.kt
  23. 144 11
      demo/src/main/res/layout/activity_graphy.xml
  24. 20 0
      demo/src/main/res/layout/item_pipe_type.xml

+ 3 - 0
cadengine/src/main/java/cn/sagacloud/android/cadengine/FloorScene.kt

@@ -31,6 +31,8 @@ open class FloorScene : SGraphyScene() {
     var item: QrcodeItem? = null
     var eqItem: EquipItem? = null
 
+    var pipeItem: PipeLineItem? = null
+
     /** 默认缩放比例,用于指定最小缩放比例*/
     var defaultPointScale = 0.01785718f
 
@@ -356,6 +358,7 @@ open class FloorScene : SGraphyScene() {
     open fun addDoor(door: Door) {
         val item = DoorItem(door)
         item.isVisible = isShowSpace
+        item.zOrder = 100001f
         doorList.add(item)
         addItem(item)
     } // Function addWindow()

+ 1 - 1
cadengine/src/main/java/cn/sagacloud/android/cadengine/Opt.kt

@@ -26,7 +26,7 @@ class Opt {
         /** 被选中的空间颜色 */
         val spaceChoseColor = Color.rgb(0xe6, 0xfa, 0xff)
         /** 门颜色 */
-        val doorColor = Color.rgb(0x97, 0x63, 0x17)
+        val doorColor = Color.rgb(0xcc, 0xcc, 0xcc)
         /** 窗户颜色 */
         val windowColor = Color.rgb(0xba, 0xe0, 0xfd)
         /** 文字颜色 */

+ 2 - 0
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/EquipItem.kt

@@ -4,9 +4,11 @@ package cn.sagacloud.android.cadengine.items
 import android.graphics.Canvas
 import android.graphics.Color
 import android.graphics.Paint
+import android.graphics.drawable.BitmapDrawable
 import cn.sagacloud.android.cadengine.types.Point
 import com.sybotan.android.graphy.SGraphyItem
 
+
 /**
  * Created by lihao.
  * Date: 2021/6/4

+ 7 - 0
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/PipeLineItem.kt

@@ -13,6 +13,7 @@ import com.sybotan.android.graphy.SGraphyItem
 class PipeLineItem(val data: PipeLine, parent: SGraphyItem? = null) : SGraphyItem(parent) {
     /** 画笔 */
     val paint = Paint()
+    val mPaint_inner = Paint()
 
     /** 管道轮廓 */
     private var pipePath: Path? = null
@@ -21,6 +22,7 @@ class PipeLineItem(val data: PipeLine, parent: SGraphyItem? = null) : SGraphyIte
     private val pointArr = ArrayList<ArrayList<PointF>>()
 
     val outPaint = Paint()
+
     var mPoints = ArrayList<PointF>()
 
     init {
@@ -54,6 +56,11 @@ class PipeLineItem(val data: PipeLine, parent: SGraphyItem? = null) : SGraphyIte
         outPaint.isAntiAlias = true
         outPaint.color = Color.rgb(0x44, 0x71, 0xa3)
         outPaint.strokeWidth = 100f
+
+        //内圈
+        mPaint_inner.color = Color.parseColor("#0c90eb")
+        mPaint_inner.isAntiAlias = true
+        mPaint_inner.style = Paint.Style.FILL
     } // Constructor
 
 

+ 79 - 9
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/TunableSpaceItem.kt

@@ -3,7 +3,6 @@ package cn.sagacloud.android.cadengine.items
 import android.graphics.*
 import android.text.TextPaint
 import cn.sagacloud.android.cadengine.Opt
-import cn.sagacloud.android.cadengine.types.Space
 import cn.sagacloud.android.cadengine.types.TunableSpace
 import com.sybotan.android.graphy.SGraphyItem
 
@@ -95,7 +94,7 @@ class TunableSpaceItem(val data: TunableSpace, parent: SGraphyItem? = null) : SG
         outPaint.style = Paint.Style.STROKE
         outPaint.color = Color.parseColor("#7E96FF")
         outPaint.setAntiAlias(true)
-        outPaint.strokeWidth = 100f
+        outPaint.strokeWidth = 50f
 
         centerPaint.style = Paint.Style.STROKE
         centerPaint.color = Color.parseColor("#7E96FF")
@@ -104,6 +103,75 @@ class TunableSpaceItem(val data: TunableSpace, parent: SGraphyItem? = null) : SG
 
     } // Constructor
 
+    /**
+     * 计算任意多边形的面积
+     * @param latLngLines 经纬度坐标点
+     * @return
+     */
+    fun calculateArea(latLngLines: List<PointF>): Float {
+        val pointFList: MutableList<DoubleArray> = ArrayList()
+        for (i in latLngLines.indices) {
+            val latLng: PointF = latLngLines[i]
+            //经纬度转换成平面直角坐标系
+            wGS2flat(latLng.x.toDouble(), latLng.y.toDouble())?.let { pointFList.add(it) }
+        }
+        var iCycle: Int
+        val iCount: Int
+        iCycle = 0
+        var iArea = 0.0
+        iCount = pointFList.size
+        iCycle = 0
+        while (iCycle < iCount) {
+            iArea = iArea + (pointFList[iCycle][0] * pointFList[(iCycle + 1) % iCount][1] - pointFList[(iCycle + 1) % iCount][0] * pointFList[iCycle][1])
+            iCycle++
+        }
+        return Math.abs(0.5 * iArea).toFloat()
+    }
+
+    // 地球长半轴
+    val EARTH_RADIUS = 6378.137
+
+    /**
+     * 经纬度转换成以米为单位的平面直角坐标
+     *
+     * @param lon 经度
+     * @param lat 纬度
+     * @return 平面直角坐标double型数组,以米为单位
+     */
+    fun wGS2flat(lon: Double, lat: Double): DoubleArray? {
+        val L = CalcRad(lon)
+        val l = L - CalcRad(120.0)
+        val B = CalcRad(lat)
+        val cosb = Math.cos(B)
+        val sinb = Math.sin(B)
+        val a = EARTH_RADIUS * 1000
+        // 地球短半轴
+        val b = 6356752.3142451793
+        val t = Math.tan(B)
+        // double r = 3600 * 180 / Math.PI;
+        val e2 = (Math.pow(a, 2.0) - Math.pow(b, 2.0)) / Math.pow(a, 2.0)
+        val e12 = (Math.pow(a, 2.0) - Math.pow(b, 2.0)) / Math.pow(b, 2.0)
+        val n2 = e12 * Math.pow(cosb, 2.0)
+        val N = a / Math.sqrt(1 - e2 * Math.pow(sinb, 2.0))
+        val x = 6367449.1458 * B - 32009.8185 * cosb * sinb - (133.9975
+                * cosb * Math.pow(sinb, 3.0)) - 0.6975 * cosb * Math.pow(sinb, 5.0)
+        val X = x + N / 2 * t * Math.pow(cosb, 2.0) * Math.pow(l, 2.0) + (N / 24 * t * Math.pow(cosb, 4.0)
+                * (5 - Math.pow(t, 2.0) + 9 * n2 + 4 * Math.pow(n2, 2.0))
+                * Math.pow(l, 4.0))
+        val Y = N * cosb * l + (N / 6 * Math.pow(cosb, 3.0)
+                * (1 - Math.pow(t, 2.0) + n2) * Math.pow(l, 3.0))
+        return doubleArrayOf(X, Y)
+    }
+
+    /**
+     * 计算弧度
+     *
+     * @param d 以度为单位的经纬度数值
+     * @return 以弧度为单位的经纬度数值
+     */
+    fun CalcRad(d: Double): Double {
+        return d * Math.PI / 180.0
+    }
 
     /**
      * Item对象边界区域
@@ -123,17 +191,19 @@ class TunableSpaceItem(val data: TunableSpace, parent: SGraphyItem? = null) : SG
      */
     override fun onDraw(canvas: Canvas) {
         if (null != spacePath) {
-            if (outPaint.color == Color.rgb(0xbd, 0xe8, 0xfe)) {
+            if (paint.color == Opt.spaceChoseColor) {
                 paint.color = Opt.spaceChoseColor
             } else {
-                if (data.jobStatus.equals("01")) {
-                    paint.color = Color.parseColor("#33ffff00")
-                } else if (data.jobStatus.equals("02")){
-                    paint.color = Color.parseColor("#33ff0000")
-                } else if (data.jobStatus.equals("03")){
-                    paint.color = Color.parseColor("#3300ff00")
+                if (data.jobStatus.equals("01") || data.jobStatus.equals("04")) {
+                    paint.color = Color.parseColor("#FFFF78")
+                } else if (data.jobStatus.equals("02")) {
+                    paint.color = Color.parseColor("#FF6B6B")
+                } else if (data.jobStatus.equals("03") || data.jobStatus.equals("05")) {
+                    paint.color = Color.parseColor("#99FF99")
                 }
             }
+            outPaint.color = Color.parseColor("#7E96FF")
+            canvas.drawPath(spacePath!!, outPaint)
             canvas.drawPath(spacePath!!, paint)
         }
         super.onDraw(canvas)

BIN
demo/libs/armeabi-v7a/libzbar.so


BIN
demo/libs/armeabi/liblocSDK8a.so


BIN
demo/libs/armeabi/libzbar.so


+ 159 - 2
demo/src/main/java/com/sybotan/android/demo/activities/GraphyActivity.kt

@@ -25,7 +25,10 @@ package com.sybotan.android.demo.activities
 
 import android.content.Intent
 import android.graphics.Color
+import android.graphics.PointF
 import android.os.Bundle
+import android.support.v7.widget.GridLayoutManager
+import android.support.v7.widget.LinearLayoutManager
 import android.util.Log
 import android.view.Gravity
 import android.view.View
@@ -34,13 +37,16 @@ import android.widget.Toast
 import cn.sagacloud.android.cadengine.FloorScene
 import cn.sagacloud.android.cadengine.Opt
 import cn.sagacloud.android.cadengine.items.*
+import cn.sagacloud.android.cadengine.types.PipeLine
 import cn.sagacloud.android.cadengine.types.Point
 import cn.sagacloud.android.cadengine.types.Space
 import cn.sagacloud.android.cadengine.types.TunableSpace
 import cn.sagacloud.cadengine.HttpDownloadMap
 import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
 import com.sybotan.android.demo.R
 import com.sybotan.android.demo.activities.poc.DeviceActivity
+import com.sybotan.android.demo.adapter.PipeAdapter
 import com.sybotan.android.demo.bean.result.*
 import com.sybotan.android.demo.retrofit.BaseViewModelInterface
 import com.sybotan.android.demo.tools.DensityUtils
@@ -90,6 +96,9 @@ class GraphyActivity : BaseActivity() {
     /** 缩放后的同比例距离 */
     var realDistance = 0f
 
+    /** 管道类型数据 */
+    lateinit var pipeTypeList: ArrayList<PipeListModel>
+
     val scene = FloorScene()
     val gson = Gson()
 
@@ -163,6 +172,9 @@ class GraphyActivity : BaseActivity() {
     private fun initSingleTopUp() {
         scene.setOnSingleTopUp(object : FloorScene.OnSingleTopUp {
             override fun onSingUp(x: Float, y: Float) {
+                if ("pipe".equals(scene.type)) {
+                    return
+                }
                 //选中空间完毕界面逻辑
                 if (scene.mapType.equals("space")) {
                     if ("space".equals(from)) {
@@ -178,6 +190,7 @@ class GraphyActivity : BaseActivity() {
                         if (equipLl.visibility == View.GONE) {
                             drawLl.visibility = View.VISIBLE
                             graphyVM.getSpaceEq(scene.choseSpace)
+                            graphyVM.spacePipe(scene.choseSpace)
                         }
                         equipLocation.setText("($x,$y)")
 
@@ -201,6 +214,10 @@ class GraphyActivity : BaseActivity() {
                     }
                     scene.equipList.clear()
                     scene.qrcodeItemList.clear()
+                    for (item in scene.pipeItemList) {
+                        scene.removeItem(item)
+                    }
+                    scene.pipeItemList.clear()
                 }
 
                 //打点业务
@@ -258,9 +275,25 @@ class GraphyActivity : BaseActivity() {
             }
         }
 
+        /** checkBox */
+        sceneCheckBox.setOnCheckedChangeListener { buttonView, isChecked ->
+            if (isChecked) {
+                sceneSubmit.isEnabled = true
+                sceneSubmit.alpha = 1f
+            } else {
+                sceneSubmit.isEnabled = false
+                sceneSubmit.alpha = 0.3f
+            }
+        }
+
+        /** 设置空间的任务状态完成 */
+        sceneSubmit.setOnClickListener {
+            graphyVM.setJob(scene.choseSpace, codeEdit.text.toString(), "05")
+        }
+
         /** 设置空间的任务状态完成 */
         modelSubmit.setOnClickListener {
-            graphyVM.setJob(scene.choseSpace, codeEdit.text.toString())
+            graphyVM.setJob(scene.choseSpace, codeEdit.text.toString(), "03")
         }
 
         /** 打点按钮 */
@@ -284,12 +317,35 @@ class GraphyActivity : BaseActivity() {
             scene.item?.let { it1 -> scene.removeItem(it1) }
         }
 
-        /** 下一步 */
+        /** 取消绘制管道 */
+        pipeCancel.setOnClickListener {
+            pipeLl.visibility = View.GONE
+            drawLl.visibility = View.VISIBLE
+            scene.type = "normal"
+            for (item in scene.pipeItemList) {
+                scene.removeItem(item)
+            }
+            scene.pipeLineList.clear()
+            scene.pipeItemList.clear()
+        }
+
+        /** 绑定二维码下一步 */
         qrcodeNext.setOnClickListener {
             val intent = Intent(this@GraphyActivity, CaptureActivity::class.java)
             startActivityForResult(intent, REQUEST_CODE_SCAN)
         }
 
+        /** 添加管线下一步 */
+        pipeNext.setOnClickListener {
+            for (model in pipeTypeList) {
+                if (model.isCheck) {
+                    graphyVM.addPipe(model, scene.pipeLineList, pipeEdit.text.toString(), scene.choseSpace)
+                    break
+                }
+            }
+        }
+
+
         /** 添加设备 */
         drawEquip.setOnClickListener {
             scene.type = "equip"
@@ -298,10 +354,21 @@ class GraphyActivity : BaseActivity() {
 
         }
 
+        /** 添加管线 */
+        drawPipe.setOnClickListener {
+            scene.type = "pipe"
+            drawLl.visibility = View.GONE
+            pipeLl.visibility = View.VISIBLE
+//            piprRv.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
+            piprRv.layoutManager = GridLayoutManager(this, 3, LinearLayoutManager.HORIZONTAL, false)
+            graphyVM.pipeList()
+        }
+
         /** 取消添加设备 */
         equipCancel.setOnClickListener {
             drawLl.visibility = View.VISIBLE
             equipLl.visibility = View.GONE
+            scene.eqItem?.let { it1 -> scene.removeItem(it1) }
             scene.type = "normal"
         }
 
@@ -498,12 +565,97 @@ class GraphyActivity : BaseActivity() {
                     }
                     refreshEquip(list)
                 }
+
+                /** 查询管道类型树 */
+                GraphyVM.PIPE_LIST -> {
+                    pipeTypeList = params as ArrayList<PipeListModel>
+                    val adapter = PipeAdapter(this, pipeTypeList)
+                    piprRv.adapter = adapter
+                }
+
+                /** 添加管线 */
+                GraphyVM.ADD_PIPE -> {
+                    pipeLl.visibility = View.GONE
+                    drawLl.visibility = View.VISIBLE
+                    scene.type = "normal"
+                    for (item in scene.pipeItemList) {
+                        scene.removeItem(item)
+                    }
+                    scene.pipeLineList.clear()
+                    scene.pipeItemList.clear()
+
+                    graphyVM.spacePipe(scene.choseSpace)
+                }
+
+                /** 查询空间下的管道 */
+                GraphyVM.SPACE_PIPE -> {
+                    val spacePipeModel = params as ArrayList<SpacePipeModel>
+
+                    //流式布局
+                    pipeWwv.removeAllViews()
+                    for (model in spacePipeModel) {
+                        val textview = TextView(this)
+                        textview.setText(model.typeName + "(${model.children.size})")
+                        textview.setSingleLine()
+                        textview.gravity = Gravity.CENTER
+                        textview.textSize = 12f
+                        textview.height = DensityUtils.dp2px(this, 30f)
+                        if (model.isCheck) {
+                            textview.background = resources.getDrawable(R.drawable.shape_filter_normal)
+                            textview.textColor = resources.getColor(R.color.grey_900)
+                        } else {
+                            textview.background = resources.getDrawable(R.drawable.shape_filter_selected)
+                            textview.textColor = resources.getColor(R.color.white)
+                        }
+                        textview.setOnClickListener {
+                            model.isCheck = !model.isCheck
+                            if (model.isCheck) {
+                                textview.background = resources.getDrawable(R.drawable.shape_filter_normal)
+                                textview.textColor = resources.getColor(R.color.grey_900)
+                            } else {
+                                textview.background = resources.getDrawable(R.drawable.shape_filter_selected)
+                                textview.textColor = resources.getColor(R.color.white)
+                            }
+                            refreshPipe(spacePipeModel)
+                        }
+                        pipeWwv.addView(textview)
+
+                    }
+                    refreshPipe(spacePipeModel)
+                }
             }
         }, this, buildingId, floorId)
         graphyVM.getSpaceJob(from)
     }
 
     /**
+     * 刷新地图上管线
+     */
+    private fun refreshPipe(spacePipeModel: ArrayList<SpacePipeModel>) {
+        for (item in scene.pipeItemList) {
+            scene.removeItem(item)
+        }
+        scene.pipeItemList.clear()
+
+        for (model in spacePipeModel) {
+            if (!model.children.isEmpty() && !model.isCheck) {
+                for (child in model.children) {
+                    val pipe = PipeLine()
+                    var points: ArrayList<ArrayList<PointF>> = ArrayList()
+                    points.add(child.position)
+                    pipe.points!!.addAll(points)
+                    val pipeItem = PipeLineItem(pipe, null)
+                    pipeItem.isVisible = true
+                    pipeItem.zOrder = 100000f
+                    scene.pipeItemList.add(pipeItem)
+                    scene.addItem(pipeItem)
+
+                }
+            }
+        }
+    }
+
+    /**
      * 刷新地图上设备
      */
     private fun refreshEquip(list: List<SpaceEqModel>) {
@@ -626,11 +778,16 @@ class GraphyActivity : BaseActivity() {
             REQUEST_CODE_EQUIP -> {
                 if (resultCode == RESULT_OK) {
                     equipLocation.setText("")
+                    equipEdit.setText("")
+                    scene.eqItem?.let { it1 -> scene.removeItem(it1) }
                     roof.isChecked = false
                     floor.isChecked = false
                     wall.isChecked = false
                     air.isChecked = false
                     scene.point = Point()
+                    scene.type = "normal"
+                    equipLl.visibility = View.GONE
+                    drawLl.visibility = View.VISIBLE
                     graphyVM.getSpaceEq(scene.choseSpace)
                 }
             }

+ 347 - 0
demo/src/main/java/com/sybotan/android/demo/adapter/BaseRecyclerViewAdapter.java

@@ -0,0 +1,347 @@
+package com.sybotan.android.demo.adapter;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.text.TextUtils;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.TextView;
+
+
+import java.util.List;
+
+/**
+ * function="基于Recycleview的万能适配器"
+ * Created by wangmaobo on 2018/4/3.
+ */
+public abstract class BaseRecyclerViewAdapter<T>
+        extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+    protected List<T> mBeans;
+    protected Context mContext;
+    private int mLastAnimatedPosition = -1;
+    public OnItemClickListener mOnItemClickListener;
+    protected LayoutInflater inflater;
+    /*
+     * 是否开启item动画
+     */
+    private boolean mAnimateItems = false;
+    private int viewType;
+    private boolean mIsFirst = true;
+    public ViewGroup parent;
+
+    public BaseRecyclerViewAdapter(Context context, List<T> beans) {
+        mContext = context;
+        mBeans = beans;
+    }
+
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        this.viewType = viewType;
+        this.parent = parent;
+        inflater = LayoutInflater.from(mContext);
+        View view = inflater.inflate(getItemLayoutId(viewType), parent, false);
+        ViewHolder viewHolder = new ViewHolder(view);
+        return viewHolder;
+    }
+
+    @Override
+    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+        itemAnimation(holder.itemView, position);
+        ViewHolder viewHolder = (ViewHolder) holder;
+        onBindDataToView(viewHolder, mBeans.get(position));
+    }
+
+    @Override
+    public int getItemCount() {
+        return mBeans == null ? 0 : mBeans.size();
+    }
+
+    public void add(T bean) {
+        mBeans.add(bean);
+        notifyDataSetChanged();
+    }
+
+    public void addAll(List<T> beans) {
+        mBeans.addAll(beans);
+        notifyDataSetChanged();
+    }
+
+    public void clear() {
+        mBeans.clear();
+        notifyDataSetChanged();
+    }
+
+    /**
+     * item动画
+     */
+    private void itemAnimation(View itemView, int position) {
+        if (!mAnimateItems) return;
+        if (position > mLastAnimatedPosition) {
+            mLastAnimatedPosition = position;
+            itemView.setTranslationY(getScreenHeight());
+            itemView.setRotation(360);
+            itemView.animate()
+                    .translationY(0)
+                    .rotation(0)
+                    .setStartDelay(1000 * position)
+                    .setInterpolator(new DecelerateInterpolator(3.f))
+                    .setDuration(800)
+                    .start();
+        }
+    }
+
+    private int getScreenHeight() {
+        return mContext.getResources().getDisplayMetrics().heightPixels;
+    }
+
+    public class ViewHolder extends RecyclerView.ViewHolder {
+        private final SparseArray<View> mViews;
+        private View itemView;
+
+        public ViewHolder(View itemView) {
+            super(itemView);
+            mViews = new SparseArray<>();
+            this.itemView = itemView;
+            this.itemView.setOnClickListener(v -> {
+                onItemClick(getAdapterPosition());
+                if (mOnItemClickListener != null)
+                    setOnItemClick(v, getAdapterPosition());
+            });
+            setTextChangedListener(this, itemView);
+            setRatingBarListener(this, itemView);
+        }
+
+        public <T extends View> T getView(int viewId) {
+            View view = mViews.get(viewId);
+            if (view == null) {
+                view = itemView.findViewById(viewId);
+                mViews.put(viewId, view);
+            }
+            return (T) view;
+        }
+
+        public ViewHolder setText(int viewId, String text) {
+            if (TextUtils.isEmpty(text)) {
+                text = "";
+            }
+            TextView tv = getView(viewId);
+            tv.setText(text);
+            return this;
+        }
+
+        public ViewHolder setHint(int viewId, String text) {
+            TextView tv = getView(viewId);
+            tv.setHint(text);
+            return this;
+        }
+
+        public ViewHolder setAlpha(int viewId, float alpha) {
+            View view = getView(viewId);
+            view.setAlpha(alpha);
+            return this;
+        }
+
+        /**
+         * 如果text为空,显示“--”
+         *
+         * @param viewId
+         * @param text
+         * @return
+         */
+        public ViewHolder setTextNotNull(int viewId, String text) {
+            if (TextUtils.isEmpty(text)) {
+                text = "--";
+            }
+            TextView tv = getView(viewId);
+            tv.setText(text);
+
+            return this;
+        }
+
+        public ViewHolder setTextHint(int viewId, String hint) {
+            if (TextUtils.isEmpty(hint)) {
+                return this;
+            }
+            TextView tv = getView(viewId);
+            tv.setHint(hint);
+            return this;
+        }
+
+        public ViewHolder setRightIconGone(int viewId, boolean isGone) {
+            if (isGone) {
+                getView(viewId).getLayoutParams().width = 0;
+            } else {
+                getView(viewId).getLayoutParams().width = 16;
+            }
+            return this;
+        }
+
+        public ViewHolder setEditEnable(int viewId, boolean isEnable) {
+            if (isEnable) {
+                getView(viewId).setEnabled(isEnable);
+            } else {
+                getView(viewId).setEnabled(isEnable);
+            }
+            return this;
+        }
+
+        public ViewHolder setBackground(int viewId, int drawableId) {
+            View view = getView(viewId);
+            view.setBackground(mContext.getResources().getDrawable(drawableId));
+            return this;
+        }
+
+        /**
+         * 如果text为空,控件隐藏
+         *
+         * @param viewId
+         * @param text
+         * @return
+         */
+        public ViewHolder setTextAndView(int viewId, String text) {
+            TextView tv = getView(viewId);
+            if (TextUtils.isEmpty(text)) {
+                tv.setVisibility(View.GONE);
+            } else {
+                tv.setText(text);
+                tv.setVisibility(View.VISIBLE);
+            }
+            return this;
+        }
+
+        public ViewHolder setProjectName(int viewId, String text) {
+            TextView tv = getView(viewId);
+            return this;
+        }
+
+        public ViewHolder setTextColor(int viewId, int textColorId) {
+            TextView tv = getView(viewId);
+            tv.setTextColor(textColorId);
+            return this;
+        }
+
+
+        public ViewHolder setClickListener(int viewId) {
+            View v = getView(viewId);
+            v.setOnClickListener(v1 -> onSingleViewClick(v1, getAdapterPosition()));
+            return this;
+        }
+
+        public ViewHolder cancelClickListener(int viewId) {
+            View v = getView(viewId);
+            v.setOnClickListener(null);
+            return this;
+        }
+
+        public ViewHolder setVisible(int viewId) {
+            View v = getView(viewId);
+            v.setVisibility(View.VISIBLE);
+            return this;
+        }
+
+        public ViewHolder setInVisible(int viewId) {
+            View v = getView(viewId);
+            v.setVisibility(View.GONE);
+            return this;
+        }
+
+        public ViewHolder setInVisibleTwo(int viewId) {
+            View v = getView(viewId);
+            v.setVisibility(View.INVISIBLE);
+            return this;
+        }
+
+        public int getCurrentPosition() {
+            return getAdapterPosition();
+        }
+
+    }
+
+    /**
+     * 绑定布局id
+     *
+     * @param viewType
+     * @return
+     */
+    protected abstract int getItemLayoutId(int viewType);
+
+    /**
+     * 绑定数据
+     *
+     * @param holder
+     * @param t
+     */
+    protected abstract void onBindDataToView(ViewHolder holder, T t);
+
+    /**
+     * 支持多种ItemType
+     *
+     * @param position
+     * @return
+     */
+    @Override
+    public abstract int getItemViewType(int position);
+
+    /**
+     * ItemView里的某个子控件的单击事件(如果需要,重写此方法就行)
+     * 只有在{@link #onBindDataToView}注册了{@link ViewHolder#setClickListener}才有效果
+     *
+     * @param position
+     */
+    protected void onSingleViewClick(View view, int position) {
+
+    }
+
+    /**
+     * ItemView的单击事件(如果需要,重写此方法就行)
+     *
+     * @param position
+     */
+    protected void onItemClick(int position) {
+
+    }
+
+    /**
+     * 为edittext添加文本监听(如果需要,重写此方法就行)
+     *
+     * @param holder
+     * @param itemView
+     */
+    protected void setTextChangedListener(ViewHolder holder, View itemView) {
+
+    }
+
+    protected void setRatingBarListener(ViewHolder holder, View itemView) {
+
+    }
+
+    /**
+     * 为Adapter添加item点击方法
+     */
+    public BaseRecyclerViewAdapter setOnItemClickListener(OnItemClickListener listener) {
+        mOnItemClickListener = listener;
+        return this;
+    }
+
+    public interface OnItemClickListener {
+        void onItemClick(BaseRecyclerViewAdapter adapter, View view, int position);
+    }
+
+    private void setOnItemClick(View v, int position) {
+        mOnItemClickListener.onItemClick(BaseRecyclerViewAdapter.this, v, position);
+    }
+
+    public View.OnTouchListener onTouchListener = (v, event) -> {
+        if (MotionEvent.ACTION_DOWN == event.getAction()) {
+            v.getParent().requestDisallowInterceptTouchEvent(true);
+        } else if (MotionEvent.ACTION_UP == event.getAction()) {
+            v.getParent().requestDisallowInterceptTouchEvent(false);
+        }
+        return false;
+    };
+
+}

+ 53 - 0
demo/src/main/java/com/sybotan/android/demo/adapter/PipeAdapter.java

@@ -0,0 +1,53 @@
+package com.sybotan.android.demo.adapter;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+
+import com.sybotan.android.demo.R;
+import com.sybotan.android.demo.bean.result.PipeListModel;
+
+import java.util.List;
+
+/**
+ * Created by lihao.
+ * Date: 6/15/21
+ */
+public class PipeAdapter extends BaseRecyclerViewAdapter<PipeListModel> {
+    public PipeAdapter(Context context, List<PipeListModel> beans) {
+        super(context, beans);
+    }
+
+    @Override
+    protected int getItemLayoutId(int viewType) {
+        return R.layout.item_pipe_type;
+    }
+
+    @Override
+    protected void onBindDataToView(ViewHolder holder, PipeListModel model) {
+        TextView pipe = holder.getView(R.id.pipe);
+        holder.setText(R.id.pipe, model.sysName + "-" + model.name);
+        holder.getView(R.id.pipe).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                for (int i = 0; i < mBeans.size(); i++) {
+                    mBeans.get(i).isCheck = false;
+                }
+                model.isCheck = true;
+                notifyDataSetChanged();
+            }
+        });
+        if (model.isCheck) {
+            pipe.setBackgroundResource(R.drawable.shape_filter_selected);
+            pipe.setTextColor(mContext.getResources().getColor(R.color.white));
+        } else {
+            pipe.setBackgroundResource(R.drawable.shape_filter_normal);
+            pipe.setTextColor(mContext.getResources().getColor(R.color.grey_900));
+        }
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return 0;
+    }
+}

+ 17 - 0
demo/src/main/java/com/sybotan/android/demo/bean/request/ReqAddPipe.kt

@@ -0,0 +1,17 @@
+package com.sybotan.android.demo.bean.request
+
+import android.graphics.PointF
+
+/**
+ * Created by lihao.
+ * Date: 6/15/21
+ */
+class ReqAddPipe {
+    var spaceId: String? = null
+    var sys: String? = null
+    var type: String? = null
+    var position: ArrayList<PointF> = ArrayList()
+    var remark: String? = null
+    var name: String? = null
+    var target: String? = "action"
+}

+ 8 - 0
demo/src/main/java/com/sybotan/android/demo/bean/request/ReqPipeList.java

@@ -0,0 +1,8 @@
+package com.sybotan.android.demo.bean.request;
+
+/**
+ * Created by lihao.
+ * Date: 6/15/21
+ */
+public class ReqPipeList {
+}

+ 10 - 0
demo/src/main/java/com/sybotan/android/demo/bean/request/ReqSpacePipe.kt

@@ -0,0 +1,10 @@
+package com.sybotan.android.demo.bean.request
+
+/**
+ * Created by lihao.
+ * Date: 6/15/21
+ */
+class ReqSpacePipe {
+    var spaceId: String? = null
+    var group: Boolean? = true
+}

+ 8 - 0
demo/src/main/java/com/sybotan/android/demo/bean/result/AddPipeModel.java

@@ -0,0 +1,8 @@
+package com.sybotan.android.demo.bean.result;
+
+/**
+ * Created by lihao.
+ * Date: 6/15/21
+ */
+public class AddPipeModel {
+}

+ 4 - 0
demo/src/main/java/com/sybotan/android/demo/bean/result/Children.java

@@ -1,5 +1,9 @@
 package com.sybotan.android.demo.bean.result;
 
+import android.graphics.PointF;
+
+import java.util.ArrayList;
+
 /**
  * Created by lihao.
  * Date: 6/11/21

+ 17 - 0
demo/src/main/java/com/sybotan/android/demo/bean/result/ChildrenZ.java

@@ -0,0 +1,17 @@
+package com.sybotan.android.demo.bean.result;
+
+import android.graphics.PointF;
+
+import java.util.ArrayList;
+
+/**
+ * Created by lihao.
+ * Date: 6/11/21
+ */
+public class ChildrenZ {
+    public String pipeId;
+    public String deviceId;
+    public String name;
+    public ArrayList<PointF> position = new ArrayList<>();
+    public String remark;
+}

+ 15 - 0
demo/src/main/java/com/sybotan/android/demo/bean/result/PipeListModel.java

@@ -0,0 +1,15 @@
+package com.sybotan.android.demo.bean.result;
+
+/**
+ * Created by lihao.
+ * Date: 6/15/21
+ */
+public class PipeListModel {
+    public String sysCode;
+    public String sysName;
+    public String name;
+    public String code;
+
+
+    public boolean isCheck = false;
+}

+ 16 - 0
demo/src/main/java/com/sybotan/android/demo/bean/result/SpacePipeModel.kt

@@ -0,0 +1,16 @@
+package com.sybotan.android.demo.bean.result
+
+import java.util.*
+
+/**
+ * 查询空间下的管道
+ * Created by lihao.
+ * Date: 6/15/21
+ */
+class SpacePipeModel {
+    var type: String? = null
+    var typeName: String? = null
+    var children = ArrayList<ChildrenZ>()
+
+    var isCheck: Boolean = false
+}

+ 22 - 0
demo/src/main/java/com/sybotan/android/demo/retrofit/API.java

@@ -2,8 +2,11 @@ package com.sybotan.android.demo.retrofit;
 
 
 import com.sybotan.android.demo.bean.BaseModel;
+import com.sybotan.android.demo.bean.result.AddPipeModel;
+import com.sybotan.android.demo.bean.result.PipeListModel;
 import com.sybotan.android.demo.bean.result.SpaceEqModel;
 import com.sybotan.android.demo.bean.result.ResDeviceModel;
+import com.sybotan.android.demo.bean.result.SpacePipeModel;
 import com.sybotan.android.demo.entitiies.Build;
 import com.sybotan.android.demo.bean.result.AddProblemModel;
 import com.sybotan.android.demo.bean.result.BindQrcodeModel;
@@ -166,4 +169,23 @@ public interface API {
      */
     @POST("clmt/job/add_eq")
     Observable<BaseModel<ResDeviceModel>> addDeviceJob(@Body RequestBody body);
+
+    /**
+     * 添加管线
+     */
+    @POST("clmt/job/add_pipe")
+    Observable<BaseModel<AddPipeModel>> addPipe(@Body RequestBody body);
+
+    /**
+     * 查询空间下的管道
+     */
+    @POST("clmt/query/space_pipe")
+    Observable<BaseModel<ArrayList<SpacePipeModel>>> spacePipe(@Body RequestBody body);
+
+    /**
+     * 查询管道类型
+     */
+    @POST("clmt/dict/pipe_list")
+    Observable<BaseModel<ArrayList<PipeListModel>>> pipeList(@Body RequestBody body);
+
 }

+ 4 - 4
demo/src/main/java/com/sybotan/android/demo/tools/WordWrapView.java

@@ -12,10 +12,10 @@ import com.sybotan.android.demo.R;
  * Created by cunwen on 17/4/14.
  */
 public class WordWrapView extends ViewGroup {
-    private int PADDING_HOR = 15;//水平方向padding
-    private int PADDING_VERTICAL = 10;//垂直方向padding--文字上下距离边框的距离
-    private int SIDE_MARGIN = 40;//左右间距--整体的左右margin
-    private int TEXT_MARGIN = 10;//textview之间的间距
+    private int PADDING_HOR = 7;//水平方向padding
+    private int PADDING_VERTICAL = 5;//垂直方向padding--文字上下距离边框的距离
+    private int SIDE_MARGIN = 20;//左右间距--整体的左右margin
+    private int TEXT_MARGIN = 6;//textview之间的间距
     private boolean mIsAudit;
 
     /**

+ 65 - 3
demo/src/main/java/com/sybotan/android/demo/viewmodel/GraphyVM.kt

@@ -1,5 +1,6 @@
 package com.sybotan.android.demo.viewmodel
 
+import android.graphics.PointF
 import cn.sagacloud.android.cadengine.items.PointItem
 import cn.sagacloud.android.cadengine.items.TunableSpaceItem
 import cn.sagacloud.android.cadengine.types.Point
@@ -11,7 +12,7 @@ import com.sybotan.android.demo.bean.result.Z
 import com.sybotan.android.demo.retrofit.BaseObserver
 import com.sybotan.android.demo.retrofit.BaseViewModelInterface
 import com.sybotan.android.demo.retrofit.RetrofitFactory
-import java.util.*
+import kotlin.collections.ArrayList
 
 /**
  * Created by lihao.
@@ -151,12 +152,12 @@ class GraphyVM(b: BaseViewModelInterface?, activity: BaseActivity?, //建筑id
      * @param choseSpace 选中的空间
      * @param toString   数字化交付编码
      */
-    fun setJob(choseSpace: TunableSpaceItem?, toString: String) {
+    fun setJob(choseSpace: TunableSpaceItem?, toString: String, jobStatus: String) {
         val bean = ReqSetJob()
         bean.buildingId = buildingId
         bean.floorId = floorId
         bean.spaceId.add(choseSpace!!.data.id)
-        bean.jobStatus = "03"
+        bean.jobStatus = jobStatus
         bean.spaceCode = toString
         val observable = RetrofitFactory.getInstance().setJob(getRequestBody(bean))
         sendRequest(observable, object : BaseObserver<SetJobModel>(mActivity, this) {
@@ -183,6 +184,58 @@ class GraphyVM(b: BaseViewModelInterface?, activity: BaseActivity?, //建筑id
         }, true)
     }
 
+    /**
+     * 获取管线类型
+     */
+    fun pipeList() {
+        val bean = ReqPipeList()
+        val observable = RetrofitFactory.getInstance().pipeList(getRequestBody(bean))
+        sendRequest(observable, object : BaseObserver<ArrayList<PipeListModel>>(mActivity, this) {
+            override fun onSuccess(models: ArrayList<PipeListModel>) {
+                mEmitter.SendDircetive(PIPE_LIST, models)
+            }
+        }, true)
+    }
+
+    /**
+     * 添加管线
+     * @param model         管线类型
+     * @param pipeLineList  位置坐标
+     * @param remark        描述
+     * @param choseSpace    被选中的空间
+     */
+    fun addPipe(model: PipeListModel, pipeLineList: java.util.ArrayList<PointF>, remark: String, choseSpace: TunableSpaceItem?) {
+        val bean = ReqAddPipe()
+        bean.spaceId = choseSpace!!.data.id
+        bean.sys = model.sysCode
+        bean.type = model.code
+        bean.position = pipeLineList
+        bean.remark = remark
+        bean.name = model.name
+        val observable = RetrofitFactory.getInstance().addPipe(getRequestBody(bean))
+        sendRequest(observable, object : BaseObserver<AddPipeModel>(mActivity, this) {
+            override fun onSuccess(models: AddPipeModel) {
+                mEmitter.SendDircetive(ADD_PIPE, null)
+            }
+        }, true)
+    }
+
+    /**
+     * 查询空间下的管道
+     * @param choseSpace    被选中的空间
+     */
+    fun spacePipe(choseSpace: TunableSpaceItem?) {
+        val bean = ReqSpacePipe()
+        bean.spaceId = choseSpace!!.data.id
+        bean.group = true
+        val observable = RetrofitFactory.getInstance().spacePipe(getRequestBody(bean))
+        sendRequest(observable, object : BaseObserver<java.util.ArrayList<SpacePipeModel>>(mActivity, this) {
+            override fun onSuccess(models: java.util.ArrayList<SpacePipeModel>) {
+                mEmitter.SendDircetive(SPACE_PIPE, models)
+            }
+        }, true)
+    }
+
     companion object {
         //查询空间和任务
         const val SPACE_JOB = "SPACE_JOB"
@@ -210,6 +263,15 @@ class GraphyVM(b: BaseViewModelInterface?, activity: BaseActivity?, //建筑id
 
         //设置空间的任务状态(新建和修改)
         const val SPACE_EQ = "SPACE_EQ"
+
+        //查询管道类型树
+        const val PIPE_LIST = "PIPE_LIST"
+
+        //添加管线
+        const val ADD_PIPE = "ADD_PIPE"
+
+        //查询空间下的管道
+        const val SPACE_PIPE = "SPACE_PIPE"
     }
 
 }

+ 144 - 11
demo/src/main/res/layout/activity_graphy.xml

@@ -286,14 +286,21 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical"
+            android:paddingBottom="20dp"
             android:visibility="gone">
 
-            <com.sybotan.android.demo.tools.WordWrapView
-                android:id="@+id/equipWwv"
+            <ScrollView
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="50dp"
-                android:layout_marginRight="50dp" />
+                android:layout_height="100dp"
+                android:scrollbars="none">
+
+                <com.sybotan.android.demo.tools.WordWrapView
+                    android:id="@+id/equipWwv"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="20dp"
+                    android:layout_marginRight="20dp" />
+            </ScrollView>
 
             <TextView
                 android:id="@+id/drawEquip"
@@ -310,15 +317,22 @@
                 android:textColor="@color/white"
                 android:textSize="15sp" />
 
-            <com.sybotan.android.demo.tools.WordWrapView
-                android:id="@+id/pipeWwv"
+            <ScrollView
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="50dp"
-                android:layout_marginTop="5dp"
-                android:layout_marginRight="50dp" />
+                android:layout_height="100dp"
+                android:scrollbars="none">
+
+                <com.sybotan.android.demo.tools.WordWrapView
+                    android:id="@+id/pipeWwv"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="20dp"
+                    android:layout_marginTop="5dp"
+                    android:layout_marginRight="20dp" />
+            </ScrollView>
 
             <TextView
+                android:id="@+id/drawPipe"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_horizontal"
@@ -331,6 +345,32 @@
                 android:text="绘制管道桥架"
                 android:textColor="@color/white"
                 android:textSize="15sp" />
+
+            <CheckBox
+                android:id="@+id/sceneCheckBox"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="22dp"
+                android:text="此空间勘测完毕,模型和现场无区别" />
+
+
+            <TextView
+                android:id="@+id/sceneSubmit"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="12dp"
+                android:alpha="0.3"
+                android:background="@drawable/bg_blue_3bacb2"
+                android:enabled="false"
+                android:paddingLeft="100dp"
+                android:paddingTop="10dp"
+                android:paddingRight="100dp"
+                android:paddingBottom="10dp"
+                android:text="核查完成"
+                android:textColor="@color/white"
+                android:textSize="15sp" />
         </LinearLayout>
 
         <LinearLayout
@@ -457,5 +497,98 @@
                 android:textSize="15sp" />
         </LinearLayout>
 
+        <LinearLayout
+            android:id="@+id/pipeLl"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:paddingBottom="5dp"
+            android:visibility="gone">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="5dp"
+                android:text="1、在平面图上绘制管道"
+                android:textColor="@color/grey_900"
+                android:textSize="15sp" />
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="8dp"
+                android:text="2、确定管道类型"
+                android:textColor="@color/grey_900"
+                android:textSize="16sp" />
+
+            <android.support.v7.widget.RecyclerView
+                android:id="@+id/piprRv"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="8dp"
+                android:text="3、记录辅助信息"
+                android:textColor="@color/grey_900"
+                android:textSize="16sp" />
+
+            <EditText
+                android:id="@+id/pipeEdit"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginLeft="65dp"
+                android:layout_marginTop="8dp"
+                android:layout_marginRight="65dp"
+                android:hint="请输入辅助信息"
+                android:textColorHint="@color/grey_500"
+                android:textSize="16sp" />
+
+            <TextView
+                android:id="@+id/pipeNext"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@+id/quesTv"
+                android:layout_centerHorizontal="true"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginLeft="50dp"
+                android:layout_marginTop="12dp"
+                android:layout_marginRight="50dp"
+                android:background="@drawable/bg_blue_3bacb2"
+                android:gravity="center"
+                android:paddingLeft="15dp"
+                android:paddingTop="10dp"
+                android:paddingRight="15dp"
+                android:paddingBottom="10dp"
+                android:text="下一步"
+                android:textColor="@color/white"
+                android:textSize="15sp" />
+
+            <TextView
+                android:id="@+id/pipeCancel"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@+id/quesTv"
+                android:layout_centerHorizontal="true"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginLeft="50dp"
+                android:layout_marginTop="12dp"
+                android:layout_marginRight="50dp"
+                android:background="@drawable/bg_grey_e6e6e6"
+                android:gravity="center"
+                android:paddingLeft="15dp"
+                android:paddingTop="10dp"
+                android:paddingRight="15dp"
+                android:paddingBottom="10dp"
+                android:text="取消"
+                android:textColor="@color/grey_900"
+                android:textSize="15sp" />
+        </LinearLayout>
+
     </RelativeLayout>
 </LinearLayout>

+ 20 - 0
demo/src/main/res/layout/item_pipe_type.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_marginLeft="5dp"
+    android:layout_marginTop="5dp"
+    android:layout_marginRight="5dp">
+
+    <TextView
+        android:id="@+id/pipe"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@drawable/shape_filter_normal"
+        android:paddingLeft="5dp"
+        android:paddingTop="2dp"
+        android:paddingRight="5dp"
+        android:paddingBottom="2dp"
+        android:text="加速度"
+        android:textColor="@color/grey_900" />
+</RelativeLayout>