一个可以方便调试响应数据的控件(Android版本),okhttp读取信息kotlin

" ]\n" +
“}”
)
}

}

核心代码

大部分代码都有中英文对应的注释,可能有些地方翻译地不太好,请各位见谅哈。

上面也提到了,该控件是以RecyclerView为基础,涉及到JsonItemViewJsonViewAdapterJsonRecyclerView三个类。

JSONItemView

该类用于展示每一条数据对应的视图,用到的布局文件item_json_view.xml,它继承LinearLayout,有四个关键的变量,代码如下所示:

// JSONItemView.kt
private lateinit var tvLeft: TextView
private lateinit var ivIcon: ImageView
private lateinit var tvRight: TextView

/**

  • Set the scaled pixel text size.

  • 设置文本大小。
    */
    var textSize = DEFAULT_TEXT_SIZE_SP
    set(value) {
    // 范围是[12.0F,30.0F]
    field = when {
    value < 12.0F -> 12.0F
    value > 30.0F -> 30.0F
    else -> value
    }
    // 设置左边文本的文字大小
    tvLeft.textSize = field
    // 设置展示展开和收缩图标的大小
    val size = TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP,
    field,
    resources.displayMetrics
    ).toInt()
    ivIcon.layoutParams = (ivIcon.layoutParams as LinearLayout.LayoutParams).apply {
    width = size
    height = size
    }
    // 设置右边文本的文字大小
    tvRight.textSize = field
    }

  • 变量tvLeft左边TextView,用于展示key相关的文本

  • 变量ivIcon中间ImageView,用于展示展开或者收缩的图标

  • 变量tvRight右边TextView,用于展示value相关的文本

  • 变量textSizepublic的变量,可以通过该变量改变文本的大小,要注意的是,单位是sp,无论是赋多大或者多小值,文本的最小值12sp最大值30sp

JSONViewAdapter

该类用于处理不同类型的数据和点击相关的逻辑,它继承RecyclerView.Adapter,主要涉及到如下几个关键的方法:

onBindViewHolder方法

代码如下所示:

// JSONViewAdapter.kt
override fun onBindViewHolder(holder: JSONViewAdapter.JsonItemViewHolder, position: Int) {
with(holder.jsonItemView) {
textSize = this@JSONViewAdapter.textSize
setRightColor(textColor)
jsonObject?.let { bindJSONObjectData(position, it) }
jsonArray?.let { bindJSONArrayData(position, it) }
}
}

作用是将数据绑定到视图,如果数据类型是JSONObject,就调用bindJSONObjectData方法,如果数据类型是JSONArray,就调用bindJSONArrayData方法。

handleValue方法

代码如下所示:

// JSONViewAdapter.kt
/**

  • Handle the styling of the right part of the json item view (i.e., the part that shows the value).
  • 处理JsonItemView右边部分的样式(即展示值的部分)。
  • @param value The value to be displayed in the json item view.(要在JsonItemView展示的value。)
  • @param itemView The json item view to be processed.(要处理的JsonItemView对象。)
  • @param appendComma Whether to append commas.(是否附加逗号。)
  • @param hierarchy The number of view hierarchies.(View的层次结构数量。)
    */
    private fun handleValue(
    value: Any?,
    itemView: JSONItemView,
    appendComma: Boolean,
    hierarchy: Int
    ) {
    itemView.showRight(SpannableStringBuilder().apply {
    when (value) {
    is Number ->
    // 处理值为Number类型的样式
    handleNumberValue(itemView, value)
    is Boolean ->
    // 处理值为Boolean类型的样式
    handleBooleanValue(itemView, value)
    is String ->
    // 处理值为String类型的样式
    handleStringValue(itemView, value)
    is JSONObject ->
    // 处理值为JSONObject类型的样式
    handleJSONObjectValue(itemView, value, appendComma, hierarchy)
    is JSONArray ->
    // 处理值为JSONArray类型的样式
    handleJSONArrayValue(itemView, value, appendComma, hierarchy)
    else ->
    // 处理值为null的样式
    handleNullValue(itemView)
    }
    if (appendComma) append(",")
    })
    }

onClick方法

如果数据类型是JSONObject或者JSONArray的话,可以通过点击展开或者收缩视图,代码如下所示:

如果是第一次展开,就调用performFirstExpand方法,否则就调用performClick方法,代码如下所示:

