1. 新增问题和删除修改功能(调试中)
2. 轨迹记录功能开放为所有类型的场景都记录
已修改25个文件
已添加12个文件
1288 ■■■■ 文件已修改
app/src/main/AndroidManifest.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/bean/vo/ProblemDetailVo.kt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/common/database/DbFactory.kt 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/common/net/NetWorkProgressInterceptor.kt 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/common/net/NetWorkProgressListener.kt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/common/net/ProgressRequestBody.kt 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/common/net/ResponseBodyCallBack2.kt 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/common/net/ResultCallBack2.kt 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/common/net/RetrofitFactory.kt 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/httpservice/MediaFileService.kt 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/httpservice/ProblemListService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/model/bean/BaseResponse.kt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/base/BaseActivity.kt 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/base/BaseTakePicActivity.kt 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/common/CameraActivity.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/BaseProblemListActivity.kt 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/BaseProblemListViewModel.kt 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/InspectionDetailActivity.kt 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuChangeActivity.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuEvidenceActivity.kt 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuEvidenceViewModel.kt 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuNewGitActivity.kt 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuProblemListActivity.kt 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuProblemUpdateActivity.kt 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuRecheckActivity.kt 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/repository/CommonRepository.kt 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/repository/ProblemRepository.kt 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/repository/dao/MediaFileDao.kt 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/util/DialogUtil2.kt 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/util/updateApp/UpdateAppUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/cn/flightfeather/thirdapp/view/PopupWindowWithMask.kt 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable-xxhdpi/shape_black_spinner.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/ic_unfold_more_black_20dp.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/dialog_take_evidence.xml 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_spinner_drop_down.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/strings.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/styles.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/AndroidManifest.xml
@@ -192,6 +192,8 @@
            android:theme="@style/AppTheme.NoActionBar" />
        <activity android:name=".module.inspection.MenuEvidenceActivity"
            android:theme="@style/TransparentTheme" />
        <activity android:name=".module.inspection.MenuProblemUpdateActivity"
            android:theme="@style/TransparentTheme" />
        <activity android:name=".module.inspection.MenuRecheckActivity"
            android:theme="@style/TransparentTheme" />
        <activity android:name=".module.inspection.MenuProblemListActivity"
app/src/main/java/cn/flightfeather/thirdapp/bean/vo/ProblemDetailVo.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
package cn.flightfeather.thirdapp.bean.vo
/**
 * @author riku
 * Date: 2020/7/30
 */
data class ProblemDetailVo(
        var problemTypeName: String,
        var problems: List<String>
)
app/src/main/java/cn/flightfeather/thirdapp/common/database/DbFactory.kt
@@ -8,24 +8,32 @@
 * @author riku
 * Date: 2019/5/16
 */
class DbFactory private constructor(application: CommonApplication){
class DbFactory private constructor(private val application: CommonApplication){
    private var daoSession: DaoSession? = null
    init {
        daoSession = application.daoSession
    }
    companion object {
        @Volatile
        private lateinit var daoSession: DaoSession
        private var mDbFactory: DbFactory? = null
        //数据库初始化
        @JvmStatic
        @Synchronized
        fun init(application: CommonApplication) {
            daoSession = application.daoSession
            if (mDbFactory == null) {
                mDbFactory = DbFactory(application)
            }
        }
        //获取数据库操作对象daoSession
        fun getGreenDaoObservable(): Observable<DaoSession> {
            return Observable.create { emitter ->
                daoSession.let {
                mDbFactory?.daoSession?.let {
                    emitter.onNext(it)
                    emitter.onComplete()
                }
@@ -33,7 +41,10 @@
        }
        fun getInstance(): DaoSession {
            return daoSession
            if (mDbFactory == null) {
                mDbFactory = DbFactory(CommonApplication.getInstance())
            }
            return mDbFactory!!.daoSession!!
        }
    }
}
app/src/main/java/cn/flightfeather/thirdapp/common/net/NetWorkProgressInterceptor.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package cn.flightfeather.thirdapp.common.net
import okhttp3.Interceptor
import okhttp3.Response
/**
 * @author riku
 * Date: 2020/4/24
 */
class NetWorkProgressInterceptor(private val netWorkProgressListener: NetWorkProgressListener) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        if (request.body() == null) {
            return chain.proceed(request)
        }
        val b = request.newBuilder()
            .method(
                request.method(),
                ProgressRequestBody(request.body(), netWorkProgressListener))
            .build()
        return chain.proceed(b)
    }
}
app/src/main/java/cn/flightfeather/thirdapp/common/net/NetWorkProgressListener.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
package cn.flightfeather.thirdapp.common.net
/**
 * @author riku
 * Date: 2020/4/24
 * ä¸Šä¼ ã€ä¸‹è½½è¿›åº¦ç›‘听接口
 */
interface NetWorkProgressListener {
    fun onProgress(progress: Long, total: Long)
}
app/src/main/java/cn/flightfeather/thirdapp/common/net/ProgressRequestBody.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package cn.flightfeather.thirdapp.common.net
import cn.flightfeather.thirdapp.common.net.NetWorkProgressListener
import okhttp3.MediaType
import okhttp3.RequestBody
import okio.*
/**
 * @author riku
 * Date: 2020/4/24
 * å¸¦è¿›åº¦å›žè°ƒçš„RequestBody
 */
class ProgressRequestBody(
    private val mRequestBody: RequestBody?,
    private val netWorkProgressListener: NetWorkProgressListener
) : RequestBody() {
    override fun contentType(): MediaType? = mRequestBody?.contentType()
    override fun contentLength(): Long = mRequestBody?.contentLength() ?: super.contentLength()
    override fun writeTo(sink: BufferedSink) {
        val progressSink = ProgressSink(sink)
        val newSink = Okio.buffer(progressSink)
        mRequestBody?.writeTo(newSink)
        newSink.flush()
    }
    inner class ProgressSink(delegate: Sink) : ForwardingSink(delegate) {
        private var bytesWritten = 0L
        override fun write(source: Buffer, byteCount: Long) {
            super.write(source, byteCount)
            bytesWritten += byteCount
            netWorkProgressListener.onProgress(bytesWritten, contentLength())
        }
    }
}
app/src/main/java/cn/flightfeather/thirdapp/common/net/ResponseBodyCallBack2.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package cn.flightfeather.thirdapp.common.net
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import cn.flightfeather.thirdapp.model.bean.BaseResponse
/**
 * @author riku
 * Date: 2020/8/4
 * ç›¸æ¯”于[ResponseBodyCallBack], å°†è¿”回结果用[BaseResponse]进行统一包装
 */
class ResponseBodyCallBack2<T>(private val resultCallBack: ResultCallBack2<T>?) : Callback<BaseResponse<T>> {
    override fun onFailure(p0: Call<BaseResponse<T>>, p1: Throwable) {
        resultCallBack?.onFailure("网络连接错误,请检查网络")
    }
    override fun onResponse(p0: Call<BaseResponse<T>>, p1: Response<BaseResponse<T>>) {
        if (p1.isSuccessful && p1.body()?.success == true) {
            resultCallBack?.onSuccess(p1.body()?.data, p1.body()?.message ?: "")
        } else {
            resultCallBack?.onFailure(p1.body()?.message ?: "")
        }
    }
}
app/src/main/java/cn/flightfeather/thirdapp/common/net/ResultCallBack2.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package cn.flightfeather.thirdapp.common.net
/**
 * @author riku
 * Date: 2019/4/24
 * æ•°æ®èŽ·å–ç»“æžœå›žè°ƒ
 * MVVM模式中,数据仓库(repository)管理所有的数据获取具体实现,提供此接口来实现数据获取各步骤中的方法回调
 */
interface ResultCallBack2<T> {
    /**
     * åˆ†é¡µä¿¡æ¯èŽ·å–
     * @param current å½“前页码(最小为1)
     * @param total æ€»é¡µæ•°
     */
    fun onPage(current: Int, total: Int) = Unit
    fun onSuccess(result: T?, message: String)
    fun onCacheSuccess(result: T?) = Unit
    fun onFailure(message:String)
}
app/src/main/java/cn/flightfeather/thirdapp/common/net/RetrofitFactory.kt
@@ -1,20 +1,54 @@
package cn.flightfeather.thirdapp.common.net
import cn.flightfeather.thirdapp.BuildConfig
import cn.flightfeather.thirdapp.CommonApplication
import com.google.gson.GsonBuilder
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
/**
 * @author riku
 * Date: 2019/7/22
 * ç½‘络请求
 */
class RetrofitFactory constructor(application: CommonApplication){
class RetrofitFactory constructor(val application: CommonApplication){
    val retrofit: Retrofit = application.retrofit
    val retrofitImage: Retrofit = application.retrofitImage
    private fun newOkHttpClient(list: List<Interceptor>): OkHttpClient =
            OkHttpClient.Builder()
                    .connectTimeout(20 * 1000L, TimeUnit.MILLISECONDS)
                    .apply {
                        list.forEach {
                            addInterceptor(it)
                        }
                    }
                    .build()
    private fun newRetrofit(mOkHttpClient: OkHttpClient): Retrofit =
            Retrofit.Builder()
                    .apply {
                        baseUrl(application.ROOT_URL_RELEASE)
                    }
                    .addConverterFactory(
                            GsonConverterFactory.create(
                                    GsonBuilder()
                                            .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
                                            .create()
                            )
                    )
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(mOkHttpClient)
                    .build()
    companion object {
@@ -35,5 +69,14 @@
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(subscriber)
        }
        fun withProgressListeningRetrofit(listener: NetWorkProgressListener?): Retrofit {
            return if (listener == null) {
                instance.retrofit
            } else {
                val c = instance.newOkHttpClient(listOf(NetWorkProgressInterceptor(listener)))
                instance.newRetrofit(c)
            }
        }
    }
}
app/src/main/java/cn/flightfeather/thirdapp/httpservice/MediaFileService.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package cn.flightfeather.thirdapp.httpservice
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Url
/**
 * @author riku
 * Date: 2020/8/6
 */
interface MediaFileService {
    @GET
    fun downloadImage(@Url fileUrl: String): Call<ResponseBody>
    @DELETE("mediafile/{MediaFileGUID}/ ")
    fun deleteMediaFile(@Path("MediaFileGUID") mediaFileGuid: String): Call<ResponseBody>
}
app/src/main/java/cn/flightfeather/thirdapp/httpservice/ProblemListService.java
@@ -1,18 +1,24 @@
package cn.flightfeather.thirdapp.httpservice;
import java.util.ArrayList;
import java.util.List;
import cn.flightfeather.thirdapp.bean.vo.AreaVo;
import cn.flightfeather.thirdapp.bean.vo.ChargeInfoVo;
import cn.flightfeather.thirdapp.bean.vo.ProblemDetailVo;
import cn.flightfeather.thirdapp.bean.vo.ProblemlistVo;
import cn.flightfeather.thirdapp.bean.vo.StatisticsVo;
import cn.flightfeather.thirdapp.model.bean.BaseResponse;
import io.reactivex.Observable;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;
/**
@@ -41,4 +47,13 @@
    //更新问题
    @POST("problemlist/")
    Call<ResponseBody> updateProblemList(@Body ProblemlistVo problemlistVo);
    @GET("problemtype/byScene")
    Observable<Response<ArrayList<ProblemDetailVo>>> getBySceneType(@Query("sceneTypeId") int sceneTypeId);
    /**
     * è®¾ç½®é—®é¢˜ä¸ºåˆ é™¤çŠ¶æ€
     */
    @POST("problemlist/{id}")
    Call<BaseResponse<Integer>> deleteProblem(@Path("id") String problemId);
}
app/src/main/java/cn/flightfeather/thirdapp/model/bean/BaseResponse.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package cn.flightfeather.thirdapp.model.bean
/**
 * @author riku
 * Date: 2020/8/4
 * ç½‘络请求返回数据基类
 */
