在即将到来的绘制和保存要素的篇章之前,我们需要组织好要素的录入结构与规划,为了能快速上手即用我为大家写了这部分的代码逻辑,入口在程序侧边栏项目配置
字段信息编辑完毕回退就会自动保存,在ArcgisAndroid生成一个配置文件,文件名就是项目名,里面的各种信息都是json格式
字段类型有string,int,double。显示样式可以有输入和选择,样式为选择的时候要把默认值内容回车换行一行一个输入,这样在展示的时候就可以用这个换行符来分割得到每一个值让你快速选择来代替重复性的输入。
值得一提的是如何根据json配置文件来动态组装dialog界面的控件呢?这个就需要用代码动态生成了,我弄了个UIGenerator控件工具类,在这做了一些基础的代码控件,可以看到有线性布局,输入框,下拉控件,TextView,还有MaterialCardView。例如我有10个字段我就调用UIGenerator.buildLinearLayout然后指定成为垂直,然后循环调用UIGenerator.buildEditInputView10次就会添加进来父容器buildLinearLayout中,这样就组出了一个线性布局里面有10个输入框了,还可以在buildLinearLayout外面再build一个cardView这样就会出现卡片样式,这下你已经脑补出来了,巧妙吧 ~=。=~
package com.tanqidi.arcgisandroid.base.utils
import android.opengl.Visibility
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout
import androidx.core.view.setPadding
import com.tanqidi.arcgisandroid.databinding.*
class UIGenerator {
companion object {
/**
* 生成线性布局
*/
fun buildLinearLayout(
layoutInflater: LayoutInflater,
viewGroup: ViewGroup,
isAttach: Boolean = true,
myOrientation: Int = LinearLayout.HORIZONTAL,
myGravity: Int = Gravity.LEFT,
layoutWeight: Int = -1,
myMarginLeft: Int = 0,
myMarginRight: Int = 0,
myMarginTop: Int = 0,
myMarginBottom: Int = 0,
myWidth: Int = MATCH_PARENT,
myHeight: Int = WRAP_CONTENT,
myPadding: Int = 0,
myPaddingLeft: Int = 0,
myPaddingRight: Int = 0,
myPaddingTop: Int = 0,
myPaddingBottom: Int = 0,
myVisibility: Int = View.VISIBLE,
myBackgroundColor: Int? = null
): ItemLinearlayoutBinding {
return ItemLinearlayoutBinding.inflate(layoutInflater, viewGroup, isAttach).apply {
linearLayoutContainer.apply {
id = (0..Int.MAX_VALUE).random()
visibility = myVisibility
orientation = myOrientation
gravity = myGravity
layoutParams = LinearLayout.LayoutParams(myWidth, myHeight).apply {
marginEnd = myMarginRight
marginStart = myMarginLeft
topMargin = myMarginTop
bottomMargin = myMarginBottom
if (myBackgroundColor != null) {
setBackgroundColor(myBackgroundColor)
}
if (layoutWeight != -1) {
weight = layoutWeight.toFloat()
}
if (myPadding > 0) {
setPadding(myPadding)
} else {
setPadding(myPaddingLeft, myPaddingTop, myPaddingRight, myPaddingBottom)
}
}
}
}
}
/**
* 输入框
*/
fun buildEditInputView(
layoutInflater: LayoutInflater,
viewGroup: ViewGroup,
layoutWeight: Int = -1,
myMarginLeft: Int = 0,
myMarginRight: Int = 0,
myMarginTop: Int = 0,
myMarginBottom: Int = 0,
myWidth: Int = MATCH_PARENT,
myHeight: Int = WRAP_CONTENT,
myPadding: Int = 0,
myPaddingLeft: Int = 0,
myPaddingRight: Int = 0,
myPaddingTop: Int = 0,
myPaddingBottom: Int = 0,
isAttach: Boolean = true,
myGravity: Int? = null,
myInputType: Int? = -1,
) : ItemEditInputBinding {
return ItemEditInputBinding.inflate(layoutInflater, viewGroup, isAttach).apply {
textInputEditText.apply {
//重新生成一个id给他,不然旋转屏幕都用同一个id,那么数据就错乱了
id = (0..Int.MAX_VALUE).random()
if (myInputType != null && myInputType != -1) {
inputType = myInputType
}
}
textInputLayout.apply {
id = (0..Int.MAX_VALUE).random()
layoutParams = LinearLayout.LayoutParams(myWidth, myHeight).apply {
marginEnd = myMarginRight
marginStart = myMarginLeft
topMargin = myMarginTop
bottomMargin = myMarginBottom
if (layoutWeight != -1) {
weight = layoutWeight.toFloat()
}
}
}
}
}
/**
* 文本
*/
fun buildTextView(
layoutInflater: LayoutInflater,
viewGroup: ViewGroup,
layoutWeight: Int = -1,
myMarginLeft: Int = 0,
myMarginRight: Int = 0,
myMarginTop: Int = 0,
myMarginBottom: Int = 0,
myWidth: Int = WRAP_CONTENT,
myHeight: Int = WRAP_CONTENT,
myPadding: Int = 0,
myPaddingLeft: Int = 0,
myPaddingRight: Int = 0,
myPaddingTop: Int = 0,
myPaddingBottom: Int = 0,
isAttach: Boolean = true,
myGravity: Int? = null
): ItemTextviewBinding {
return ItemTextviewBinding.inflate(layoutInflater, viewGroup, isAttach).apply {
textView.apply {
id = (0..Int.MAX_VALUE).random()
layoutParams = LinearLayout.LayoutParams(myWidth, myHeight).apply {
marginEnd = myMarginRight
marginStart = myMarginLeft
topMargin = myMarginTop
bottomMargin = myMarginBottom
if (myPadding > 0) {
setPadding(myPadding)
} else {
setPadding(myPaddingLeft, myPaddingTop, myPaddingRight, myPaddingBottom)
}
if (myGravity != null) {
gravity = myGravity
}
if (layoutWeight != -1) {
weight = layoutWeight.toFloat()
}
}
}
}
}
fun buildChipView(
layoutInflater: LayoutInflater,
viewGroup: ViewGroup,
isAttach: Boolean = true,
layoutWeight: Int = -1,
myMarginLeft: Int = 0,
myMarginRight: Int = 0,
myMarginTop: Int = 0,
myMarginBottom: Int = 0,
myWidth: Int = WRAP_CONTENT,
myHeight: Int = WRAP_CONTENT,
): ItemChipBinding {
return ItemChipBinding.inflate(layoutInflater, viewGroup, isAttach).apply {
chip.apply {
id = (0..Int.MAX_VALUE).random()
layoutParams = LinearLayout.LayoutParams(myWidth, myHeight).apply {
marginEnd = myMarginRight
marginStart = myMarginLeft
topMargin = myMarginTop
bottomMargin = myMarginBottom
if (layoutWeight != -1) {
weight = layoutWeight.toFloat()
}
}
}
}
}
fun buildChipGroupView(
layoutInflater: LayoutInflater,
viewGroup: ViewGroup,
isAttach: Boolean = true,
layoutWeight: Int = -1,
myMarginLeft: Int = 0,
myMarginRight: Int = 0,
myMarginTop: Int = 0,
myMarginBottom: Int = 0,
myWidth: Int = MATCH_PARENT,
myHeight: Int = WRAP_CONTENT,
): ItemChipGroupBinding {
return ItemChipGroupBinding.inflate(layoutInflater, viewGroup, isAttach).apply {
chipGroup.apply {
id = (0..Int.MAX_VALUE).random()
layoutParams = LinearLayout.LayoutParams(myWidth, myHeight).apply {
marginEnd = myMarginRight
marginStart = myMarginLeft
topMargin = myMarginTop
bottomMargin = myMarginBottom
if (layoutWeight != -1) {
weight = layoutWeight.toFloat()
}
}
}
}
}
fun buildCardView(
layoutInflater: LayoutInflater,
viewGroup: ViewGroup,
isAttach: Boolean = true,
layoutWeight: Int = -1,
myMarginLeft: Int = 0,
myMarginRight: Int = 0,
myMarginTop: Int = 0,
myMarginBottom: Int = 0,
myWidth: Int = MATCH_PARENT,
myHeight: Int = WRAP_CONTENT,
): ItemCardViewBinding {
return ItemCardViewBinding.inflate(layoutInflater, viewGroup, isAttach).apply {
materialCardView.apply {
id = (0..Int.MAX_VALUE).random()
layoutParams = LinearLayout.LayoutParams(myWidth, myHeight).apply {
marginEnd = myMarginRight
marginStart = myMarginLeft
topMargin = myMarginTop
bottomMargin = myMarginBottom
if (layoutWeight != -1) {
weight = layoutWeight.toFloat()
}
}
}
}
}
}
}
这是添加字段到界面的代码片段,剩下的其他代码就不粘贴了各位下载代码自行阅读
/**
* 创建一个字段
*/
private fun buildField(dialogBinding: ItemDialogDrawFeatureBinding, layer: com.tanqidi.arcgisandroid.data.layerConfig.Layer) {
//把上一次的所有的field清空掉
dialogBinding.fieldContainer.removeAllViews()
//列表该图层里面的所有field并创建控件
layer.fields.forEachIndexed { index, field ->
/**
* 因为字段有两种显示样式,一种是单纯的输入,另外一种是选择
*/
when(field.showType){
SHOW_TYPE_INPUT -> {
//创建一个cardView包裹住
UIGenerator.buildCardView(layoutInflater, dialogBinding.fieldContainer).apply {
//创建一个输入框
UIGenerator.buildEditInputView(layoutInflater, cardViewContainer).apply {
textInputLayout.hint = field.alias
//因为是输入,还可以限制输入的类型是什么,int,string,double ...
textInputEditText.apply {
when(field.type){
INPUT_TYPE_INT -> inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL
INPUT_TYPE_DOUBLE -> inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
INPUT_TYPE_STRING -> inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_NORMAL
}
//输入框如果输入了内容,就把内容放到dataCollectMap中
addTextChangedListener {
val inputContent = it.toString().trim()
if(!TextUtils.isEmpty(inputContent)){
dataCollectMap[field.field] = inputContent
} else {
/**
* 上面直接把inputContent放入来理解,这里为什么要放个null呢?这里如果是二次查询编辑呢?你删掉了所有的内容
* 如果不把这个null内容放进去他不会覆盖上一次的内容,可以给个null也或者是个空串也行
*/
dataCollectMap[field.field] = null
}
}
}
}
}
}
SHOW_TYPE_SELECT -> {
//创建一个cardView
UIGenerator.buildCardView(layoutInflater, dialogBinding.fieldContainer).apply {
//创建一个垂直线性布局
UIGenerator.buildLinearLayout(layoutInflater, cardViewContainer, myOrientation = LinearLayout.VERTICAL).apply {
//创建一个textView
UIGenerator.buildTextView(layoutInflater, linearLayoutContainer, myMarginLeft = 16, myMarginTop = 16).apply {
textView.text = field.alias
}
//创建ChipGroup组
UIGenerator.buildChipGroupView(layoutInflater, linearLayoutContainer).apply {
field.defaultValue.split("\n").forEachIndexed { index, item ->
UIGenerator.buildChipView(layoutInflater, chipGroup).apply {
chip.apply {
text = item
setOnCheckedChangeListener { buttonView, isChecked ->
if(isChecked){
dataCollectMap[field.field] = item
} else {
dataCollectMap[field.field] = null
}
}
}
}
}
}
}
}
}
}
}
}
https://gitee.com/tanqidi/ArcgisAndroidhttps://gitee.com/tanqidi/ArcgisAndroid