ArcGIS Engine 10.0 for.NET开发学习笔记(九)
来源:互联网 发布:java怎么解析cad图纸 编辑:程序博客网 时间:2024/05/24 01:11
【地图基本操作】
一、地图导出地图导出是将地图保存为图片,方便快速查看浏览。地图导出分为全域导出和区域导出两种。
导出窗体(FormExportMap)设计如下图所示,其中输出宽度与输出高度不允许进行编辑。
private string pSavePath = ""; private IActiveView pActiveView; private IGeometry pGeometry = null; /// <summary> /// 只读属性,地图导出空间图形 /// </summary> public IGeometry GetGeometry { set { pGeometry = value; } } private bool bRegion = true; /// <summary> /// 只读属性,是全域导出还是自由区域导出 /// </summary> public bool IsRegion { set { bRegion = value; } } public FormExportMap(AxMapControl mainAxMapControl) { InitializeComponent(); pActiveView = mainAxMapControl.ActiveView; }
在窗口进行初始化时,首先读取当前数据视图的分辨率,并添加到cboResolution中。代码如下:
private void FormExportMap_Load(object sender, EventArgs e) { InitFormSize(); } private void InitFormSize() { cboResolution.Text = pActiveView.ScreenDisplay.DisplayTransformation.Resolution.ToString(); cboResolution.Items.Add(cboResolution.Text); //...... }
当数据视图的分辨率改变时,输出图片像素的宽度和高度也会相应改变,计算公式为:输出图片的宽(高)=当前视图的宽(高)*输出图片的分辨率/当前数据视图显示的分辨率。
核心代码如下:
private void cboResolution_SelectedIndexChanged(object sender, EventArgs e) { double num = (int)Math.Round(pActiveView.ScreenDisplay.DisplayTransformation.Resolution); if (cboResolution.Text == "") { txtWidth.Text = ""; txtHeight.Text = ""; return; } if (bRegion) { IEnvelope pEnvelope = pGeometry.Envelope; tagRECT pRECT = new tagRECT(); pActiveView.ScreenDisplay.DisplayTransformation.TransformRect(pEnvelope, ref pRECT, 9); if (cboResolution.Text != "") { txtWidth.Text = Math.Round((double)(pRECT.right * (double.Parse(cboResolution.Text) / (double)num))).ToString(); txtHeight.Text = Math.Round((double)(pRECT.bottom * (double.Parse(cboResolution.Text) / (double)num))).ToString(); } } else { txtWidth.Text = Math.Round((double)(pActiveView.ExportFrame.right * (double.Parse(cboResolution.Text) / (double)num))).ToString(); txtHeight.Text = Math.Round((double)(pActiveView.ExportFrame.bottom * (double.Parse(cboResolution.Text) / (double)num))).ToString(); } }
在地图进行导出时根据bRegion进行判断是全域导出还是区域导出,核心代码如下:
private void InitFormSize() { cboResolution.Text = pActiveView.ScreenDisplay.DisplayTransformation.Resolution.ToString(); cboResolution.Items.Add(cboResolution.Text); if (bRegion) { IEnvelope pEnvelope = pGeometry.Envelope; tagRECT pRECT = new tagRECT(); pActiveView.ScreenDisplay.DisplayTransformation.TransformRect(pEnvelope, ref pRECT, 9); if (cboResolution.Text != "") { txtWidth.Text = pRECT.right.ToString(); txtHeight.Text = pRECT.bottom.ToString(); } } else { if (cboResolution.Text != "") { txtWidth.Text = pActiveView.ExportFrame.right.ToString(); txtHeight.Text = pActiveView.ExportFrame.bottom.ToString(); } } }
全域导出和区域导出功能很类似,封装成ExportMap类,功能包括图片导出、视图窗口绘制几何图形元素、创建图形元素、获取RGB颜色等。类的核心代码如下:
class ExportMap { public static void ExportView(IActiveView view, IGeometry pGeo, int OutputResolution,int Width, int Height, string ExpPath, bool bRegion) { IExport pExport = null; tagRECT exportRect = new tagRECT(); IEnvelope pEnvelope = pGeo.Envelope; string sType = System.IO.Path.GetExtension(ExpPath); switch (sType) { case ".jpg": pExport = new ExportJPEGClass(); break; case ".bmp": pExport = new ExportBMPClass(); break; case ".gif": pExport = new ExportGIFClass(); break; case ".tif": pExport = new ExportTIFFClass(); break; case ".png": pExport = new ExportPNGClass(); break; case ".pdf": pExport = new ExportPDFClass(); break; default: MessageBox.Show("没有输出格式,默认到JPEG格式"); pExport = new ExportJPEGClass(); break; } pExport.ExportFileName = ExpPath; exportRect.left = 0; exportRect.top = 0; exportRect.right = Width; exportRect.bottom = Height; if (bRegion) { view.GraphicsContainer.DeleteAllElements(); view.Refresh(); } IEnvelope envelope = new EnvelopeClass(); envelope.PutCoords((double)exportRect.left, (double)exportRect.top, (double)exportRect.right, (double)exportRect.bottom); pExport.PixelBounds = envelope; view.Output(pExport.StartExporting(), OutputResolution, ref exportRect, pEnvelope, null); pExport.FinishExporting(); pExport.Cleanup(); } /// <summary> /// 全域导出 /// </summary> /// <param name="OutputResolution">输出分辨率</param> /// <param name="ExpPath">输出路径</param> /// <param name="view">视图</param> public static void ExportActiveView(int OutputResolution, string ExpPath, IActiveView view) { IExport pExport = null; tagRECT exportRect; IEnvelope envelope2 = view.Extent; int num = (int)Math.Round(view.ScreenDisplay.DisplayTransformation.Resolution); string sType = System.IO.Path.GetExtension(ExpPath); switch (sType) { case ".jpg": pExport = new ExportJPEGClass(); break; case ".bmp": pExport = new ExportBMPClass(); break; case ".gif": pExport = new ExportGIFClass(); break; case ".tif": pExport = new ExportTIFFClass(); break; case ".png": pExport = new ExportPNGClass(); break; case ".pdf": pExport = new ExportPDFClass(); break; default: MessageBox.Show("没有输出格式,默认到JPEG格式"); pExport = new ExportJPEGClass(); break; } pExport.ExportFileName = ExpPath; exportRect.left = 0; exportRect.top = 0; exportRect.right = (int)Math.Round((double)(view.ExportFrame.right * (((double)OutputResolution) / ((double)num)))); exportRect.bottom = (int)Math.Round((double)(view.ExportFrame.bottom * (((double)OutputResolution) / ((double)num)))); IEnvelope envelope = new EnvelopeClass(); envelope.PutCoords((double)exportRect.left, (double)exportRect.top, (double)exportRect.right, (double)exportRect.bottom); pExport.PixelBounds = envelope; view.Output(pExport.StartExporting(), OutputResolution, ref exportRect, envelope2, null); pExport.FinishExporting(); pExport.Cleanup(); } /// <summary> /// 区域导出 /// </summary> /// <param name="pGeo">几何图形</param> /// <param name="OutputResolution">输出分辨率</param> /// <param name="ExpPath">输出路径</param> /// <param name="view">视图</param> public static void ExportRegion(IGeometry pGeo, int OutputResolution, string ExpPath, IActiveView view) { IExport export = null; IWorldFileSettings settings = null; IEnvelope envelope2 = pGeo.Envelope; string str = ExpPath.Substring(ExpPath.Length - 3, 3).ToUpper(); switch (str) { case "JPG": settings = new ExportJPEGClass(); export = new ExportJPEGClass(); settings = export as IWorldFileSettings; ; settings.MapExtent = envelope2; settings.OutputWorldFile = false; break; case "BMP": settings = new ExportBMPClass(); export = new ExportBMPClass(); settings = export as IWorldFileSettings; ; settings.MapExtent = envelope2; settings.OutputWorldFile = false; break; case "TIF": settings = new ExportTIFFClass(); export = new ExportTIFFClass(); settings = export as IWorldFileSettings; ; settings.MapExtent = envelope2; settings.OutputWorldFile = false; break; case "PNG": settings = new ExportPNGClass(); export = new ExportPNGClass(); settings = export as IWorldFileSettings; settings.MapExtent = envelope2; settings.OutputWorldFile = false; break; default: break; } if (settings == null) return; export.ExportFileName = ExpPath; int num = (int)Math.Round(view.ScreenDisplay.DisplayTransformation.Resolution); tagRECT grect2 = new tagRECT(); IEnvelope envelope3 = new EnvelopeClass(); view.ScreenDisplay.DisplayTransformation.TransformRect(envelope2, ref grect2, 9); grect2.left = 0; grect2.top = 0; grect2.right = (int)Math.Round((double)((grect2.right - grect2.left) * (((double)OutputResolution) / ((double)num)))); grect2.bottom = (int)Math.Round((double)((grect2.bottom - grect2.top) * (((double)OutputResolution) / ((double)num)))); envelope3.PutCoords((double)grect2.left, (double)grect2.top, (double)grect2.right, (double)grect2.bottom); export.PixelBounds = envelope3; view.GraphicsContainer.DeleteAllElements(); view.Output(export.StartExporting(), OutputResolution, ref grect2, envelope2, null); export.FinishExporting(); export.Cleanup(); AddElement(pGeo, view); } /// <summary> /// 视图窗口绘制几何图形元素 /// </summary> /// <param name="pGeometry">几何图形</param> /// <param name="activeView">视图</param> public static void AddElement(IGeometry pGeometry, IActiveView activeView) { IRgbColor fillColor = GetRgbColor(204, 175, 235); IRgbColor lineColor = GetRgbColor(0, 0, 0); IElement pEle = CreateElement(pGeometry, lineColor, fillColor); IGraphicsContainer pGC = activeView.GraphicsContainer; if (pGC != null) { pGC.AddElement(pEle, 0); activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pEle, null); } } /// <summary> /// 获取RGB颜色 /// </summary> /// <param name="intR">红</param> /// <param name="intG">绿</param> /// <param name="intB">蓝</param> /// <returns></returns> private static IRgbColor GetRgbColor(int intR, int intG, int intB) { IRgbColor pRgbColor = null; if (intR < 0 || intR > 255 || intG < 0 || intG > 255 || intB < 0 || intB > 255) { return pRgbColor; } pRgbColor = new RgbColorClass(); pRgbColor.Red = intR; pRgbColor.Green = intG; pRgbColor.Blue = intB; return pRgbColor; } /// <summary> /// 创建图形元素 /// </summary> /// <param name="pGeometry">几何图形</param> /// <param name="lineColor">边框颜色</param> /// <param name="fillColor">填充颜色</param> /// <returns></returns> private static IElement CreateElement(IGeometry pGeometry, IRgbColor lineColor, IRgbColor fillColor) { if (pGeometry == null || lineColor == null || fillColor == null) { return null; } IElement pElem = null; try { if (pGeometry is IEnvelope) pElem = new RectangleElementClass(); else if (pGeometry is IPolygon) pElem = new PolygonElementClass(); else if (pGeometry is ICircularArc) { ISegment pSegCircle = pGeometry as ISegment;//QI ISegmentCollection pSegColl = new PolygonClass(); object o = Type.Missing; pSegColl.AddSegment(pSegCircle, ref o, ref o); IPolygon pPolygon = pSegColl as IPolygon; pGeometry = pPolygon as IGeometry; pElem = new CircleElementClass(); } else if (pGeometry is IPolyline) pElem = new LineElementClass(); if (pElem == null) return null; pElem.Geometry = pGeometry; IFillShapeElement pFElem = pElem as IFillShapeElement; ISimpleFillSymbol pSymbol = new SimpleFillSymbolClass(); pSymbol.Color = fillColor; pSymbol.Outline.Color = lineColor; pSymbol.Style = esriSimpleFillStyle.esriSFSCross; if (pSymbol == null) { return null; } pFElem.Symbol = pSymbol; } catch (Exception ex) { MessageBox.Show(ex.Message); } return pElem; } }
1、全域导出
当全域导出按钮的事件触发时,赋值给控制全域输出的布尔型变量为true。核心代码如下:
private void btnExportMap_Click(object sender, EventArgs e) { if (frmExpMap == null || frmExpMap.IsDisposed) { frmExpMap = new FormExportMap(mainMapControl); } frmExpMap.IsRegion = false; frmExpMap.GetGeometry = mainMapControl.ActiveView.Extent; frmExpMap.Show(); frmExpMap.Activate(); }
2、区域导出
按钮单击事件代码:
private void btnExportRegion_Click(object sender, EventArgs e) { mainMapControl.CurrentTool = null; mainMapControl.MousePointer = esriControlsMousePointer.esriPointerCrosshair; pMouseOperate = "ExportRegion"; }
区域导出首先绘制出需要导出的多边形区域,主要使用IRubberBand接口。IRubberBand接口有TrackExisting和TrackNew两种方法。TrackExisting用于判断当鼠标点击时,是否移动或重绘选中的图形;TrackNew用于当鼠标点击时,在视图窗口中绘制一个新的图形。
对绘制多边形的方法进行封装,代码如下://绘制多边形 public IPolygon DrawPolygon(AxMapControl mapCtrl) { IGeometry pGeometry = null; if (mapCtrl == null) return null; IRubberBand rb = new RubberPolygonClass(); pGeometry = rb.TrackNew(mapCtrl.ActiveView.ScreenDisplay, null); return pGeometry as IPolygon; }
当鼠标点击时,绘制多边形,获取多边形的Geometry,对Geometry范围内的地图进行输出。在mainMapControl的OnMouseDown事件中,核心代码如下:
case "ExportRegion": //区域导出 //删除视图中数据 mainMapControl.ActiveView.GraphicsContainer.DeleteAllElements(); mainMapControl.ActiveView.Refresh(); IPolygon pPolygon = DrawPolygon(mainMapControl); if (pPolygon == null) return; ExportMap.AddElement(pPolygon, mainMapControl.ActiveView); if (frmExpMap == null || frmExpMap.IsDisposed) { frmExpMap = new FormExportMap(mainMapControl); } frmExpMap.IsRegion = true; frmExpMap.GetGeometry = pPolygon as IGeometry; frmExpMap.Show(); frmExpMap.Activate(); break;
二、TOCControl控件的右键菜单
添加右键菜单需要使用ContextMenuStrip控件,这里以添加属性表、缩放到图层、移除图层、图层可选、图层不可选五个常用功能为例进行讲解。右键菜单如下图所示。
//TOC菜单 IFeatureLayer pTocFeatureLayer = null; //点击的要素图层 private FormAtrribute frmAttribute = null; //图层属性窗体 private ILayer pMoveLayer; //需要调整显示顺序的图层 private int toIndex; //存放拖动图层移动到的索引号
在TOCControl控件的OnMouseDown事件中添加如下代码:
private void axTOCControl_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e) { try { if (e.button == 2) { esriTOCControlItem pItem = esriTOCControlItem.esriTOCControlItemNone; IBasicMap pMap = null; ILayer pLayer = null; object unk = null; object data = null; axTOCControl.HitTest(e.x, e.y, ref pItem, ref pMap, ref pLayer, ref unk, ref data); pTocFeatureLayer = pLayer as IFeatureLayer; if (pItem == esriTOCControlItem.esriTOCControlItemLayer && pTocFeatureLayer != null) { btnLayerSel.Enabled = !pTocFeatureLayer.Selectable; btnLayerUnSel.Enabled = pTocFeatureLayer.Selectable; contextMenuStrip.Show(Control.MousePosition); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
1、查看图层属性表
实现思路如下:
(1)遍历矢量目标图层的所有字段,读取其别名赋值给表的列标题。
(2)查询图层的所有要素,根据要素字段的索引序号读取要素的字段值,并添加到列表中,依次循环。
(3)与DataGridView控件的数据源绑定。
属性表运行界面如下图所示:
//要查询的属性图层 private IFeatureLayer _curFeatureLayer; public IFeatureLayer CurFeatureLayer { get { return _curFeatureLayer; } set { _curFeatureLayer = value; } } public void InitUI() { if (_curFeatureLayer == null) return; IFeature pFeature = null; DataTable pFeatDT = new DataTable(); //创建数据表 DataRow pDataRow = null; //数据表行变量 DataColumn pDataCol = null; //数据表列变量 IField pField = null; for (int i = 0; i < _curFeatureLayer.FeatureClass.Fields.FieldCount; i++) { pDataCol = new DataColumn(); pField = _curFeatureLayer.FeatureClass.Fields.get_Field(i); pDataCol.ColumnName = pField.AliasName; //获取字段名作为列标题 pDataCol.DataType = Type.GetType("System.Object");//定义列字段类型 pFeatDT.Columns.Add(pDataCol); //在数据表中添加字段信息 } IFeatureCursor pFeatureCursor = _curFeatureLayer.Search(null, true); pFeature = pFeatureCursor.NextFeature(); while (pFeature != null) { pDataRow = pFeatDT.NewRow(); //获取字段属性 for (int k = 0; k < pFeatDT.Columns.Count; k++) { pDataRow[k] = pFeature.get_Value(k); } pFeatDT.Rows.Add(pDataRow); //在数据表中添加字段属性信息 pFeature = pFeatureCursor.NextFeature(); } //释放指针 System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor); //dataGridAttribute.BeginInit(); dataGridAttribute.DataSource = pFeatDT; //dataGridAttribute.EndInit(); }
在属性表按钮的单击事件中调用属性窗口,核心代码如下:
//属性表窗口 private void btnAttribute_Click(object sender, EventArgs e) { if (frmAttribute == null || frmAttribute.IsDisposed) { frmAttribute = new FormAtrribute(); } frmAttribute.CurFeatureLayer = pTocFeatureLayer; frmAttribute.InitUI(); frmAttribute.ShowDialog(); }
2、缩放到图层
根据IFeatureLayer接口的AreaOfInterest属性获取图层的范围,并赋予数据视图的范围。在缩放到图层按钮的单击事件中,核心代码如下:
//缩放到图层 private void btnZoomToLayer_Click(object sender, EventArgs e) { if (pTocFeatureLayer == null) return; (mainMapControl.Map as IActiveView).Extent = pTocFeatureLayer.AreaOfInterest; (mainMapControl.Map as IActiveView).PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null); }
3、移除图层
一般情况下,对地图进行删除操作时需进行提示。在移除图层按钮的单击事件中,核心代码如下:
//移除图层 private void btnRemoveLayer_Click(object sender, EventArgs e) { try { if (pTocFeatureLayer == null) return; DialogResult result = MessageBox.Show("是否删除[" + pTocFeatureLayer.Name + "]图层", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information); if (result == DialogResult.OK) { mainMapControl.Map.DeleteLayer(pTocFeatureLayer); } mainMapControl.ActiveView.Refresh(); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
4、图层可选、不可选
设置图层是否可选,主要用到IFeatureLayer接口的Selectable属性,当图层设置不可选时,要素选择工具不能拾取该图层的要素。当右键菜单弹出时,设置图层可选、不可选按钮可用状态。
点击可选按钮时,设置图层可算,可选按钮不可用。核心代码如下:
//图层可选 private void btnLayerSel_Click(object sender, EventArgs e) { pTocFeatureLayer.Selectable = true; btnLayerSel.Enabled = !btnLayerSel.Enabled; }
点击不可选按钮时,设置图层不可选,不可选按钮不可用。核心代码如下:
//图层不可选 private void btnLayerUnSel_Click(object sender, EventArgs e) { pTocFeatureLayer.Selectable = false; btnLayerUnSel.Enabled = !btnLayerUnSel.Enabled; }
三、图层显示顺序调整
为实现使用鼠标将需要调整显示顺序的图层拖放到目标位置的功能,涉及TOCControl控件的OnMouseDown和OnMouseUp两个事件以及HitTest()方法。
实现思路:
(1)在TOCControl中,鼠标点击时即在OnMouseDown事件中,拾取需要调整显示顺序的图层,当鼠标弹起时即OnMouseUp事件中,获得图层移到位置的图层索引号。
(2)使用IMap接口提供的MoveLayer方法,将需要调整显示顺序的图层移到目标位置。
(3)使用TOCControl的Update()方法,更新TOCControl控件中的图层顺序。
需要声明的变量如下:
private ILayer pMoveLayer; //需要调整显示顺序的图层private int toIndex; //存放拖动图层移动到的索引号private Point pMoveLayerPoint = new Point(); //鼠标在TOC中左键按下时点的位置
在TOCControl的OuMouseDown事件中,核心代码如下:
private void axTOCControl_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e) { try { if (e.button == 1) { esriTOCControlItem pItem = esriTOCControlItem.esriTOCControlItemNone; IBasicMap pMap = null; object unk = null; object data = null; ILayer pLayer = null; axTOCControl.HitTest(e.x, e.y, ref pItem, ref pMap, ref pLayer, ref unk, ref data); if (pLayer == null) return; pMoveLayerPoint.PutCoords(e.x, e.y); if (pItem == esriTOCControlItem.esriTOCControlItemLayer) { if (pLayer is IAnnotationSublayer) { return; } else { pMoveLayer = pLayer; } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
在TOCControl的OuMouseUp事件中,核心代码如下:
private void axTOCControl_OnMouseUp(object sender, ITOCControlEvents_OnMouseUpEvent e) { try { if (e.button == 1 && pMoveLayer != null && pMoveLayerPoint.Y != e.y) { esriTOCControlItem pItem = esriTOCControlItem.esriTOCControlItemNone; IBasicMap pBasicMap = null; object unk = null; object data = null; ILayer pLayer = null; axTOCControl.HitTest(e.x, e.y, ref pItem, ref pBasicMap, ref pLayer, ref unk, ref data); IMap pMap = mainMapControl.ActiveView.FocusMap; if (pItem == esriTOCControlItem.esriTOCControlItemLayer || pLayer != null) { if (pMoveLayer != pLayer) { ILayer pTempLayer; //获得鼠标弹起时所在图层的索引号 for (int i = 0; i < pMap.LayerCount; i++) { pTempLayer = pMap.get_Layer(i); if (pTempLayer == pLayer) { toIndex = i; } } } } //移动到最前面 else if (pItem == esriTOCControlItem.esriTOCControlItemMap) { toIndex = 0; } //移动到最后面 else if (pItem == esriTOCControlItem.esriTOCControlItemNone) { toIndex = pMap.LayerCount - 1; } pMap.MoveLayer(pMoveLayer, toIndex); mainMapControl.ActiveView.Refresh(); axTOCControl.Update(); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
0 0
- ArcGIS Engine 10.0 for.NET开发学习笔记(九)
- ArcGIS Engine 10.0 for.NET开发学习笔记(一)
- ArcGIS Engine 10.0 for.NET开发学习笔记(二)
- ArcGIS Engine 10.0 for.NET开发学习笔记(三)
- ArcGIS Engine 10.0 for.NET开发学习笔记(四)
- ArcGIS Engine 10.0 for.NET开发学习笔记(五)
- ArcGIS Engine 10.0 for.NET开发学习笔记(六)
- ArcGIS Engine 10.0 for.NET开发学习笔记(七)
- ArcGIS Engine 10.0 for.NET开发学习笔记(八)
- arcgis engine开发学习
- Arcgis Engine Runtime开发笔记
- Arcgis Engine for java 10 开发环境配置 (eclipse)
- ArcGIS Engine学习(1)
- Arcgis for iOS开发笔记(一)
- 《ArcGIS Runtime SDK for .NET开发笔记》 --Hello Word
- 《ArcGIS Runtime SDK for .NET开发笔记》--三维功能
- 《ArcGIS Runtime SDK for .NET开发笔记》--在线编辑
- Arcgis Engine for java 10 开发环境配置
- C语言的数据类型
- Android 设置应用程序的主题颜色
- 黑盒测试基础之BUG三方评估
- iOS 出现蓝色块
- mysql新建表,对表主键外键操作
- ArcGIS Engine 10.0 for.NET开发学习笔记(九)
- centos6 安装phpredis扩展
- HDU 2186 悼念512汶川大地震遇难同胞——一定要记住我爱你
- SSH框架总结(框架分析+环境搭建+实例源码下载
- 笔记︱虚拟变量回归=差异显著(方差分析)+差异量化(系数值)
- STM32F103学习笔记——时钟使能
- SSL协议(HTTPS) 握手、工作流程详解(双向HTTPS流程)
- MultiRecyclerView(多布局的RecyclerView)的简单使用
- ACID事务