data class BaseResponse<T>(
        val success: Boolean,
        val message: String,
        val data: T?
)
app/src/main/java/cn/flightfeather/thirdapp/module/base/BaseActivity.kt
@@ -1,7 +1,9 @@
package cn.flightfeather.thirdapp.module.base
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
@@ -25,8 +27,14 @@
    protected val disposableList = mutableListOf<Disposable>()
    @SuppressLint("SourceLockedOrientationActivity")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        try {
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        } catch (e: Exception) {
            e.printStackTrace()
        }
        setContentView(getLayoutId())
        rootView = findViewById<ViewGroup>(android.R.id.content).getChildAt(0) as ViewGroup
    }
app/src/main/java/cn/flightfeather/thirdapp/module/base/BaseTakePicActivity.kt
@@ -31,8 +31,8 @@
        const val EXTRA_SELECT_IMAGES = ImagePicker.EXTRA_SELECT_IMAGES
    }
    //拍摄的待上传的图片文件列表
    val pathTempList = mutableListOf<File>()
    //拍摄的待上传的图片文件列表, true: ä»£è¡¨éœ€è¦ä¸Šä¼ ï¼›false: ä»£è¡¨ä¸éœ€è¦ä¸Šä¼ 
    val pathTempList = mutableListOf<Pair<File, Boolean>>()
    // fixme: 2019/8/2  ç”±äºŽåŽŸä»£ç ä¸­å¤§éƒ¨åˆ†å›¾ç‰‡æ‹æ‘„å›ºå®šæ­»äº†æœ€å¤š3张,所以没有使用列表结构,而是手动设置了3个ImageView,此处暂时延用,不做修改
    var imageViewList = mutableListOf<ImageView>()
@@ -56,8 +56,8 @@
                //查看临时拍摄图片可以删除
                data?.getIntExtra("position", -1)?.let {
                    if (it > -1) {
                        if (pathTempList[it].exists()) {
                            pathTempList[it].delete()
                        if (pathTempList[it].first.exists()) {
                            pathTempList[it].first.delete()
                        }
                        pathTempList.removeAt(it)
                        refreshImageView()
@@ -74,7 +74,7 @@
                    }
                    try {
                        FileUtil.copyFile(oldFile, newFile)
                        pathTempList.add(newFile)
                        pathTempList.add(Pair(newFile, true))
                    } catch (e: IOException) {
                        e.printStackTrace()
                        application.toast("复制文件失败")
@@ -92,14 +92,17 @@
                i < picSize -> {
                    imageViewList[i].setOnClickListener(viewPhotoClickListener(i))
                    // fixme: 2019/8/2 æ­¤å¤„ç»™imageVIew设置图片在原代码中是自定义了一个AsyncTask,之后可以用Glide等第三方框架替代
                    SetImageTask(pathTempList[i], imageViewList[i]).execute()
                    imageViewList[i].scaleType = ImageView.ScaleType.CENTER_CROP
                    SetImageTask(pathTempList[i].first, imageViewList[i]).execute()
                }
                i == picSize -> imageViewList[i].run {
                    setOnClickListener(takePhotoClickListener(i))
                    scaleType = ImageView.ScaleType.FIT_CENTER
                    setImageResource(R.drawable.icon_add_photo)
                }
                else -> imageViewList[i].run {
                    setOnClickListener(null)
                    scaleType = ImageView.ScaleType.FIT_CENTER
                    setImageResource(R.drawable.icon_add_photo_blank)
                }
            }
@@ -109,11 +112,15 @@
    //有图片时,查看图片的点击事件(temp)
    fun viewPhotoClickListener(position: Int): View.OnClickListener {
        return View.OnClickListener {
            val fileList = mutableListOf<File>()
            pathTempList.forEach {
                fileList.add(it.first)
            }
            val intent = Intent(this, PhotoViewerActivity::class.java)
            intent.putExtra("position", position)
            intent.putExtra("type", PhotoViewerActivity.EVIDENCE_PHOTO_TEMP)
            intent.putExtra("deletable", picDeletable)
            intent.putExtra(PhotoViewerActivity.PARA_FILES, pathTempList as Serializable)
            intent.putExtra(PhotoViewerActivity.PARA_FILES, fileList as Serializable)
            startActivityForResult(intent, VIEW_PHOTO)
        }
    }
@@ -123,7 +130,7 @@
        return View.OnClickListener {
            val t = imageViewList.size - pathTempList.size
            val picNum = if (t >= 0) t else 0
            PhotoUtil.pickPhoto2(this, TAKE_PHOTO, picNum)
            PhotoUtil.pickPhoto(this, TAKE_PHOTO, picNum)
        }
    }
app/src/main/java/cn/flightfeather/thirdapp/module/common/CameraActivity.kt
@@ -98,7 +98,7 @@
    private fun initLocation() {
        locationUtil = LocationUtil(this)
        locationUtil.startLocation {
            val date = Date(it.time)
            val date = Date()
            val time = DateFormatter.dateTimeFormat3.format(date)
            val locationInfo = "经度: ${it.longitude}" +
                    "\n纬度: ${it.latitude}" +
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/BaseProblemListActivity.kt
@@ -10,9 +10,13 @@
import cn.flightfeather.thirdapp.adapter.ProblemListAdapter
import cn.flightfeather.thirdapp.adapter.RecyclerItemClickListener
import cn.flightfeather.thirdapp.bean.Inspection
import cn.flightfeather.thirdapp.bean.Scense
import cn.flightfeather.thirdapp.bean.Subtask
import cn.flightfeather.thirdapp.model.event.ProblemEvent
import cn.flightfeather.thirdapp.module.base.BaseActivity
import kotlinx.android.synthetic.main.dialog_problem_list.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
/**
 * @author riku
@@ -33,17 +37,21 @@
     */
    abstract var type: Int
    var subTaskSelected: Subtask? = null
    var inspection: Inspection? = null
    var lat: Double = 0.0
    var lng: Double = 0.0
    protected var subTaskSelected: Subtask? = null
    protected var inspection: Inspection? = null
    protected var scene: Scense? = null
    protected var lat: Double = 0.0
    protected var lng: Double = 0.0
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        EventBus.getDefault().register(this)
        viewModel = ViewModelProviders.of(this).get(BaseProblemListViewModel::class.java)
        subTaskSelected = intent.getSerializableExtra("subTask") as Subtask?
        inspection = intent.getSerializableExtra("inspection") as Inspection?
        scene = intent.getSerializableExtra("scene") as Scense?
        lat = intent.getDoubleExtra("lat", 0.0)
        lng = intent.getDoubleExtra("lng", 0.0)
@@ -67,6 +75,7 @@
                }
                override fun onItemLongClick(view: View?, position: Int) {
                    onItemViewLongClick(view, position)
                }
            }))