// JSONViewAdapter.kt
override fun onClick(v: View?) {
// 如果itemView的子View数量是1,就证明这是第一次展开
(itemView.childCount == 1)
.yes { performFirstExpand() }
.otherwise { performClick() }
}

performFirstExpand方法

该方法用于第一次展开JSONObject或者JSONArray对应的itemView,代码如下所示:

// JSONViewAdapter.kt
/**

  • The first time the view corresponding to a JSONObject or JSONArray is expanded.
  • 第一次展开JSONObject或者JSONArray对应的itemView。
    */
    private fun performFirstExpand() {
    isExpanded = true
    itemView.showIcon(false)
    itemView.tag = itemView.getRightText()
    itemView.showRight(if (isJsonObject) “{” else “[”)

// 展开该层级以下的视图
val array: JSONArray? =
if (isJsonObject) (value as JSONObject).names() else value as JSONArray
val length = array?.length() ?: 0
for (i in 0 until length) {
itemView.addViewNoInvalidate(JSONItemView(itemView.context).apply {
textSize = this@JSONViewAdapter.textSize
setRightColor(textColor)
val childValue = array?.opt(i)
isJsonObject
.yes {
handleJSONObject(
key = childValue as String,
value = (value as JSONObject)[childValue],
appendComma = i < length - 1,
hierarchy = hierarchy
)
}
.otherwise {
handleJSONArray(
value = childValue,
appendComma = i < length - 1,
hierarchy = hierarchy
)
}
})
}
// 展示该层级最后的一个视图
itemView.addViewNoInvalidate(JSONItemView(itemView.context).apply {
textSize = this@JSONViewAdapter.textSize
setRightColor(textColor)
showRight(
StringBuilder(getHierarchyStr(hierarchy - 1))
.append(if (isJsonObject) “}” else “]”)
.append(if (appendComma) “,” else “”)
)
})
// 重绘itemView
itemView.requestLayout()
itemView.invalidate()
}

performClick方法

该方法用于点击后展开或者收缩,代码如下所示:

/**

  • Click to expand or collapse.
  • 点击后展开或者收缩。
    */
    private fun performClick() {
    itemView.showIcon(isExpanded)
    val rightText = itemView.getRightText()
    itemView.showRight(itemView.tag as CharSequence)
    itemView.tag = rightText
    for (i in 1 until itemView.childCount) {
    // 如果展开的话,就把子View都设成可见状态,否则就设为隐藏状态
    itemView.getChildAt(i).visibility = if (isExpanded) View.GONE else View.VISIBLE
    }
    isExpanded = !isExpanded
    }

如果数据类型是url的话,可以通过点击来打开浏览器查看,代码如下所示:

/**

  • Click to expand or collapse.
  • 点击后展开或者收缩。
    */
    private fun performClick() {
    itemView.showIcon(isExpanded)
    val rightText = itemView.getRightText()
    itemView.showRight(itemView.tag as CharSequence)
    itemView.tag = rightText
    for (i in 1 until itemView.childCount) {
    // 如果展开的话,就把子View都设成可见状态,否则就设为隐藏状态
    itemView.getChildAt(i).visibility = if (isExpanded) View.GONE else View.VISIBLE
    }
    isExpanded = !isExpanded
    }

判断是否是url类型的正则表达式如下所示,注释已经写得很详细,这里就不再赘述:

private val urlPattern: Pattern = Pattern.compile(
// 验证是否是http://、https://、ftp://、rtsp://、mms://其中一个
"^((http|https|ftp|rtsp|mms)?😕

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

/)?" +
// 判断字符是否为FTP地址(ftp://user:password@)
// 判断字符是否为0到9、小写字母a到z、、!、~、*、’、(、)、.、&、=、+、$、%、-其中一个,匹配零次或者一次
"(([0-9a-z
!~’().&=+$%-]+: )?" +
// 判断字符是否为0到9、小写字母a到z、_、!、~、
、’、(、)、.、&、=、+、$、%、-其中一个,匹配一次或者多次
“[0-9a-z_!~’().&=+$%-]+" +
// @
“@)?” +
// 判断字符是否为IP地址,例子:192.168.255.255
// 判断字符是否匹配1+[0到9,匹配两次],例如:192
“((1\d{2}” +
// 或者
“|” +
// 判断字符是否匹配2+[0到4,匹配一次]+[0到9,匹配一次],例如:225
“2[0-4]\d” +
// 或者
“|” +
// 判断字符是否匹配25+[0到5,匹配一次],例如:255
“25[0-5]” +
// 或者
“|” +
// 判断字符是否匹配[1到9,匹配一次]+[0到9,匹配一次],例如:25
“[1-9]\d” +
// 或者
“|” +
// 判断字符是否匹配1到9,匹配一次,例如:5
“[1-9])” +
// 判断字符是否匹配.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d),匹配三次
“(\.(” +
// 判断字符是否匹配1+[0到9,匹配两次],例如:192
“1\d{2}” +
// 或者
“|” +
// 判断字符是否匹配2+[0到4,匹配一次]+[0到9,匹配一次],例如:225
“2[0-4]\d” +
// 或者
“|” +
// 判断字符是否匹配25+[0到5,匹配一次],例如:255
“25[0-5]” +
// 或者
“|” +
// 判断字符是否匹配[1到9]+[0到9],例如:25
“[1-9]\d” +
// 或者
“|” +
// 判断字符是否匹配0到9,匹配一次,例如:5
“\d))” +
// 匹配三次
“{3}” +
// 或者
“|” +
// 判断字符是否为域名(Domain Name)
// 三级域名或者以上,判断字符是否为0到9、小写字母a到z、_、!、~、
、’、(、)、-其中一个,匹配零次或者多次,然后加上.,例如:www.
“([0-9a-z_!~’()-]+\.)” +
// 二级域名,长度不能超过63个字符,先判断第一个字符是否为0到9、小写字母a到z其中一个,匹配一次,然后判断第二个字符是否为0到9、小写字母a到z、-其中一个,最多匹配61次,这两个字符匹配零次或者一次,最后判断第三个字符是否为0到9、小写字母a到z其中一个,然后加上.
“([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]” +
// 顶级域名,判断字符是否为小写字母a到z其中一个,匹配最少两次、最多六次,例如:.com、.cn
“\.[a-z]{2,6})” +
// 端口号,判断字符是否匹配:+[0到9,匹配最少一次、最多四次],匹配零次或者一次
“(:[0-9]{1,4})?” +
// 判断字符是否为斜杠(/),匹配零次或者一次,如果没有文件名,就不需要斜杠
“((/?)|” +
// 判断字符是否为0到9、小写字母a到z、大写字母A到Z、、!、~、*、’、(、)、.、;、?、:、@、&、=、+、$、,、%、#、-其中一个,匹配一次或者多次
"(/[0-9a-zA-Z
!~*’(){}.;?😡&=+$,%#-]+)+” +
// 判断字符是否为斜杠(/),匹配零次或者一次
“/?)$”
)

正则表达式可视化图如下所示:

UrlRegularExpression.png

JSONRecyclerView

该类用于将要处理的数据以列表的方式展示到视图,注释写得比较清楚,这里就不再赘述了,代码如下所示:

// JSONRecyclerView.kt
package com.tanjiajun.jsonrecyclerview.view

import android.content.Context
import android.util.AttributeSet
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.tanjiajun.jsonrecyclerview.DEFAULT_TEXT_SIZE_SP
import com.tanjiajun.jsonrecyclerview.R
import com.tanjiajun.jsonrecyclerview.adapter.JSONViewAdapter
import org.json.JSONArray
import org.json.JSONObject

