diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d85b90..93ed780 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d85b90..93ed780 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index f4d63e2..907912b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -1,22 +1,122 @@ package com.casic.xz.meterage.extensions +import android.app.Activity import android.content.Context +import android.graphics.drawable.Drawable +import android.text.Editable +import android.text.Html +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan +import android.text.style.ImageSpan +import android.view.View +import android.widget.TextView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.Target import com.casic.xz.meterage.callback.OnImageCompressListener import com.casic.xz.meterage.model.ErrorMessageModel import com.casic.xz.meterage.utils.LocaleConstant +import com.casic.xz.meterage.view.BigImageActivity import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.createCompressImageDir +import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.utils.SaveKeyValues import org.json.JSONObject +import org.xml.sax.XMLReader import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File import java.util.* +import java.util.concurrent.ExecutionException /** * String扩展方法 */ +fun String.separateResponseCode(): Int { + if (this.isBlank()) { + return 404 + } + return JSONObject(this).getInt("code") +} + +fun String.toErrorMessage(): String { + val errorModel = Gson().fromJson( + this, object : TypeToken() {}.type + ) + return errorModel.message.toString() +} + +fun String.formatTextFromHtml(activity: Activity?, textView: TextView?, width: Int) { + if (activity == null || textView == null || this.isBlank()) { + return + } + synchronized(this) { + textView.movementMethod = LinkMovementMethod.getInstance() + textView.text = Html.fromHtml(this) //默认不处理图片先这样简单设置 + Thread { + val imageGetter = object : Html.ImageGetter { + override fun getDrawable(source: String?): Drawable? { + try { + val drawable = Glide.with(activity).asDrawable().load(source) + .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get() ?: return null + var w = drawable.intrinsicWidth + var h = drawable.intrinsicHeight + + //对图片改变尺寸 + val scale = (width / w).toFloat() + w = (scale * w).toInt() + h = (scale * h).toInt() + drawable.setBounds(0, 0, w, h) + return drawable + } catch (e: ExecutionException) { + e.printStackTrace() + } catch (e: InterruptedException) { + e.printStackTrace() + } + return null + } + } + val charSequence: CharSequence = Html.fromHtml(this, imageGetter, + object : Html.TagHandler { + override fun handleTag( + opening: Boolean, tag: String?, output: Editable?, xmlReader: XMLReader? + ) { + //获取传入html文本里面包含的所有Tag,然后取出img开头的 + if (tag?.lowercase(Locale.getDefault()) == "img") { + val len = output?.length + // 获取图片地址 + val images = output!!.getSpans(len!! - 1, len, ImageSpan::class.java) + val imgURL = images[0].source ?: return + // 使图片可点击并监听点击事件 + output.setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + //查看大图 + val urls = ArrayList() + urls.add(imgURL) + activity.navigatePageTo(0, urls) + } + }, len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + } + } + ) + activity.runOnUiThread(Runnable { textView.text = charSequence }) + }.start() + } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" +} + fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -38,27 +138,4 @@ listener.onError(e) } }).launch() -} - -fun String.separateResponseCode(): Int { - if (this.isBlank()) { - return 404 - } - return JSONObject(this).getInt("code") -} - -fun String.toErrorMessage(): String { - val errorModel = Gson().fromJson( - this, object : TypeToken() {}.type - ) - return errorModel.message.toString() -} - -//拼接图片地址 -fun String.combineImagePath(): String { - if (this.isEmpty()) return this - val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL - ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d85b90..93ed780 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index f4d63e2..907912b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -1,22 +1,122 @@ package com.casic.xz.meterage.extensions +import android.app.Activity import android.content.Context +import android.graphics.drawable.Drawable +import android.text.Editable +import android.text.Html +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan +import android.text.style.ImageSpan +import android.view.View +import android.widget.TextView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.Target import com.casic.xz.meterage.callback.OnImageCompressListener import com.casic.xz.meterage.model.ErrorMessageModel import com.casic.xz.meterage.utils.LocaleConstant +import com.casic.xz.meterage.view.BigImageActivity import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.createCompressImageDir +import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.utils.SaveKeyValues import org.json.JSONObject +import org.xml.sax.XMLReader import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File import java.util.* +import java.util.concurrent.ExecutionException /** * String扩展方法 */ +fun String.separateResponseCode(): Int { + if (this.isBlank()) { + return 404 + } + return JSONObject(this).getInt("code") +} + +fun String.toErrorMessage(): String { + val errorModel = Gson().fromJson( + this, object : TypeToken() {}.type + ) + return errorModel.message.toString() +} + +fun String.formatTextFromHtml(activity: Activity?, textView: TextView?, width: Int) { + if (activity == null || textView == null || this.isBlank()) { + return + } + synchronized(this) { + textView.movementMethod = LinkMovementMethod.getInstance() + textView.text = Html.fromHtml(this) //默认不处理图片先这样简单设置 + Thread { + val imageGetter = object : Html.ImageGetter { + override fun getDrawable(source: String?): Drawable? { + try { + val drawable = Glide.with(activity).asDrawable().load(source) + .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get() ?: return null + var w = drawable.intrinsicWidth + var h = drawable.intrinsicHeight + + //对图片改变尺寸 + val scale = (width / w).toFloat() + w = (scale * w).toInt() + h = (scale * h).toInt() + drawable.setBounds(0, 0, w, h) + return drawable + } catch (e: ExecutionException) { + e.printStackTrace() + } catch (e: InterruptedException) { + e.printStackTrace() + } + return null + } + } + val charSequence: CharSequence = Html.fromHtml(this, imageGetter, + object : Html.TagHandler { + override fun handleTag( + opening: Boolean, tag: String?, output: Editable?, xmlReader: XMLReader? + ) { + //获取传入html文本里面包含的所有Tag,然后取出img开头的 + if (tag?.lowercase(Locale.getDefault()) == "img") { + val len = output?.length + // 获取图片地址 + val images = output!!.getSpans(len!! - 1, len, ImageSpan::class.java) + val imgURL = images[0].source ?: return + // 使图片可点击并监听点击事件 + output.setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + //查看大图 + val urls = ArrayList() + urls.add(imgURL) + activity.navigatePageTo(0, urls) + } + }, len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + } + } + ) + activity.runOnUiThread(Runnable { textView.text = charSequence }) + }.start() + } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" +} + fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -38,27 +138,4 @@ listener.onError(e) } }).launch() -} - -fun String.separateResponseCode(): Int { - if (this.isBlank()) { - return 404 - } - return JSONObject(this).getInt("code") -} - -fun String.toErrorMessage(): String { - val errorModel = Gson().fromJson( - this, object : TypeToken() {}.type - ) - return errorModel.message.toString() -} - -//拼接图片地址 -fun String.combineImagePath(): String { - if (this.isEmpty()) return this - val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL - ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt new file mode 100644 index 0000000..8279efd --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt @@ -0,0 +1,88 @@ +package com.casic.xz.meterage.view + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.xz.meterage.R +import com.luck.picture.lib.photoview.PhotoView +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + +class BigImageActivity : KotlinBaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + ImmerseStatusBarUtil.setColor(this, Color.BLACK) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + + } + + override fun observeRequestState() { + + } + + override fun initEvent() { + val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.size == 0) { + return + } + val imageSize = urls.size + pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.offscreenPageLimit = imageSize + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + imageSize + ")") + } + + override fun onPageScrollStateChanged(state: Int) {} + }) + } + + inner class BigImageAdapter( + private val context: Context, private val data: ArrayList + ) : PagerAdapter() { + + override fun getCount(): Int = data.size + + override fun isViewFromObject(view: View, any: Any): Boolean { + return view == any + } + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = + LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(data[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { finish() } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, any: Any) { + container.removeView(any as View) + } + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d85b90..93ed780 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index f4d63e2..907912b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -1,22 +1,122 @@ package com.casic.xz.meterage.extensions +import android.app.Activity import android.content.Context +import android.graphics.drawable.Drawable +import android.text.Editable +import android.text.Html +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan +import android.text.style.ImageSpan +import android.view.View +import android.widget.TextView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.Target import com.casic.xz.meterage.callback.OnImageCompressListener import com.casic.xz.meterage.model.ErrorMessageModel import com.casic.xz.meterage.utils.LocaleConstant +import com.casic.xz.meterage.view.BigImageActivity import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.createCompressImageDir +import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.utils.SaveKeyValues import org.json.JSONObject +import org.xml.sax.XMLReader import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File import java.util.* +import java.util.concurrent.ExecutionException /** * String扩展方法 */ +fun String.separateResponseCode(): Int { + if (this.isBlank()) { + return 404 + } + return JSONObject(this).getInt("code") +} + +fun String.toErrorMessage(): String { + val errorModel = Gson().fromJson( + this, object : TypeToken() {}.type + ) + return errorModel.message.toString() +} + +fun String.formatTextFromHtml(activity: Activity?, textView: TextView?, width: Int) { + if (activity == null || textView == null || this.isBlank()) { + return + } + synchronized(this) { + textView.movementMethod = LinkMovementMethod.getInstance() + textView.text = Html.fromHtml(this) //默认不处理图片先这样简单设置 + Thread { + val imageGetter = object : Html.ImageGetter { + override fun getDrawable(source: String?): Drawable? { + try { + val drawable = Glide.with(activity).asDrawable().load(source) + .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get() ?: return null + var w = drawable.intrinsicWidth + var h = drawable.intrinsicHeight + + //对图片改变尺寸 + val scale = (width / w).toFloat() + w = (scale * w).toInt() + h = (scale * h).toInt() + drawable.setBounds(0, 0, w, h) + return drawable + } catch (e: ExecutionException) { + e.printStackTrace() + } catch (e: InterruptedException) { + e.printStackTrace() + } + return null + } + } + val charSequence: CharSequence = Html.fromHtml(this, imageGetter, + object : Html.TagHandler { + override fun handleTag( + opening: Boolean, tag: String?, output: Editable?, xmlReader: XMLReader? + ) { + //获取传入html文本里面包含的所有Tag,然后取出img开头的 + if (tag?.lowercase(Locale.getDefault()) == "img") { + val len = output?.length + // 获取图片地址 + val images = output!!.getSpans(len!! - 1, len, ImageSpan::class.java) + val imgURL = images[0].source ?: return + // 使图片可点击并监听点击事件 + output.setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + //查看大图 + val urls = ArrayList() + urls.add(imgURL) + activity.navigatePageTo(0, urls) + } + }, len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + } + } + ) + activity.runOnUiThread(Runnable { textView.text = charSequence }) + }.start() + } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" +} + fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -38,27 +138,4 @@ listener.onError(e) } }).launch() -} - -fun String.separateResponseCode(): Int { - if (this.isBlank()) { - return 404 - } - return JSONObject(this).getInt("code") -} - -fun String.toErrorMessage(): String { - val errorModel = Gson().fromJson( - this, object : TypeToken() {}.type - ) - return errorModel.message.toString() -} - -//拼接图片地址 -fun String.combineImagePath(): String { - if (this.isEmpty()) return this - val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL - ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt new file mode 100644 index 0000000..8279efd --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt @@ -0,0 +1,88 @@ +package com.casic.xz.meterage.view + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.xz.meterage.R +import com.luck.picture.lib.photoview.PhotoView +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + +class BigImageActivity : KotlinBaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + ImmerseStatusBarUtil.setColor(this, Color.BLACK) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + + } + + override fun observeRequestState() { + + } + + override fun initEvent() { + val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.size == 0) { + return + } + val imageSize = urls.size + pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.offscreenPageLimit = imageSize + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + imageSize + ")") + } + + override fun onPageScrollStateChanged(state: Int) {} + }) + } + + inner class BigImageAdapter( + private val context: Context, private val data: ArrayList + ) : PagerAdapter() { + + override fun getCount(): Int = data.size + + override fun isViewFromObject(view: View, any: Any): Boolean { + return view == any + } + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = + LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(data[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { finish() } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, any: Any) { + container.removeView(any as View) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt index a14ec4d..94067d3 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt @@ -1,12 +1,16 @@ package com.casic.xz.meterage.view import android.annotation.SuppressLint +import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.formatTextFromHtml import com.casic.xz.meterage.extensions.initLayoutImmersionBar import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* import kotlinx.android.synthetic.main.include_base_title.* @@ -35,6 +39,24 @@ noticeNoView.text = dataRow.noticeNo noticeTitleView.text = dataRow.noticeTitle noticeSketchView.text = dataRow.noticeSketch + + dataRow.noticeContent.formatTextFromHtml( + this, noticeContentView, obtainScreenWidth() + ) + + if (dataRow.minioFileName.isNullOrBlank()) { + minioFileView.text = "暂无附件" + } else { + minioFileView.text = dataRow.minioFileName + val textPaint = minioFileView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + + minioFileView.setOnClickListener { + //查看附件 + } + } } }) } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d85b90..93ed780 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index f4d63e2..907912b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -1,22 +1,122 @@ package com.casic.xz.meterage.extensions +import android.app.Activity import android.content.Context +import android.graphics.drawable.Drawable +import android.text.Editable +import android.text.Html +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan +import android.text.style.ImageSpan +import android.view.View +import android.widget.TextView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.Target import com.casic.xz.meterage.callback.OnImageCompressListener import com.casic.xz.meterage.model.ErrorMessageModel import com.casic.xz.meterage.utils.LocaleConstant +import com.casic.xz.meterage.view.BigImageActivity import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.createCompressImageDir +import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.utils.SaveKeyValues import org.json.JSONObject +import org.xml.sax.XMLReader import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File import java.util.* +import java.util.concurrent.ExecutionException /** * String扩展方法 */ +fun String.separateResponseCode(): Int { + if (this.isBlank()) { + return 404 + } + return JSONObject(this).getInt("code") +} + +fun String.toErrorMessage(): String { + val errorModel = Gson().fromJson( + this, object : TypeToken() {}.type + ) + return errorModel.message.toString() +} + +fun String.formatTextFromHtml(activity: Activity?, textView: TextView?, width: Int) { + if (activity == null || textView == null || this.isBlank()) { + return + } + synchronized(this) { + textView.movementMethod = LinkMovementMethod.getInstance() + textView.text = Html.fromHtml(this) //默认不处理图片先这样简单设置 + Thread { + val imageGetter = object : Html.ImageGetter { + override fun getDrawable(source: String?): Drawable? { + try { + val drawable = Glide.with(activity).asDrawable().load(source) + .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get() ?: return null + var w = drawable.intrinsicWidth + var h = drawable.intrinsicHeight + + //对图片改变尺寸 + val scale = (width / w).toFloat() + w = (scale * w).toInt() + h = (scale * h).toInt() + drawable.setBounds(0, 0, w, h) + return drawable + } catch (e: ExecutionException) { + e.printStackTrace() + } catch (e: InterruptedException) { + e.printStackTrace() + } + return null + } + } + val charSequence: CharSequence = Html.fromHtml(this, imageGetter, + object : Html.TagHandler { + override fun handleTag( + opening: Boolean, tag: String?, output: Editable?, xmlReader: XMLReader? + ) { + //获取传入html文本里面包含的所有Tag,然后取出img开头的 + if (tag?.lowercase(Locale.getDefault()) == "img") { + val len = output?.length + // 获取图片地址 + val images = output!!.getSpans(len!! - 1, len, ImageSpan::class.java) + val imgURL = images[0].source ?: return + // 使图片可点击并监听点击事件 + output.setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + //查看大图 + val urls = ArrayList() + urls.add(imgURL) + activity.navigatePageTo(0, urls) + } + }, len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + } + } + ) + activity.runOnUiThread(Runnable { textView.text = charSequence }) + }.start() + } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" +} + fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -38,27 +138,4 @@ listener.onError(e) } }).launch() -} - -fun String.separateResponseCode(): Int { - if (this.isBlank()) { - return 404 - } - return JSONObject(this).getInt("code") -} - -fun String.toErrorMessage(): String { - val errorModel = Gson().fromJson( - this, object : TypeToken() {}.type - ) - return errorModel.message.toString() -} - -//拼接图片地址 -fun String.combineImagePath(): String { - if (this.isEmpty()) return this - val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL - ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt new file mode 100644 index 0000000..8279efd --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt @@ -0,0 +1,88 @@ +package com.casic.xz.meterage.view + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.xz.meterage.R +import com.luck.picture.lib.photoview.PhotoView +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + +class BigImageActivity : KotlinBaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + ImmerseStatusBarUtil.setColor(this, Color.BLACK) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + + } + + override fun observeRequestState() { + + } + + override fun initEvent() { + val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.size == 0) { + return + } + val imageSize = urls.size + pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.offscreenPageLimit = imageSize + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + imageSize + ")") + } + + override fun onPageScrollStateChanged(state: Int) {} + }) + } + + inner class BigImageAdapter( + private val context: Context, private val data: ArrayList + ) : PagerAdapter() { + + override fun getCount(): Int = data.size + + override fun isViewFromObject(view: View, any: Any): Boolean { + return view == any + } + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = + LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(data[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { finish() } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, any: Any) { + container.removeView(any as View) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt index a14ec4d..94067d3 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt @@ -1,12 +1,16 @@ package com.casic.xz.meterage.view import android.annotation.SuppressLint +import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.formatTextFromHtml import com.casic.xz.meterage.extensions.initLayoutImmersionBar import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* import kotlinx.android.synthetic.main.include_base_title.* @@ -35,6 +39,24 @@ noticeNoView.text = dataRow.noticeNo noticeTitleView.text = dataRow.noticeTitle noticeSketchView.text = dataRow.noticeSketch + + dataRow.noticeContent.formatTextFromHtml( + this, noticeContentView, obtainScreenWidth() + ) + + if (dataRow.minioFileName.isNullOrBlank()) { + minioFileView.text = "暂无附件" + } else { + minioFileView.text = dataRow.minioFileName + val textPaint = minioFileView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + + minioFileView.setOnClickListener { + //查看附件 + } + } } }) } diff --git a/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt index 3c90012..1e6dd90 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt @@ -111,6 +111,7 @@ override fun onResume() { super.onResume() + pageIndex = 1 getNoticeListByPage() } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d85b90..93ed780 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index f4d63e2..907912b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -1,22 +1,122 @@ package com.casic.xz.meterage.extensions +import android.app.Activity import android.content.Context +import android.graphics.drawable.Drawable +import android.text.Editable +import android.text.Html +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan +import android.text.style.ImageSpan +import android.view.View +import android.widget.TextView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.Target import com.casic.xz.meterage.callback.OnImageCompressListener import com.casic.xz.meterage.model.ErrorMessageModel import com.casic.xz.meterage.utils.LocaleConstant +import com.casic.xz.meterage.view.BigImageActivity import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.createCompressImageDir +import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.utils.SaveKeyValues import org.json.JSONObject +import org.xml.sax.XMLReader import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File import java.util.* +import java.util.concurrent.ExecutionException /** * String扩展方法 */ +fun String.separateResponseCode(): Int { + if (this.isBlank()) { + return 404 + } + return JSONObject(this).getInt("code") +} + +fun String.toErrorMessage(): String { + val errorModel = Gson().fromJson( + this, object : TypeToken() {}.type + ) + return errorModel.message.toString() +} + +fun String.formatTextFromHtml(activity: Activity?, textView: TextView?, width: Int) { + if (activity == null || textView == null || this.isBlank()) { + return + } + synchronized(this) { + textView.movementMethod = LinkMovementMethod.getInstance() + textView.text = Html.fromHtml(this) //默认不处理图片先这样简单设置 + Thread { + val imageGetter = object : Html.ImageGetter { + override fun getDrawable(source: String?): Drawable? { + try { + val drawable = Glide.with(activity).asDrawable().load(source) + .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get() ?: return null + var w = drawable.intrinsicWidth + var h = drawable.intrinsicHeight + + //对图片改变尺寸 + val scale = (width / w).toFloat() + w = (scale * w).toInt() + h = (scale * h).toInt() + drawable.setBounds(0, 0, w, h) + return drawable + } catch (e: ExecutionException) { + e.printStackTrace() + } catch (e: InterruptedException) { + e.printStackTrace() + } + return null + } + } + val charSequence: CharSequence = Html.fromHtml(this, imageGetter, + object : Html.TagHandler { + override fun handleTag( + opening: Boolean, tag: String?, output: Editable?, xmlReader: XMLReader? + ) { + //获取传入html文本里面包含的所有Tag,然后取出img开头的 + if (tag?.lowercase(Locale.getDefault()) == "img") { + val len = output?.length + // 获取图片地址 + val images = output!!.getSpans(len!! - 1, len, ImageSpan::class.java) + val imgURL = images[0].source ?: return + // 使图片可点击并监听点击事件 + output.setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + //查看大图 + val urls = ArrayList() + urls.add(imgURL) + activity.navigatePageTo(0, urls) + } + }, len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + } + } + ) + activity.runOnUiThread(Runnable { textView.text = charSequence }) + }.start() + } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" +} + fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -38,27 +138,4 @@ listener.onError(e) } }).launch() -} - -fun String.separateResponseCode(): Int { - if (this.isBlank()) { - return 404 - } - return JSONObject(this).getInt("code") -} - -fun String.toErrorMessage(): String { - val errorModel = Gson().fromJson( - this, object : TypeToken() {}.type - ) - return errorModel.message.toString() -} - -//拼接图片地址 -fun String.combineImagePath(): String { - if (this.isEmpty()) return this - val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL - ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt new file mode 100644 index 0000000..8279efd --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt @@ -0,0 +1,88 @@ +package com.casic.xz.meterage.view + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.xz.meterage.R +import com.luck.picture.lib.photoview.PhotoView +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + +class BigImageActivity : KotlinBaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + ImmerseStatusBarUtil.setColor(this, Color.BLACK) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + + } + + override fun observeRequestState() { + + } + + override fun initEvent() { + val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.size == 0) { + return + } + val imageSize = urls.size + pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.offscreenPageLimit = imageSize + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + imageSize + ")") + } + + override fun onPageScrollStateChanged(state: Int) {} + }) + } + + inner class BigImageAdapter( + private val context: Context, private val data: ArrayList + ) : PagerAdapter() { + + override fun getCount(): Int = data.size + + override fun isViewFromObject(view: View, any: Any): Boolean { + return view == any + } + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = + LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(data[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { finish() } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, any: Any) { + container.removeView(any as View) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt index a14ec4d..94067d3 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt @@ -1,12 +1,16 @@ package com.casic.xz.meterage.view import android.annotation.SuppressLint +import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.formatTextFromHtml import com.casic.xz.meterage.extensions.initLayoutImmersionBar import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* import kotlinx.android.synthetic.main.include_base_title.* @@ -35,6 +39,24 @@ noticeNoView.text = dataRow.noticeNo noticeTitleView.text = dataRow.noticeTitle noticeSketchView.text = dataRow.noticeSketch + + dataRow.noticeContent.formatTextFromHtml( + this, noticeContentView, obtainScreenWidth() + ) + + if (dataRow.minioFileName.isNullOrBlank()) { + minioFileView.text = "暂无附件" + } else { + minioFileView.text = dataRow.minioFileName + val textPaint = minioFileView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + + minioFileView.setOnClickListener { + //查看附件 + } + } } }) } diff --git a/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt index 3c90012..1e6dd90 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt @@ -111,6 +111,7 @@ override fun onResume() { super.onResume() + pageIndex = 1 getNoticeListByPage() } diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..9d060f4 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d85b90..93ed780 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index f4d63e2..907912b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -1,22 +1,122 @@ package com.casic.xz.meterage.extensions +import android.app.Activity import android.content.Context +import android.graphics.drawable.Drawable +import android.text.Editable +import android.text.Html +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan +import android.text.style.ImageSpan +import android.view.View +import android.widget.TextView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.Target import com.casic.xz.meterage.callback.OnImageCompressListener import com.casic.xz.meterage.model.ErrorMessageModel import com.casic.xz.meterage.utils.LocaleConstant +import com.casic.xz.meterage.view.BigImageActivity import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.createCompressImageDir +import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.utils.SaveKeyValues import org.json.JSONObject +import org.xml.sax.XMLReader import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File import java.util.* +import java.util.concurrent.ExecutionException /** * String扩展方法 */ +fun String.separateResponseCode(): Int { + if (this.isBlank()) { + return 404 + } + return JSONObject(this).getInt("code") +} + +fun String.toErrorMessage(): String { + val errorModel = Gson().fromJson( + this, object : TypeToken() {}.type + ) + return errorModel.message.toString() +} + +fun String.formatTextFromHtml(activity: Activity?, textView: TextView?, width: Int) { + if (activity == null || textView == null || this.isBlank()) { + return + } + synchronized(this) { + textView.movementMethod = LinkMovementMethod.getInstance() + textView.text = Html.fromHtml(this) //默认不处理图片先这样简单设置 + Thread { + val imageGetter = object : Html.ImageGetter { + override fun getDrawable(source: String?): Drawable? { + try { + val drawable = Glide.with(activity).asDrawable().load(source) + .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get() ?: return null + var w = drawable.intrinsicWidth + var h = drawable.intrinsicHeight + + //对图片改变尺寸 + val scale = (width / w).toFloat() + w = (scale * w).toInt() + h = (scale * h).toInt() + drawable.setBounds(0, 0, w, h) + return drawable + } catch (e: ExecutionException) { + e.printStackTrace() + } catch (e: InterruptedException) { + e.printStackTrace() + } + return null + } + } + val charSequence: CharSequence = Html.fromHtml(this, imageGetter, + object : Html.TagHandler { + override fun handleTag( + opening: Boolean, tag: String?, output: Editable?, xmlReader: XMLReader? + ) { + //获取传入html文本里面包含的所有Tag,然后取出img开头的 + if (tag?.lowercase(Locale.getDefault()) == "img") { + val len = output?.length + // 获取图片地址 + val images = output!!.getSpans(len!! - 1, len, ImageSpan::class.java) + val imgURL = images[0].source ?: return + // 使图片可点击并监听点击事件 + output.setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + //查看大图 + val urls = ArrayList() + urls.add(imgURL) + activity.navigatePageTo(0, urls) + } + }, len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + } + } + ) + activity.runOnUiThread(Runnable { textView.text = charSequence }) + }.start() + } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" +} + fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -38,27 +138,4 @@ listener.onError(e) } }).launch() -} - -fun String.separateResponseCode(): Int { - if (this.isBlank()) { - return 404 - } - return JSONObject(this).getInt("code") -} - -fun String.toErrorMessage(): String { - val errorModel = Gson().fromJson( - this, object : TypeToken() {}.type - ) - return errorModel.message.toString() -} - -//拼接图片地址 -fun String.combineImagePath(): String { - if (this.isEmpty()) return this - val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL - ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt new file mode 100644 index 0000000..8279efd --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt @@ -0,0 +1,88 @@ +package com.casic.xz.meterage.view + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.xz.meterage.R +import com.luck.picture.lib.photoview.PhotoView +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + +class BigImageActivity : KotlinBaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + ImmerseStatusBarUtil.setColor(this, Color.BLACK) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + + } + + override fun observeRequestState() { + + } + + override fun initEvent() { + val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.size == 0) { + return + } + val imageSize = urls.size + pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.offscreenPageLimit = imageSize + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + imageSize + ")") + } + + override fun onPageScrollStateChanged(state: Int) {} + }) + } + + inner class BigImageAdapter( + private val context: Context, private val data: ArrayList + ) : PagerAdapter() { + + override fun getCount(): Int = data.size + + override fun isViewFromObject(view: View, any: Any): Boolean { + return view == any + } + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = + LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(data[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { finish() } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, any: Any) { + container.removeView(any as View) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt index a14ec4d..94067d3 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt @@ -1,12 +1,16 @@ package com.casic.xz.meterage.view import android.annotation.SuppressLint +import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.formatTextFromHtml import com.casic.xz.meterage.extensions.initLayoutImmersionBar import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* import kotlinx.android.synthetic.main.include_base_title.* @@ -35,6 +39,24 @@ noticeNoView.text = dataRow.noticeNo noticeTitleView.text = dataRow.noticeTitle noticeSketchView.text = dataRow.noticeSketch + + dataRow.noticeContent.formatTextFromHtml( + this, noticeContentView, obtainScreenWidth() + ) + + if (dataRow.minioFileName.isNullOrBlank()) { + minioFileView.text = "暂无附件" + } else { + minioFileView.text = dataRow.minioFileName + val textPaint = minioFileView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + + minioFileView.setOnClickListener { + //查看附件 + } + } } }) } diff --git a/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt index 3c90012..1e6dd90 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt @@ -111,6 +111,7 @@ override fun onResume() { super.onResume() + pageIndex = 1 getNoticeListByPage() } diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..9d060f4 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_notice_detail.xml b/app/src/main/res/layout/activity_notice_detail.xml index 25b055f..fd23cd8 100644 --- a/app/src/main/res/layout/activity_notice_detail.xml +++ b/app/src/main/res/layout/activity_notice_detail.xml @@ -157,6 +157,49 @@ android:textSize="@dimen/sp_14" /> + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d85b90..93ed780 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt index f4d63e2..907912b 100644 --- a/app/src/main/java/com/casic/xz/meterage/extensions/String.kt +++ b/app/src/main/java/com/casic/xz/meterage/extensions/String.kt @@ -1,22 +1,122 @@ package com.casic.xz.meterage.extensions +import android.app.Activity import android.content.Context +import android.graphics.drawable.Drawable +import android.text.Editable +import android.text.Html +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan +import android.text.style.ImageSpan +import android.view.View +import android.widget.TextView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.Target import com.casic.xz.meterage.callback.OnImageCompressListener import com.casic.xz.meterage.model.ErrorMessageModel import com.casic.xz.meterage.utils.LocaleConstant +import com.casic.xz.meterage.view.BigImageActivity import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.extensions.createCompressImageDir +import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.utils.SaveKeyValues import org.json.JSONObject +import org.xml.sax.XMLReader import top.zibin.luban.Luban import top.zibin.luban.OnCompressListener import java.io.File import java.util.* +import java.util.concurrent.ExecutionException /** * String扩展方法 */ +fun String.separateResponseCode(): Int { + if (this.isBlank()) { + return 404 + } + return JSONObject(this).getInt("code") +} + +fun String.toErrorMessage(): String { + val errorModel = Gson().fromJson( + this, object : TypeToken() {}.type + ) + return errorModel.message.toString() +} + +fun String.formatTextFromHtml(activity: Activity?, textView: TextView?, width: Int) { + if (activity == null || textView == null || this.isBlank()) { + return + } + synchronized(this) { + textView.movementMethod = LinkMovementMethod.getInstance() + textView.text = Html.fromHtml(this) //默认不处理图片先这样简单设置 + Thread { + val imageGetter = object : Html.ImageGetter { + override fun getDrawable(source: String?): Drawable? { + try { + val drawable = Glide.with(activity).asDrawable().load(source) + .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get() ?: return null + var w = drawable.intrinsicWidth + var h = drawable.intrinsicHeight + + //对图片改变尺寸 + val scale = (width / w).toFloat() + w = (scale * w).toInt() + h = (scale * h).toInt() + drawable.setBounds(0, 0, w, h) + return drawable + } catch (e: ExecutionException) { + e.printStackTrace() + } catch (e: InterruptedException) { + e.printStackTrace() + } + return null + } + } + val charSequence: CharSequence = Html.fromHtml(this, imageGetter, + object : Html.TagHandler { + override fun handleTag( + opening: Boolean, tag: String?, output: Editable?, xmlReader: XMLReader? + ) { + //获取传入html文本里面包含的所有Tag,然后取出img开头的 + if (tag?.lowercase(Locale.getDefault()) == "img") { + val len = output?.length + // 获取图片地址 + val images = output!!.getSpans(len!! - 1, len, ImageSpan::class.java) + val imgURL = images[0].source ?: return + // 使图片可点击并监听点击事件 + output.setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + //查看大图 + val urls = ArrayList() + urls.add(imgURL) + activity.navigatePageTo(0, urls) + } + }, len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + } + } + ) + activity.runOnUiThread(Runnable { textView.text = charSequence }) + }.start() + } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" +} + fun String.compressImage(context: Context, listener: OnImageCompressListener) { Luban.with(context) .load(this) @@ -38,27 +138,4 @@ listener.onError(e) } }).launch() -} - -fun String.separateResponseCode(): Int { - if (this.isBlank()) { - return 404 - } - return JSONObject(this).getInt("code") -} - -fun String.toErrorMessage(): String { - val errorModel = Gson().fromJson( - this, object : TypeToken() {}.type - ) - return errorModel.message.toString() -} - -//拼接图片地址 -fun String.combineImagePath(): String { - if (this.isEmpty()) return this - val defaultValue = SaveKeyValues.getValue( - LocaleConstant.DEFAULT_SERVER_CONFIG, LocaleConstant.SERVER_BASE_URL - ) as String - return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt new file mode 100644 index 0000000..8279efd --- /dev/null +++ b/app/src/main/java/com/casic/xz/meterage/view/BigImageActivity.kt @@ -0,0 +1,88 @@ +package com.casic.xz.meterage.view + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.xz.meterage.R +import com.luck.picture.lib.photoview.PhotoView +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + +class BigImageActivity : KotlinBaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + ImmerseStatusBarUtil.setColor(this, Color.BLACK) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + + } + + override fun observeRequestState() { + + } + + override fun initEvent() { + val index: Int = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0) + val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY) + if (urls == null || urls.size == 0) { + return + } + val imageSize = urls.size + pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.offscreenPageLimit = imageSize + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + imageSize + ")") + } + + override fun onPageScrollStateChanged(state: Int) {} + }) + } + + inner class BigImageAdapter( + private val context: Context, private val data: ArrayList + ) : PagerAdapter() { + + override fun getCount(): Int = data.size + + override fun isViewFromObject(view: View, any: Any): Boolean { + return view == any + } + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = + LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(data[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { finish() } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, any: Any) { + container.removeView(any as View) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt index a14ec4d..94067d3 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/NoticeDetailActivity.kt @@ -1,12 +1,16 @@ package com.casic.xz.meterage.view import android.annotation.SuppressLint +import android.graphics.Paint import androidx.lifecycle.ViewModelProvider import com.casic.xz.meterage.R +import com.casic.xz.meterage.extensions.formatTextFromHtml import com.casic.xz.meterage.extensions.initLayoutImmersionBar import com.casic.xz.meterage.vm.NoticeViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.obtainScreenWidth import com.pengxh.kt.lite.utils.Constant import kotlinx.android.synthetic.main.activity_notice_detail.* import kotlinx.android.synthetic.main.include_base_title.* @@ -35,6 +39,24 @@ noticeNoView.text = dataRow.noticeNo noticeTitleView.text = dataRow.noticeTitle noticeSketchView.text = dataRow.noticeSketch + + dataRow.noticeContent.formatTextFromHtml( + this, noticeContentView, obtainScreenWidth() + ) + + if (dataRow.minioFileName.isNullOrBlank()) { + minioFileView.text = "暂无附件" + } else { + minioFileView.text = dataRow.minioFileName + val textPaint = minioFileView.paint + textPaint.flags = Paint.UNDERLINE_TEXT_FLAG + textPaint.isAntiAlias = true + minioFileView.setTextColor(R.color.themeColor.convertColor(this)) + + minioFileView.setOnClickListener { + //查看附件 + } + } } }) } diff --git a/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt b/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt index 3c90012..1e6dd90 100644 --- a/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt +++ b/app/src/main/java/com/casic/xz/meterage/view/NoticeListActivity.kt @@ -111,6 +111,7 @@ override fun onResume() { super.onResume() + pageIndex = 1 getNoticeListByPage() } diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..9d060f4 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_notice_detail.xml b/app/src/main/res/layout/activity_notice_detail.xml index 25b055f..fd23cd8 100644 --- a/app/src/main/res/layout/activity_notice_detail.xml +++ b/app/src/main/res/layout/activity_notice_detail.xml @@ -157,6 +157,49 @@ android:textSize="@dimen/sp_14" /> + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml new file mode 100644 index 0000000..d90eb44 --- /dev/null +++ b/app/src/main/res/layout/item_big_picture.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file