@@ -74,10 +83,10 @@
        tv_title.text = when (type) {
            InspectionDetailActivity.PROBLEM_LIST -> "问题清单"
            InspectionDetailActivity.PROBLEM_CHECK -> "问题审核"
            InspectionDetailActivity.CHANGE_CHECK -> "整改审核"
            InspectionDetailActivity.PROBLEM_CHANGE -> "现场整改"
            InspectionDetailActivity.PROBLEM_RECHECK -> "问题复核"
            InspectionDetailActivity.PROBLEM_CHECK -> "问题审核"
            InspectionDetailActivity.CHANGE_CHECK -> "整改审核"
            else -> ""
        }
@@ -85,4 +94,13 @@
            finish()
        }
    }
    open fun onItemViewLongClick(view: View?, position: Int) {
    }
    @Subscribe
    fun onPutProblem(problemEvent: ProblemEvent) {
        viewModel.getProblems(inspection?.guid)
    }
}
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/BaseProblemListViewModel.kt
@@ -5,9 +5,14 @@
import cn.flightfeather.thirdapp.bean.Subtask
import cn.flightfeather.thirdapp.bean.vo.ProblemlistVo
import cn.flightfeather.thirdapp.common.net.ResultCallBack
import cn.flightfeather.thirdapp.common.net.ResultCallBack2
import cn.flightfeather.thirdapp.model.event.ProblemEvent
import cn.flightfeather.thirdapp.module.base.BaseViewModel
import cn.flightfeather.thirdapp.repository.InspectionRepository
import cn.flightfeather.thirdapp.repository.ProblemRepository
import cn.flightfeather.thirdapp.util.DateFormatter
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.toast
/**
 * @author riku
@@ -16,6 +21,7 @@
class BaseProblemListViewModel : BaseViewModel() {
    private val inspectionRepository = InspectionRepository()
    private val problemRepository = ProblemRepository()
    var problemList = MutableLiveData<ArrayList<ProblemlistVo>>().apply { value = ArrayList() }
@@ -67,4 +73,24 @@
            })
        }
    }
    /**
     * åˆ é™¤é—®é¢˜
     */
    fun deleteProblem(position: Int, s: () -> Unit) {
        problemList.value?.get(position)?.let {
            problemRepository.deleteProblem(it.guid ?: "", object : ResultCallBack2<Int> {
                override fun onSuccess(result: Int?, message: String) {
                    if (result != null) {
                        EventBus.getDefault().post(ProblemEvent(it.voToEntity(), InspectionDetailActivity.PROBLEM_DELETE))
                        s()
                    }
                }
                override fun onFailure(message: String) {
                    application.toast(message)
                }
            })
        }
    }
}
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/InspectionDetailActivity.kt
@@ -58,7 +58,10 @@
        const val PROBLEM_RECHECK = 102//问题复核
        const val PROBLEM_CHECK = 103//问题审核
        const val CHANGE_CHECK = 104//整改审核
        const val PROBLEM_DELETE = 105
    }
    private var taskStatus: String = Domain.TASK_STATUS_FINISHED
    /**
     * åŠ è½½å®ŒæˆçŠ¶æ€ï¼Œ
@@ -133,9 +136,10 @@
        iv_patrol_back.setOnClickListener(this)
        ll_patrol_task_detail.visibility = View.GONE
        hideMenu()
        viewModel.inspection.observe(this, Observer {
            it?.apply {
                showMenu()
                if (extension1 != null) {
                    val list = extension1.split(";").map{str ->
                        str.split(",").map {str2 ->
@@ -162,7 +166,7 @@
        viewModel.subTask.observe(this, Observer {
            it?.let {
                updateUIBySubTask(it)
                refreshMenuStatus(it.status)
                taskStatus = it.status
                onDataLoaded(1)
            }
        })
@@ -325,9 +329,8 @@
            result = result.and(it)
        }
        if (result) {
            menuList.forEach {
                it.setOnClickListener(this)
            }
            showMenu()
            refreshMenuStatus(taskStatus)
        } else {
            toast("请等待数据加载完成")
        }
@@ -385,7 +388,7 @@
        val address = s.cityname + s.districtname + " " + s.location
        tv_scense_address.text = address
        val contact1 = s.contacts + " " + s.contactst
        val contact1 = s.contacts ?: "" + " " + s.contactst ?: ""
        tv_scense_contact1.text = contact1
        tv_call_contact1.setOnClickListener {
            //打电话
@@ -569,8 +572,10 @@
    }
    private fun startTracking() {
        if (viewModel.scene.value?.typeid?.toString() != Constant.SCENE_TYPE9
                || viewModel.subTask.value?.status != Domain.TASK_STATUS_RUNNING) return
        if (
//                viewModel.scene.value?.typeid?.toString() != Constant.SCENE_TYPE9 ||
                viewModel.subTask.value?.status != Domain.TASK_STATUS_RUNNING
        ) return
        //当继续执行正在进行中的任务时,根据是否有历史轨迹记录来判断是否开启
        if (viewModel.inspection.value?.extension1 != null) {
@@ -716,8 +721,9 @@
                val intent = Intent(this, MenuProblemListActivity::class.java).apply {
                    putExtra("subTask", viewModel.subTask.value)
                    putExtra("inspection", viewModel.inspection.value)
                    putExtra("scenseLat", viewModel.scene.value?.latitude)
                    putExtra("scenseLng", viewModel.scene.value?.longitude)
                    putExtra("scene", viewModel.scene.value)
                    putExtra("lat", viewModel.scene.value?.latitude)
                    putExtra("lng", viewModel.scene.value?.longitude)
                }
                startActivity(intent)
            }
@@ -726,8 +732,8 @@
                val intent = Intent(this, MenuChangeActivity::class.java).apply {
                    putExtra("subTask", viewModel.subTask.value)
                    putExtra("inspection", viewModel.inspection.value)
                    putExtra("scenseLat", viewModel.scene.value?.latitude)
                    putExtra("scenseLng", viewModel.scene.value?.longitude)
                    putExtra("lat", viewModel.scene.value?.latitude)
                    putExtra("lng", viewModel.scene.value?.longitude)
                }
                startActivity(intent)
            }
@@ -835,7 +841,7 @@
                }
                startActivity(intent)
            }
            //问题审核
            //整改审核
            R.id.ln_patrol_change_check -> {
                val intent = Intent(this, MenuChangeCheckActivity::class.java).apply {
                    putExtra("subTask", viewModel.subTask.value)
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuChangeActivity.kt
@@ -46,7 +46,7 @@
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    fun onUpdateChange(problemEvent: ProblemEvent) {
        if (problemEvent.type == InspectionFragment.PROBLEM_CHANGE) {
        if (problemEvent.type == InspectionDetailActivity.PROBLEM_CHANGE) {
            inspection?.apply {
                changednum = changednum?.plus(1) ?: 1
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuEvidenceActivity.kt
@@ -27,12 +27,11 @@
import java.io.IOException
import java.util.*
class MenuEvidenceActivity : BaseTakePicActivity() {
open class MenuEvidenceActivity : BaseTakePicActivity() {
    override fun getLayoutId(): Int = R.layout.dialog_take_evidence
    override fun getImageViews(): MutableList<ImageView>
            = mutableListOf(iv_take_evidence_add_photo1, iv_take_evidence_add_photo2, iv_take_evidence_add_photo3)
    override fun getImageViews(): MutableList<ImageView> = mutableListOf(iv_take_evidence_add_photo1, iv_take_evidence_add_photo2, iv_take_evidence_add_photo3)
    override val picDeletable: Boolean = true
@@ -44,6 +43,7 @@
    var lat = 0.0
    var lng = 0.0
    protected var submitTime = 0L//提交时间,防止连续提交,多次记录
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
@@ -53,46 +53,25 @@
        viewModel = ViewModelProviders.of(this).get(MenuEvidenceViewModel::class.java)
        getExtra()
        initUI()
        initObserver()
        viewModel.getLocationList()
        subTask?.let { t ->
            scene?.let { s ->
                viewModel.getProblemType(t.typeno, t.citycode, t.districtcode, s.typeid)
            }
        }
    }
    open fun getExtra() {
        subTask = intent.getSerializableExtra("subTask") as Subtask?
        inspection = intent.getSerializableExtra("inspection") as Inspection?
        scene = intent.getSerializableExtra("scene") as Scense?
        lat = intent.getDoubleExtra("lat", 0.0)
        lng = intent.getDoubleExtra("lng", 0.0)
        initUI()
        viewModel.locationList.observe(this, Observer {
            it?.let {
                sp_take_evidence_select_location.adapter = DomainItemListAdapter(it, this)
            }
        })
        viewModel.problemFatherType.observe(this, Observer {
            it?.let {
                sp_take_evidence_select_problem_type.adapter = ArrayAdapter(this, R.layout.item_spinner_drop_down, it)
            }
        })
        viewModel.problemType.observe(this, Observer {
            it?.let {
                sp_take_evidence_select_problem.adapter = ProblemTypeListAdapter(it, this)
            }
        })
        viewModel.suggestionList.observe(this, Observer {
            it.let {
                sp_take_evidence_select_suggestion.adapter = ArrayAdapter(this, R.layout.item_spinner_drop_down, it)
            }
        })
        viewModel.getLocationList()
        subTask?.let {t ->
            scene?.let {s ->
                viewModel.getProblemType(t.typeno, t.citycode, t.districtcode, s.typeid)
            }
        }
    }
    private fun initUI() {
@@ -122,8 +101,11 @@
        }
        fab_take_evidence_ok.setOnClickListener {
            it.isClickable = false
            putProblem()
            val now = Date()
            if (now.time - submitTime >= 1000) {
                submitTime = now.time
                putProblem()
            }
        }
        fab_take_evidence_close.setOnClickListener {
@@ -131,7 +113,33 @@
        }
    }
    private fun updateUIByProblemType(visible: Int) {
    open fun initObserver() {
        viewModel.locationList.observe(this, Observer {
            it?.let {
                sp_take_evidence_select_location.adapter = DomainItemListAdapter(it, this)
            }
        })
        viewModel.problemFatherType.observe(this, Observer {
            it?.let {
                sp_take_evidence_select_problem_type.adapter = ArrayAdapter(this, R.layout.item_spinner_drop_down, it)
            }
        })
        viewModel.problemType.observe(this, Observer {
            it?.let {
                sp_take_evidence_select_problem.adapter = ProblemTypeListAdapter(it, this)
            }
        })
        viewModel.suggestionList.observe(this, Observer {
            it.let {
                sp_take_evidence_select_suggestion.adapter = ArrayAdapter(this, R.layout.item_spinner_drop_down, it)
            }
        })
    }
    protected fun updateUIByProblemType(visible: Int) {
        sp_take_evidence_select_location.visibility = visible
        et_take_evidence_location.visibility = visible
        iv_take_evidence_add_photo1.visibility = visible
@@ -141,6 +149,10 @@
    }
    private fun putProblem() {
        if (inspection == null || subTask == null || scene == null) {
            toast("当前巡查状态错误,无法上传问题,请尝试重新启动")
        }
        val problemType = sp_take_evidence_select_problem_type.selectedItem.toString()
        val pro = Problemlist().apply {
@@ -150,6 +162,7 @@
            sguid = scene?.guid
            sensename = scene?.name
            senseaddress = "${scene?.cityname ?: ""}${scene?.districtname ?: ""}${scene?.townname ?: ""}${scene?.location ?: ""}"
            val p = sp_take_evidence_select_problem.selectedItem
            if (p is Problemtype) {
                ptguid = p.guid
@@ -191,7 +204,7 @@
        if (problemType != "态度" && pathTempList.isNotEmpty()) {
            viewModel.putProblem(pro)
            putMediaFile(pro)
        }else if (problemType == "态度") {
        } else if (problemType == "态度") {
            viewModel.putProblem(pro)
        } else {
            application.toast("至少拍一张照片")
@@ -199,7 +212,7 @@
        }
    }
    private fun putMediaFile(problem: Problemlist) {
    protected fun putMediaFile(problem: Problemlist) {
        //保存照片到对应文件夹
        val savePathList = ArrayList<File>()
        val calendar = java.util.Calendar.getInstance()
@@ -223,7 +236,11 @@
        fileNameList.add(fileName3)
        for (i in pathTempList.indices) {
            val oldFile = pathTempList[i]
            //过滤不需要上传的图片
            if (!pathTempList[i].second) {
                continue
            }
            val oldFile = pathTempList[i].first
            val newFile = savePathList[i]
            //保存到mediaFile数据库
            val mediaFile = Mediafile()
@@ -261,11 +278,14 @@
    }
    //清除拍照取证的缓存
    fun clearTemp() {
    private fun clearTemp() {
        for (i in pathTempList.indices) {
            val file = pathTempList[i]
            if (file.exists()) {
                file.delete()
            //需要上传的图片才是在本地拍摄的,带有缓存
            if (pathTempList[i].second) {
                val file = pathTempList[i].first
                if (file.exists()) {
                    file.delete()
                }
            }
        }
    }
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuEvidenceViewModel.kt
@@ -2,6 +2,7 @@
import android.arch.lifecycle.MutableLiveData
import cn.flightfeather.thirdapp.bean.*
import cn.flightfeather.thirdapp.bean.vo.ProblemlistVo
import cn.flightfeather.thirdapp.common.net.ResultCallBack
import cn.flightfeather.thirdapp.model.event.ProblemEvent
import cn.flightfeather.thirdapp.module.base.BaseViewModel
@@ -9,6 +10,7 @@
import okhttp3.ResponseBody
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.toast
import java.io.File
/**
 * @author riku
@@ -31,6 +33,13 @@
    val problemMap = HashMap<String, ArrayList<Problemtype>>()
    val mediaFileList = MutableLiveData<List<Mediafile>>()
    //所有数据加载完成通知
    val loadingOver = MutableLiveData<Boolean>()
    //记录各个数据加载是否完成的状态
    private val loadingStatus = BooleanArray(3)
    /**
     * èŽ·å–åœºæ™¯é—®é¢˜å¯é€‰ä½ç½®ï¼ˆç›®å‰åªæœ‰å·¥åœ°ï¼Œä½†æ‰€æœ‰åœºæ™¯éƒ½ä½¿ç”¨ï¼‰
     */