/**

  • Created by TanJiaJun on 5/31/21.
    */
    class JSONRecyclerView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
    ) : RecyclerView(context, attrs, defStyleAttr) {

private val adapter = JSONViewAdapter(context)

init {
layoutManager = LinearLayoutManager(context)
setAdapter(adapter)
}

/**

  • 绑定JSON字符串数据。
  • Bind the json string data.
  • @param jsonString The json string to bind.(要绑定的JSON字符串。)
    */
    fun bindData(jsonString: String) =
    adapter.bindData(jsonString)

/**

  • 绑定JSONObject数据。
  • Bind the json object data.
  • @param jsonObject The json object to bind.(要绑定的JSONObject。)
    */
    fun bindData(jsonObject: JSONObject) =
    adapter.bindData(jsonObject)

/**

  • 绑定JSONArray数据。
  • Bind the json array data.
  • @param jsonArray The json array to bind.(要绑定的JSONArray。)
    */
    fun bindData(jsonArray: JSONArray) =
    adapter.bindData(jsonArray)

/**

  • 设置JsonItemView的样式。
  • Set the json item view styles.
  • @param textSize The size of all text.(所有文本的大小。)
  • @param textColor The normal text color.(普通文本的颜色)
  • @param keyColor The color of the text of type key.(key类型文本的颜色。)
  • @param stringColor The color of the text of type String.(字符串类型文本的颜色。)
  • @param numberColor The color of the text of type Number.(Number类型文本的颜色。)
  • @param booleanColor The color of text of type Boolean.(Boolean类型文本的颜色。)
  • @param urlColor The color of url text.(url文本的颜色。)
  • @param nullColor The color of null text.(null文本的颜色。)
    */
    @JvmOverloads
    fun setStyles(
    textSize: Float = DEFAULT_TEXT_SIZE_SP,
    @ColorInt textColor: Int = ContextCompat.getColor(context, R.color.default_text_color),
    @ColorInt keyColor: Int = ContextCompat.getColor(context, R.color.default_key_color),
    @ColorInt stringColor: Int = ContextCompat.getColor(context, R.color.default_string_color),
    @ColorInt numberColor: Int = ContextCompat.getColor(context, R.color.default_number_color),
    @ColorInt booleanColor: Int = ContextCompat.getColor(
    context,
    R.color.default_boolean_color
    ),
    @ColorInt urlColor: Int = ContextCompat.getColor(context, R.color.default_url_color),
    @ColorInt nullColor: Int = ContextCompat.getColor(context, R.color.default_null_color)
    ) {
    with(adapter) {
    this.textSize = when {
    textSize < MIN_TEXT_SIZE -> MIN_TEXT_SIZE
    textSize > MAX_TEXT_SIZE -> MAX_TEXT_SIZE
    else -> textSize
    }
    this.textColor = textColor
    this.keyColor = keyColor
    this.stringColor = stringColor
    this.numberColor = numberColor
    this.booleanColor = booleanColor
    this.urlColor = urlColor
    this.nullColor = nullColor
    // 刷新列表
    notifyDataSetChanged()
    }
    }

private companion object {
const val MIN_TEXT_SIZE = 12.0F
const val MAX_TEXT_SIZE = 24.0F
}

tSize < MIN_TEXT_SIZE -> MIN_TEXT_SIZE
textSize > MAX_TEXT_SIZE -> MAX_TEXT_SIZE
else -> textSize
}
this.textColor = textColor
this.keyColor = keyColor
this.stringColor = stringColor
this.numberColor = numberColor
this.booleanColor = booleanColor
this.urlColor = urlColor
this.nullColor = nullColor
// 刷新列表
notifyDataSetChanged()
}
}

private companion object {
const val MIN_TEXT_SIZE = 12.0F
const val MAX_TEXT_SIZE = 24.0F
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以回答您的问题。以下是使用Kotlin语言在Android中使用OkHttp获取JSON数据并解析的代码示例: 首先,您需要在您的项目中添加OkHttp库的依赖项。在您的app的build.gradle文件中添加以下代码: ```groovy dependencies { implementation 'com.squareup.okhttp3:okhttp:4.9.0' } ``` 接下来,您可以使用以下代码获取JSON数据: ```kotlin val client = OkHttpClient() val request = Request.Builder() .url("https://example.com/data.json") .build() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { // 处理失败情况 } override fun onResponse(call: Call, response: Response) { val responseData = response.body()?.string() // 处理响应数据 } }) ``` 在上面的代码中,我们使用OkHttp创建了一个新的HTTP请求并将其排队以异步执行。当响应返回时,我们将调用回调方法以处理响应。 现在,我们需要解析JSON数据。您可以使用Kotlin内置的JSON解析器或Gson等第三方库。以下是使用Kotlin自带的解析器的代码示例: ```kotlin // 假设我们的JSON数据如下: // { // "name": "John Smith", // "age": 30, // "avatarUrl": "https://example.com/avatar.jpg" // } data class User(val name: String, val age: Int, val avatarUrl: String) val user = Json.decodeFromString<User>(responseData) val avatarUrl = user.avatarUrl // 使用Glide库加载图片 Glide.with(context) .load(avatarUrl) .into(imageView) ``` 在上面的代码中,我们首先定义了一个名为User的数据类,该类具有与JSON数据结构相匹配的属性。然后,我们使用Kotlin的JSON解析器从JSON字符串中解析出User对象。最后,我们使用Glide库加载用户的头像图片。 希望这可以帮助您开始使用KotlinOkHttp获取和解析JSON数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值