@@ -39,6 +48,7 @@
            override fun onSuccess(result: ArrayList<Domainitem>?) {
                result?.let {
                    locationList.value = it
                    onLoaded(0)
                }
            }
@@ -59,8 +69,8 @@
                    if (it.isEmpty()) {
                        it.add(Problemtype().apply {
                            guid = "0"
                            typename = "无"
                            name = "无"
                            typename = "其他"
                            name = "其他"
                        })
                    }
@@ -76,6 +86,8 @@
                    }
                    problemFatherType.value = typeList
                    onLoaded(1)
                }
            }
@@ -98,6 +110,8 @@
                    }
                    advices.add("暂无建议")
                    suggestionList.value = advices
                    onLoaded(2)
                }
            }
@@ -105,6 +119,57 @@
            }
        })
    }
    /**
     * æ ¹æ®é—®é¢˜æ‰¾åˆ°æœåŠ¡å™¨å’Œæœ¬åœ°çš„æ‰€æœ‰å›¾ç‰‡
     */
    fun getMediaFileList(p: ProblemlistVo) {
        problemRepository.getMediaFileLocal(p.guid, object : ResultCallBack<List<Mediafile>> {
            override fun onSuccess(result: List<Mediafile>?) {
                result?.let {
                    p.mediafileList.addAll(it)
                    mediaFileList.value = p.mediafileList
                }
            }
            override fun onFailure() {
            }
        })
    }
    /**
     * ä¸‹è½½é—®é¢˜å›¾ç‰‡
     *  fixme: 2020/8/6 ç›®å‰ç”±äºŽåŽŸç¨‹åºè®¾ç½®å›¾ç‰‡çš„æ–¹å¼ä¸ºæ‰‹åŠ¨ä¸‹è½½å›¾ç‰‡ï¼Œå› æ­¤æ²¿ç”¨ï¼Œä¹‹åŽç»Ÿä¸€ç”¨Glide等第三方库代替
     */
    fun downLoadMediaFile(mediaFile: Mediafile, s: (file: File) -> Unit) {
        problemRepository.downloadMediaFile(mediaFile, object : ResultCallBack<File> {
            override fun onSuccess(result: File?) {
                result?.let {
                    s(it)
                }
            }
            override fun onFailure() {
            }
        })
    }
    /**
     * åˆ é™¤é—®é¢˜å›¾ç‰‡
     */
    fun deleteMediaFile(mediaFile: List<Mediafile>) {
        mediaFile.forEach {
            problemRepository.deleteMediaFile(it, object : ResultCallBack<Boolean> {
                override fun onSuccess(result: Boolean?) {
                }
                override fun onFailure() {
                }
            })
        }
    }
    /**
@@ -124,6 +189,24 @@
                application.toast("提交失败")
            }
        })
    }
    /**
     * æ›´æ–°ä¸€ä¸ªé—®é¢˜
     */
    fun updateProblem(problem: ProblemlistVo) {
        problemRepository.updateProblem(problem, object : ResultCallBack<ResponseBody> {
            override fun onSuccess(result: ResponseBody?) {
                result?.let {
                    application.toast("修改成功")
                    EventBus.getDefault().post(ProblemEvent(problem.voToEntity()))
                }
            }
            override fun onFailure() {
                application.toast("修改失败,请检查网络")
            }
        })
    }
@@ -151,4 +234,23 @@
            problemType.value = it
        }
    }
    /**
     * åˆ¤æ–­æ˜¯å¦æ‰€æœ‰çš„æ•°æ®éƒ½åŠ è½½å®Œæˆ
     */
    fun onLoaded(i: Int) {
        if (i < loadingStatus.size) {
            loadingStatus[i] = true
        }
        var isLoadOver = true
        loadingStatus.forEach {
            isLoadOver = isLoadOver.and(it)
        }
        if (isLoadOver) {
            loadingOver.value = isLoadOver
            for (y in loadingStatus.indices) {
                loadingStatus[y] = false
            }
        }
    }
}
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuNewGitActivity.kt
@@ -227,7 +227,8 @@
                    override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                        if (response.body() != null) {
                            Toast.makeText(application, "提交成功", Toast.LENGTH_SHORT).show()
                            for (oldfile in pathTempList) {
                            for (l in pathTempList) {
                                val oldfile = l.first
                                val fileName = gitSelected.name + " " + UUIDGenerator.generateUUID(4) + ".jpg"
                                val mediafile = Mediafile()
                                mediafile.guid = UUIDGenerator.generate16ShortUUID()
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuProblemListActivity.kt
@@ -1,8 +1,12 @@
package cn.flightfeather.thirdapp.module.inspection
import android.app.Dialog
import android.arch.lifecycle.Observer
import android.content.Intent
import android.os.Bundle
import android.view.View
import cn.flightfeather.thirdapp.adapter.ProblemListAdapter
import cn.flightfeather.thirdapp.util.DialogUtil2
import kotlinx.android.synthetic.main.dialog_problem_list.*
class MenuProblemListActivity : BaseProblemListActivity() {
@@ -31,4 +35,30 @@
        viewModel.getProblems(inspection?.guid)
    }
    override fun onItemViewLongClick(view: View?, position: Int) {
        super.onItemViewLongClick(view, position)
        DialogUtil2.showBottomDialog(this, rootView, listOf("修改", "删除"), listOf ({ p->
            val intent = Intent(this, MenuProblemUpdateActivity::class.java).apply {
                putExtra("problemlistVo", viewModel.problemList.value?.get(position))
                putExtra("subTask", subTaskSelected)
                putExtra("inspection", inspection)
                putExtra("scene", scene)
                putExtra("lat", lat)
                putExtra("lng", lng)
            }
            startActivity(intent)
            p.dismiss()
        }, {p->
            p.dismiss()
            DialogUtil2.showAlertDialog(this, "确认是否删除问题?", { dialog: Dialog ->
                viewModel.deleteProblem(position) {
                    viewModel.getProblems(inspection?.guid)
                }
                dialog.dismiss()
            }) { dialog: Dialog ->
                dialog.dismiss()
            }
        }))
    }
}
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuProblemUpdateActivity.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,254 @@
package cn.flightfeather.thirdapp.module.inspection
import android.arch.lifecycle.Observer
import android.content.Intent
import android.os.Bundle
import android.os.Environment
import android.view.View
import android.widget.AdapterView
import cn.flightfeather.thirdapp.bean.Domainitem
import cn.flightfeather.thirdapp.bean.Mediafile
import cn.flightfeather.thirdapp.bean.Problemtype
import cn.flightfeather.thirdapp.bean.vo.ProblemlistVo
import cn.flightfeather.thirdapp.module.base.VIEW_PHOTO
import kotlinx.android.synthetic.main.dialog_take_evidence.*
import org.jetbrains.anko.toast
import java.io.File
import java.util.*
/**
 * @author riku
 * Date: 2020/8/6
 * é—®é¢˜å†…容修改
 */
class MenuProblemUpdateActivity : MenuEvidenceActivity() {
    private var problemVo: ProblemlistVo? = null
    private val deleteMediaFileList = mutableListOf<Mediafile>()
    //修改前的问题名称
    private var originProblemName = ""
    private var firstLoad = true
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        tv_dialog_take_evidence_title.text = "问题修改"
        fab_take_evidence_ok.setOnClickListener {
            val now = Date()
            if (now.time - submitTime >= 1000) {
                submitTime = now.time
                updateProblem()
            }
        }
        problemVo?.let {
            viewModel.getMediaFileList(it)
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            VIEW_PHOTO -> {
                //查看临时拍摄图片可以删除
                data?.getIntExtra("position", -1)?.let {
                    if (it > -1) {
                        viewModel.mediaFileList.value?.get(it)?.let {m ->
                            deleteMediaFileList.add(m)
                        }
                    }
                }
            }
        }
    }
    override fun getExtra() {
        super.getExtra()
        problemVo = intent.getSerializableExtra("problemlistVo") as ProblemlistVo
    }
    override fun initObserver() {
        super.initObserver()
        viewModel.loadingOver.observe(this, Observer {
            if (it == true && problemVo != null) {
                //问题类型 å’Œ é—®é¢˜è¯¦æƒ…
                var problemType = ""
                val problemTypeId = problemVo!!.ptguid
                with(viewModel.problemMap) breaking@{
                    forEach { entry ->
                        entry.value.forEach { pt ->
                            if (pt.guid == problemTypeId) {
                                problemType = entry.key
                                originProblemName = pt.name
                                setSelectListener()
                                return@breaking
                            }
                        }
                    }
                }
                for (i in viewModel.problemFatherType.value?.indices ?: 0..0) {
                    if (viewModel.problemFatherType.value?.get(i) == problemType) {
                        sp_take_evidence_select_problem_type.setSelection(i)
                        break
                    }
                }
                //问题描述
                var problemRemark = problemVo!!.problemname.replace(originProblemName, "")//删除描述中的问题类型
                if (problemRemark.isNotBlank()) {
                    problemRemark = problemRemark.removeRange(0, 1)//删除第一个字符,括号“(”
                    problemRemark = problemRemark.dropLast(1)//删除最后一个字符,括号“)”
                }
                et_take_evidence_problem_des.setText(problemRemark)
                //位置
                var location = problemVo!!.location
                for (i in viewModel.locationList.value?.indices ?: 0..0) {
                    val d = viewModel.locationList.value?.get(i)?.text
                    if (d != null && location.contains(d)) {
                        location = location.replace(d, "")
                        sp_take_evidence_select_location.setSelection(i)
                        break
                    }
                }
                //位置备注
                var locationRemark = location
                if (locationRemark.isNotBlank()) {
                    locationRemark = location.removeRange(0, 1)//删除第一个字符,括号“(”
                    locationRemark = locationRemark.dropLast(1)//删除最后一个字符,括号“)”
                }
                et_take_evidence_location.setText(locationRemark)
                //整改建议
                var advice = problemVo!!.advise
                var suggestion = ""
                for (i in viewModel.suggestionList.value?.indices ?: 0..0) {
                    val s = viewModel.suggestionList.value?.get(i)
                    if (s != null && advice.contains(s)) {
                        advice = advice.replace(s, "")
                        sp_take_evidence_select_suggestion.setSelection(i)
                        break
                    }
                }
                //整改建议备注
                var suggestionRemark = advice.removeRange(0, 1)//删除第一个字符,括号“(”
                suggestionRemark = suggestionRemark.dropLast(1)//删除最后一个字符,括号“)”
                et_take_evidence_suggestion.setText(suggestionRemark)
            }
        })
        viewModel.mediaFileList.observe(this, Observer {
            it?.let { loadImage(it) }
        })
    }
    private fun loadImage(mediaFileList: List<Mediafile>) {
        mediaFileList.forEach {
            if (!it.ischanged) {
                val file = getFileFromMediaFile(it)
                if (file?.exists() == true) {
                    pathTempList.add(Pair(file, false))
                } else {
                    viewModel.downLoadMediaFile(it) {f ->
                        pathTempList.add(Pair(f, false))
                        refreshImageView()
                    }
                }
            }
        }
        refreshImageView()
    }
    private fun getFileFromMediaFile(mediafile: Mediafile): File? {
        return File(Environment.getExternalStorageDirectory(), mediafile.path + mediafile.description)
    }
    private fun updateProblem() {
        val problemType = sp_take_evidence_select_problem_type.selectedItem.toString()
        problemVo?.apply {
            val p = sp_take_evidence_select_problem.selectedItem
            if (p is Problemtype) {
                ptguid = p.guid
                var problemDes = et_take_evidence_problem_des.text.toString()
                if (problemDes.isNotEmpty()) {
                    problemDes = "($problemDes)"
                }
                problemname = p.name + problemDes
            }
            var adviceDes = et_take_evidence_suggestion.text.toString()
            if (adviceDes.isNotEmpty()) {
                adviceDes = "($adviceDes)"
            }
            advise = sp_take_evidence_select_suggestion.selectedItem.toString() + adviceDes
            latitude = lat
            longitude = lng
            val d = sp_take_evidence_select_location.selectedItem
            if (d is Domainitem) {
                var locationRemark = et_take_evidence_location.text.toString()
                if (locationRemark.isNotEmpty()) {
                    locationRemark = "($locationRemark)"
                }
                // fixme: 2020/6/9 æ­¤ç‰ˆæœ¬å°†é—®é¢˜ä½ç½®ä¿®æ”¹ä¸ºè¡—道信息,暂时去除位置id
                locationid = d.index.toByte()
                location = d.text + locationRemark
            }
            time = Date()
            if (problemType != "态度" && pathTempList.isNotEmpty()) {
                viewModel.updateProblem(this)
                putMediaFile(this.voToEntity())
                deleteMediaFile()
            }else if (problemType == "态度") {
                viewModel.updateProblem(this)
                deleteMediaFile()
            } else {
                application.toast("至少拍一张照片")
                fab_take_evidence_ok.isClickable = true
            }
        }
    }
    private fun deleteMediaFile() {
        viewModel.deleteMediaFile(deleteMediaFileList)
    }
    private fun setSelectListener() {
        sp_take_evidence_select_problem_type.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onNothingSelected(parent: AdapterView<*>?) = Unit
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                val problemType = viewModel.problemFatherType.value?.get(position)
                viewModel.refreshProblems(problemType)
                viewModel.problemFatherType.value?.let {
                    if (it[position] == "态度") {
                        updateUIByProblemType(View.GONE)
                    } else {
                        updateUIByProblemType(View.VISIBLE)
                    }
                }
                val problemNameList = viewModel.problemMap[problemType] ?: arrayListOf()
                for (i in problemNameList.indices) {
                    if (problemNameList[i].name == originProblemName) {
                        sp_take_evidence_select_problem.setSelection(i)
                        break
                    }
                }
                viewModel.problemType.value?.get(0)?.guid?.let { viewModel.getSuggestionList(it) }
            }
        }
    }
}
app/src/main/java/cn/flightfeather/thirdapp/module/inspection/MenuRecheckActivity.kt
@@ -28,8 +28,6 @@
    var totalProblemCount = 0
    override fun onCreate(savedInstanceState: Bundle?) {
        EventBus.getDefault().register(this)
        super.onCreate(savedInstanceState)
        viewModel.subTaskPack.observe(this, Observer {
@@ -71,7 +69,7 @@
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    fun onUpdateRecheck(problemEvent: ProblemEvent) {
        if (problemEvent.type == InspectionFragment.PROBLEM_RECHECK) {
        if (problemEvent.type == InspectionDetailActivity.PROBLEM_RECHECK) {
            inspection?.apply {
                recheckcount = recheckcount?.plus(1) ?: 1
app/src/main/java/cn/flightfeather/thirdapp/repository/CommonRepository.kt
@@ -28,6 +28,10 @@
            .upLoadCrashInfo(accountName, partList)
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.trampoline())
            .subscribe()
            .subscribe({
                resultCallBack.onSuccess(it.body())
            }, {
                resultCallBack.onFailure()
            })
    }
}
app/src/main/java/cn/flightfeather/thirdapp/repository/ProblemRepository.kt
@@ -1,16 +1,26 @@
package cn.flightfeather.thirdapp.repository
import android.annotation.SuppressLint
import android.os.Environment
import cn.flightfeather.thirdapp.bean.*
import cn.flightfeather.thirdapp.common.net.ResponseBodyCallBack
import cn.flightfeather.thirdapp.common.net.ResultCallBack
import cn.flightfeather.thirdapp.common.net.ResultObserver
import cn.flightfeather.thirdapp.common.net.RetrofitFactory
import cn.flightfeather.thirdapp.bean.vo.ProblemlistVo
import cn.flightfeather.thirdapp.common.net.*
import cn.flightfeather.thirdapp.httpservice.InspectionService
import cn.flightfeather.thirdapp.httpservice.MediaFileService
import cn.flightfeather.thirdapp.httpservice.ProblemListService
import cn.flightfeather.thirdapp.repository.dao.DomainDao
import cn.flightfeather.thirdapp.repository.dao.MediaFileDao
import cn.flightfeather.thirdapp.repository.dao.ProblemTypeDao
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
/**
 * @author riku
@@ -20,6 +30,7 @@
class ProblemRepository {
    val retrofit = RetrofitFactory.instance.retrofit
    val retrofitImage = RetrofitFactory.instance.retrofitImage
    private val domainDao = DomainDao()
    private val problemTypeDao = ProblemTypeDao()
    private val mediaFileDao = MediaFileDao()
@@ -93,6 +104,14 @@
    }
    /**
     * æ›´æ–°é—®é¢˜
     */
    fun updateProblem(problem: ProblemlistVo, resultCallBack: ResultCallBack<ResponseBody>) {
        retrofit.create(ProblemListService::class.java).updateProblemList(problem)
                .enqueue(ResponseBodyCallBack(resultCallBack))
    }
    /**
     * å›¾ç‰‡æœ¬åœ°ç¼“å­˜
     */
    fun putMediaFileLocal(mediaFile: Mediafile, resultCallBack: ResultCallBack<Int>) {
@@ -111,4 +130,128 @@
        })
    }
    /**
     * èŽ·å–æœ¬åœ°ç¼“å­˜çš„å›¾ç‰‡
     */
    fun getMediaFileLocal(problemGuid: String, resultCallBack: ResultCallBack<List<Mediafile>>) {
        val dbService = mediaFileDao.getMediaFileByProblemId(problemGuid).map {
            Response.success(it)
        }
        RetrofitFactory.executeResult(dbService, object : ResultObserver<List<Mediafile>>() {
            override fun onSuccess(result: List<Mediafile>?) {
                resultCallBack.onSuccess(result)
            }
            override fun onFailure(e: Throwable, isNetWorkError: Boolean) {
                resultCallBack.onFailure()
            }
        })
    }
    /**
     * ä¸‹è½½é—®é¢˜å›¾ç‰‡
     */
    fun downloadMediaFile(mediaFile:Mediafile, resultCallBack: ResultCallBack<File>) {
        val url: String = mediaFile.extension1 + mediaFile.guid + ".jpg"
        retrofitImage.create(MediaFileService::class.java).downloadImage(url)
                .enqueue(object : Callback<ResponseBody> {
                    override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                        resultCallBack.onFailure()
                    }
                    override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                        if (response.body() != null) {
                            val file = writeResponseBodyToDisk(mediaFile, response.body())
                            if (file?.exists() == true) {
                                resultCallBack.onSuccess(file)
                            } else {
                                resultCallBack.onFailure()
                            }
                        } else {
                            resultCallBack.onFailure()
                        }
                    }
                })
    }
    /**
     * åˆ é™¤é—®é¢˜å›¾ç‰‡
     */
    @SuppressLint("CheckResult")
    fun deleteMediaFile(mediaFile: Mediafile, resultCallBack: ResultCallBack<Boolean>) {
        if (mediaFile.remark == "未上传") {
            mediaFileDao.deleteMediaFile(mediaFile.guid)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe{
                        if (it) {
                            resultCallBack.onSuccess(it)
                        }
                    }
        } else if (mediaFile.remark == "已上传") {
            retrofit.create(MediaFileService::class.java).deleteMediaFile(mediaFile.guid)
                    .enqueue(object : Callback<ResponseBody?> {
                        override fun onResponse(call: Call<ResponseBody?>, response: Response<ResponseBody?>) {
                            if (response.body() != null) {
                                mediaFileDao.deleteMediaFile(mediaFile.guid)
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe{
                                            if (it) {
                                                resultCallBack.onSuccess(it)
                                            }
                                        }
                            } else if (response.errorBody() != null) {
                                resultCallBack.onFailure()
                            }
                        }
                        override fun onFailure(call: Call<ResponseBody?>, t: Throwable) {
                            resultCallBack.onFailure()
                        }
                    })
        }
    }
    /**
     * åˆ é™¤é—®é¢˜
     */
    fun deleteProblem(problemId: String, resultCallBack: ResultCallBack2<Int>) {
        retrofit.create(ProblemListService::class.java).deleteProblem(problemId)
                .enqueue(ResponseBodyCallBack2(resultCallBack))
    }
    //将下载的图片写入磁盘
    private fun writeResponseBodyToDisk(mediafile: Mediafile, body: ResponseBody?): File? {
        if (body == null) {
            return null
        }
        return try {
            val `is` = body.byteStream()
            var file = File(Environment.getExternalStorageDirectory(), mediafile.path + mediafile.description)
            if (file.exists()) {
                file.delete()
                file = File(Environment.getExternalStorageDirectory(), mediafile.path + mediafile.description)
            }
            file.parentFile.mkdirs()
            val fos = FileOutputStream(file)
            val bis = BufferedInputStream(`is`)
            val buffer = ByteArray(1024)
            var len: Int
            while (bis.read(buffer).also { len = it } != -1) {
                fos.write(buffer, 0, len)
            }
            fos.flush()
            fos.close()
            bis.close()
            `is`.close()
            file
        } catch (e: IOException) {
            e.printStackTrace()
            null
        }
    }
}
app/src/main/java/cn/flightfeather/thirdapp/repository/dao/MediaFileDao.kt
@@ -48,4 +48,26 @@
                    ).list()
        }
    }
    /**
     * æ ¹æ®é—®é¢˜id获取对应的相关图片
     */
    fun getMediaFileByProblemId(problemId: String): Observable<List<Mediafile>> {
        return DbFactory.getGreenDaoObservable().map {
            it.mediafileDao.queryBuilder().where(
                    MediafileDao.Properties.Businessguid.eq(problemId),
                    MediafileDao.Properties.Remark.eq("未上传")
            ).list()
        }
    }
    /**
     * åˆ é™¤å›¾ç‰‡
     */
    fun deleteMediaFile(id: String): Observable<Boolean> {
        return DbFactory.getGreenDaoObservable().map {
            it.mediafileDao.deleteByKey(id)
            true
        }
    }
}
app/src/main/java/cn/flightfeather/thirdapp/util/DialogUtil2.kt
@@ -13,6 +13,7 @@
import android.widget.TextView
import cn.flightfeather.thirdapp.R
import cn.flightfeather.thirdapp.module.base.BaseActivity
import cn.flightfeather.thirdapp.view.PopupWindowWithMask
/**
 * @author riku
@@ -56,7 +57,7 @@
    ) {
        val view = LayoutInflater.from(activity).inflate(R.layout.dialog_bottom_sheet, null)
        activity?.let {
            PopupWindow(it).apply popupWindow@{
            PopupWindowWithMask(it).apply popupWindow@{
                isFocusable = true
                isOutsideTouchable = true
                contentView = view
@@ -80,17 +81,8 @@
                width = ViewGroup.LayoutParams.MATCH_PARENT
                animationStyle = R.style.PopWin_bottom_anim_style
                background.alpha = 0
                setOnDismissListener {
                    val wl = activity.window.attributes
                    wl.alpha = 1f
                    activity.window.attributes = wl
                }
            }.run {
                val wl = activity.window.attributes
                wl.alpha = 0.9f
                activity.window.attributes = wl
                showAtLocation(anchorView, Gravity.BOTTOM, 0, 0)
            }
        }
    }
app/src/main/java/cn/flightfeather/thirdapp/util/updateApp/UpdateAppUtil.java
@@ -97,7 +97,7 @@
    public void downLoadApk() {
        try {
            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(versionVo.getDownloadUrl()));
            request.setTitle("第三方监管");
            request.setTitle(application.getString(R.string.app_name));
            request.setDescription("正在下载...");
            request.setDestinationInExternalFilesDir(application, Environment.DIRECTORY_DOWNLOADS, "supervision.apk");
            downloadManager = (DownloadManager) application.getSystemService(Context.DOWNLOAD_SERVICE);
app/src/main/java/cn/flightfeather/thirdapp/view/PopupWindowWithMask.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
package cn.flightfeather.thirdapp.view
import android.content.Context
import android.graphics.PixelFormat
import android.os.IBinder
import android.view.KeyEvent
import android.view.View
import android.view.WindowManager
import android.widget.PopupWindow
import org.jetbrains.anko.windowManager
/**
 * @author riku
 * Date: 2020/8/28
 */
class PopupWindowWithMask(private val context: Context) : PopupWindow(context) {
    private var windowManager: WindowManager? = null
    private var maskView: View? = null
    init {
        windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    }
    override fun showAtLocation(parent: View?, gravity: Int, x: Int, y: Int) {
        addMask(parent?.windowToken)
        super.showAtLocation(parent, gravity, x, y)
    }
    override fun dismiss() {
        removeMask()
        super.dismiss()
    }
    private fun addMask(token: IBinder?) {
        val wl: WindowManager.LayoutParams = WindowManager.LayoutParams()
        wl.width = WindowManager.LayoutParams.MATCH_PARENT
        wl.height = WindowManager.LayoutParams.MATCH_PARENT
        wl.format = PixelFormat.TRANSLUCENT //不设置这个弹出框的透明遮罩显示为黑色
        wl.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL //该Type描述的是形成的窗口的层级关系
        wl.token = token //获取当前Activity中的View中的token,来依附Activity
        maskView = View(context)
        maskView?.setBackgroundColor(0x7f000000)
        maskView?.fitsSystemWindows = false
        maskView?.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                removeMask()
                return@OnKeyListener true
            }
            false
        })
        /**
         * é€šè¿‡WindowManager的addView方法创建View,产生出来的View根据WindowManager.LayoutParams属性不同,效果也就不同了。
         * æ¯”如创建系统顶级窗口,实现悬浮窗口效果!
         */
        windowManager?.addView(maskView, wl)
    }
    private fun removeMask() {
        if (null != maskView) {
            windowManager?.removeViewImmediate(maskView)
            maskView = null
        }
    }
}
app/src/main/res/drawable-xxhdpi/shape_black_spinner.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:shape="rectangle">
            <!-- å¡«å……的颜色 -->
            <solid android:color="@color/white"/>
            <!-- è®¾ç½®æŒ‰é’®çš„四个角为弧形 -->
            <!-- android:radius å¼§å½¢çš„半径 -->
            <corners android:radius="2dp" />
            <!--描边-->
            <stroke
                android:width="1dp"
                android:color="@color/black" />
            <!-- padding:Button里面的文字与Button边界的间隔 -->
        </shape>
    </item>
    <item android:drawable="@drawable/ic_unfold_more_black_20dp"
        android:gravity="end|center"/>
</layer-list>
app/src/main/res/drawable/ic_unfold_more_black_20dp.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,4 @@
<vector android:height="20dp" android:viewportHeight="24.0"
    android:viewportWidth="24.0" android:width="20dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FF000000" android:pathData="M12,5.83L15.17,9l1.41,-1.41L12,3 7.41,7.59 8.83,9 12,5.83zM12,18.17L8.83,15l-1.41,1.41L12,21l4.59,-4.59L15.17,15 12,18.17z"/>
</vector>
app/src/main/res/layout/dialog_take_evidence.xml
@@ -2,7 +2,8 @@
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools">
    <android.support.design.widget.FloatingActionButton
        android:src="@drawable/icon_close_white"
@@ -64,9 +65,9 @@
                    android:id="@+id/tv_dialog_take_evidence_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="新增问题"
                    android:text="问题取证"
                    android:textColor="@color/primary_text"
                    android:textSize="18dp" />
                    android:textSize="18sp" />
            </LinearLayout>
            <TextView
@@ -80,8 +81,9 @@
                android:id="@+id/sp_take_evidence_select_problem_type"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="-7dp"
                android:layout_marginRight="-7dp"></Spinner>
                android:layout_marginTop="@dimen/dimen4"
                style="@style/SpinnerStyle.Black"
                tools:listitem="@layout/item_spinner_drop_down" />
            <TextView
                android:id="@+id/tv_chose"
@@ -94,15 +96,16 @@
                android:id="@+id/sp_take_evidence_select_problem"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="-7dp"
                android:layout_marginRight="-7dp"></Spinner>
                android:layout_marginTop="@dimen/dimen4"
                style="@style/SpinnerStyle.Black"
                tools:listitem="@layout/item_spinner_drop_down"/>
            <EditText
                android:id="@+id/et_take_evidence_problem_des"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:hint="问题描述(可选)"
                android:textSize="@dimen/textSize_14"
                android:visibility="visible" />
            <TextView
@@ -116,14 +119,16 @@
                android:id="@+id/sp_take_evidence_select_location"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="-7dp"
                android:layout_marginRight="-7dp"></Spinner>
                android:layout_marginTop="@dimen/dimen4"
                style="@style/SpinnerStyle.Black"
                tools:listitem="@layout/item_spinner_drop_down"/>
            <EditText
                android:id="@+id/et_take_evidence_location"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="位置备注(可选)" />
                android:hint="位置备注(可选)"
                android:textSize="@dimen/textSize_14"/>
            <LinearLayout
                android:id="@+id/ll_change_suggestion"
@@ -142,50 +147,63 @@
                    android:id="@+id/sp_take_evidence_select_suggestion"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="-7dp"
                    android:layout_marginRight="-7dp">
                </Spinner>
                    android:layout_marginTop="@dimen/dimen4"
                    style="@style/SpinnerStyle.Black"
                    tools:listitem="@layout/item_spinner_drop_down"/>
                <EditText
                    android:id="@+id/et_take_evidence_suggestion"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="整改建议(可选)" />
                    android:hint="整改建议(可选)"
                    android:textSize="@dimen/textSize_14"/>
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:layout_marginTop="10dp"
                android:orientation="horizontal">
                <android.support.constraint.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="10dp"
                    android:layout_marginTop="10dp"
                    android:orientation="horizontal">
                <ImageView
                    android:id="@+id/iv_take_evidence_add_photo1"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    android:layout_marginTop="6dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/icon_add_photo" />
                    <ImageView
                        android:id="@+id/iv_take_evidence_add_photo1"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:scaleType="fitCenter"
                        android:src="@drawable/icon_add_photo"
                        android:layout_marginEnd="@dimen/dimen8"
                        app:layout_constraintDimensionRatio="W, 1:1"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintEnd_toStartOf="@id/iv_take_evidence_add_photo2"
                        app:layout_constraintTop_toTopOf="parent"/>
                <ImageView
                    android:id="@+id/iv_take_evidence_add_photo2"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="6dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/icon_add_photo_blank" />
                    <ImageView
                        android:id="@+id/iv_take_evidence_add_photo2"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:scaleType="fitCenter"
                        android:src="@drawable/icon_add_photo_blank"
                        android:layout_marginEnd="@dimen/dimen8"
                        app:layout_constraintDimensionRatio="W, 1:1"
                        app:layout_constrainedWidth="true"
                        app:layout_constraintStart_toEndOf="@id/iv_take_evidence_add_photo1"
                        app:layout_constraintEnd_toStartOf="@id/iv_take_evidence_add_photo3"
                        app:layout_constraintTop_toTopOf="parent"/>
                <ImageView
                    android:id="@+id/iv_take_evidence_add_photo3"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="6dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/icon_add_photo_blank" />
            </LinearLayout>
                    <ImageView
                        android:id="@+id/iv_take_evidence_add_photo3"
                        android:layout_width="0dp"
                        android:layout_height="0dp"
                        android:scaleType="fitCenter"
                        android:src="@drawable/icon_add_photo_blank"
                        app:layout_constraintDimensionRatio="W, 1:1"
                        app:layout_constrainedWidth="true"
                        app:layout_constraintStart_toEndOf="@id/iv_take_evidence_add_photo2"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintTop_toTopOf="parent"/>
                </android.support.constraint.ConstraintLayout>
        </LinearLayout>
        </ScrollView>
    </android.support.v7.widget.CardView>
app/src/main/res/layout/item_spinner_drop_down.xml
@@ -25,6 +25,7 @@
    android:textSize="14sp"
    tools:text="@string/app_name"
    android:maxLines="1"
    android:padding="@dimen/dimen8"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:layout_height="wrap_content"
    android:ellipsize="end" />
app/src/main/res/values/strings.xml
@@ -57,6 +57,7 @@
    <string name="problem_recheck">问题复核</string>
    <string name="history_patrol">历史巡查</string>
    <string name="locale_take_evidence">问题取证</string>
    <string name="problem_update">问题修改</string>
    <string name="question_list">问题清单</string>
    <string name="locale_change">现场整改</string>
    <string name="colligate_score">综合评分</string>
app/src/main/res/values/styles.xml
@@ -155,6 +155,17 @@
        <item name="android:textSize">12sp</item>
    </style>
    <style name="SpinnerStyle">
        <item name="android:textColor">@color/main_color_1</item>
        <item name="android:textSize">14sp</item>
        <item name="android:background">@drawable/shape_black_spinner</item>
        <item name="android:paddingEnd">20dp</item>
    </style>
    <style name="SpinnerStyle.Black" >
        <item name="android:background">@drawable/shape_black_spinner</item>
    </style>
    <!--    //标签文字样式-->
    <style name="TextStyle.Tag">
        <item name="android:textColor">@color/boardGreen</item>