constraintLayout 退档
整理问题编辑代码位置
This commit is contained in:
@ -15,7 +15,7 @@ import com.gh.gamecenter.baselist.ListFragment;
|
||||
import com.gh.gamecenter.baselist.LoadType;
|
||||
import com.gh.gamecenter.baselist.NormalListViewModel;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
import com.gh.gamecenter.qa.ask.QuestionEditActivity;
|
||||
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity;
|
||||
import com.gh.gamecenter.qa.entity.Questions;
|
||||
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
|
||||
@ -43,7 +43,7 @@ import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity;
|
||||
import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity;
|
||||
import com.gh.gamecenter.qa.answer.edit.AnswerEditFragment;
|
||||
import com.gh.gamecenter.qa.answer.fold.AnswerFoldActivity;
|
||||
import com.gh.gamecenter.qa.ask.QuestionEditActivity;
|
||||
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity;
|
||||
import com.gh.gamecenter.qa.entity.AnswerEntity;
|
||||
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity;
|
||||
import com.gh.gamecenter.qa.questions.invite.QuestionsInviteActivity;
|
||||
|
||||
@ -0,0 +1,228 @@
|
||||
package com.gh.gamecenter.qa.questions.edit
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.arch.lifecycle.Observer
|
||||
import android.arch.lifecycle.ViewModelProviders
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.databinding.DataBindingUtil
|
||||
import android.os.Bundle
|
||||
import android.support.v7.widget.GridLayoutManager
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.MenuItem
|
||||
import android.widget.EditText
|
||||
import com.gh.base.BaseActivity
|
||||
import com.gh.base.fragment.BaseDialogWrapperFragment
|
||||
import com.gh.base.fragment.WaitingDialogFragment
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.SuggestionActivity.MEDIA_STORE_REQUEST
|
||||
import com.gh.gamecenter.databinding.ActivityQuestionsEditBinding
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
|
||||
import com.gh.gamecenter.qa.questions.edit.pic.QuestionsEditPicAdapter
|
||||
import com.gh.gamecenter.qa.questions.edit.tip.QuestionTitleTipAdapter
|
||||
|
||||
/**
|
||||
* Created by khy on 28/04/18.
|
||||
*/
|
||||
class QuestionEditActivity : BaseActivity() {
|
||||
|
||||
private lateinit var mBinding: ActivityQuestionsEditBinding
|
||||
|
||||
private var mViewModel: QuestionEditViewModel? = null
|
||||
|
||||
private var mProcessingDialog: WaitingDialogFragment? = null
|
||||
private var mUpdateImageCancelDialog: Dialog? = null
|
||||
|
||||
companion object {
|
||||
// searchKey 补充到标题(新增问题)
|
||||
fun getIntent(context: Context, searchKey: String?): Intent {
|
||||
val intent = Intent(context, QuestionEditActivity::class.java)
|
||||
intent.putExtra(EntranceUtils.KEY_QUESTIONS_SEARCH_KEY, searchKey)
|
||||
return intent
|
||||
}
|
||||
|
||||
// 新增问题
|
||||
fun getIntent(context: Context): Intent {
|
||||
return Intent(context, QuestionEditActivity::class.java)
|
||||
}
|
||||
|
||||
// 编辑问题
|
||||
fun getIntent(context: Context, entity: QuestionsDetailEntity): Intent {
|
||||
val intent = Intent(context, QuestionEditActivity::class.java)
|
||||
intent.putExtra(QuestionsDetailEntity.TAG, entity)
|
||||
return intent
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_questions_edit
|
||||
}
|
||||
|
||||
@SuppressLint("Recycle")
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (data != null && requestCode == MEDIA_STORE_REQUEST) {
|
||||
mViewModel?.uploadPic(data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setToolbarMenu(R.menu.menu_question_post)
|
||||
mViewModel = ViewModelProviders.of(this).get(QuestionEditViewModel::class.java)
|
||||
mBinding = DataBindingUtil.bind(mContentView)!!
|
||||
mBinding.vm = mViewModel
|
||||
|
||||
if (intent != null) {
|
||||
val detailEntity = intent.getParcelableExtra<QuestionsDetailEntity>(QuestionsDetailEntity.TAG)
|
||||
if (detailEntity != null) { // 问题编辑
|
||||
mViewModel?.questionEntity = detailEntity
|
||||
mViewModel?.content = detailEntity.description
|
||||
mViewModel?.picList?.postValue(detailEntity.images as MutableList<String>?)
|
||||
if (mViewModel?.title.isNullOrEmpty()) mViewModel?.title = detailEntity.title
|
||||
} else { // 新增问题
|
||||
var searchKey = intent.getStringExtra(EntranceUtils.KEY_QUESTIONS_SEARCH_KEY)
|
||||
if (!searchKey.isNullOrEmpty() && searchKey.length > QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH)
|
||||
searchKey = searchKey.substring(0, QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH)
|
||||
if (mViewModel?.title.isNullOrEmpty()) mViewModel?.title = searchKey
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation
|
||||
if (mViewModel?.questionEntity != null) {
|
||||
setNavigationTitle("编辑问题")
|
||||
} else {
|
||||
setNavigationTitle(UserManager.getInstance().community.name)
|
||||
}
|
||||
|
||||
mViewModel?.getDefaultTag()
|
||||
|
||||
// TitleTip
|
||||
if (mViewModel?.questionEntity == null) {
|
||||
val titleTipAdapter = QuestionTitleTipAdapter(this, mBinding.questionseditTitle, mViewModel?.communityId)
|
||||
mBinding.questionseditTitle.setAdapter(titleTipAdapter)
|
||||
}
|
||||
|
||||
// TitleEdit
|
||||
mBinding.questionseditTitle.addTextChangedListener(LimitTextWatcher(mBinding.questionseditTitle))
|
||||
|
||||
// ContentEdit
|
||||
mBinding.questionseditContent.addTextChangedListener(LimitTextWatcher(mBinding.questionseditContent))
|
||||
|
||||
// Pic List
|
||||
val picAdapter = QuestionsEditPicAdapter(this, mViewModel!!)
|
||||
mBinding.suggestPicRv.layoutManager = object : GridLayoutManager(this, 5) {
|
||||
override fun canScrollVertically(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
mBinding.suggestPicRv.adapter = picAdapter
|
||||
|
||||
// Process dialog
|
||||
mViewModel?.processDialog?.observe(this, Observer { it ->
|
||||
if (it?.isShow!!) {
|
||||
mProcessingDialog = WaitingDialogFragment.newInstance(it.msg, false)
|
||||
mProcessingDialog?.show(supportFragmentManager, null, {
|
||||
if (mViewModel?.uploadImageSubscription != null && !mViewModel?.uploadImageSubscription!!.isDisposed) {
|
||||
mUpdateImageCancelDialog = DialogUtils.showAlertDialog(this, "提示"
|
||||
, "图片正在上传中,确定取消吗?"
|
||||
, "确定", "取消", {
|
||||
mViewModel?.uploadImageSubscription!!.dispose()
|
||||
mUpdateImageCancelDialog?.dismiss()
|
||||
mProcessingDialog?.dismiss()
|
||||
}, null)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
mUpdateImageCancelDialog?.dismiss()
|
||||
mProcessingDialog?.dismiss()
|
||||
}
|
||||
})
|
||||
|
||||
mViewModel?.titleTags?.observe(this, Observer<List<String>> {
|
||||
if (supportFragmentManager.findFragmentByTag(TagsSelectFragment::javaClass.name) == null) {
|
||||
val dialog = BaseDialogWrapperFragment.getInstance(TagsSelectFragment.getInstance(), false)
|
||||
dialog.show(supportFragmentManager, TagsSelectFragment::javaClass.name)
|
||||
}
|
||||
})
|
||||
|
||||
mViewModel?.picList?.observe(this, Observer { it ->
|
||||
if (it != null) picAdapter.notifyPicList(it)
|
||||
})
|
||||
|
||||
// 增加提问时, 如果searchKey不为空 光标跳到最后
|
||||
mBaseHandler.postDelayed({
|
||||
if (mViewModel?.questionEntity == null) {
|
||||
mBinding.questionseditTitle.setSelection(mBinding.questionseditTitle.text.toString().length)
|
||||
}
|
||||
}, 50)
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(menuItem: MenuItem?): Boolean {
|
||||
mViewModel?.checkTitleAndLoadTitleTag()
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// Limits of EditText
|
||||
private inner class LimitTextWatcher(private val mEditText: EditText) : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||
if (mEditText === mBinding.questionseditTitle) {
|
||||
val etContent = s.toString()
|
||||
|
||||
// 去空格
|
||||
if (etContent.contains(" ")) {
|
||||
mBinding.questionseditTitle.setText(etContent.replace(" ".toRegex(), ""))
|
||||
mBinding.questionseditTitle.setSelection(start)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查标题最大长度
|
||||
if (s.length > QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH) {
|
||||
mBinding.questionseditTitle.setText("")
|
||||
val newText = s.toString().substring(0, QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH)
|
||||
mBinding.questionseditTitle.setText(newText)
|
||||
mBinding.questionseditTitle.setSelection(mBinding.questionseditTitle.text?.length!!)
|
||||
toast("标题最多${QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH}个字")
|
||||
}
|
||||
} else if (mEditText === mBinding.questionseditContent) {
|
||||
|
||||
// 检查内容最大长度
|
||||
if (s.length > QuestionEditViewModel.QUESTION_CONTENT_MAX_LENGTH) {
|
||||
mBinding.questionseditContent.setText("")
|
||||
val newText = s.toString().substring(0, QuestionEditViewModel.QUESTION_CONTENT_MAX_LENGTH)
|
||||
mBinding.questionseditContent.setText(newText)
|
||||
mBinding.questionseditContent.setSelection(mBinding.questionseditContent.text.length)
|
||||
toast("内容最多${QuestionEditViewModel.QUESTION_CONTENT_MAX_LENGTH}个字")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable) {}
|
||||
}
|
||||
|
||||
// 退出提示
|
||||
override fun onBackPressed() {
|
||||
// 需要检查的内容,其中任意一个不为空都要打开提示弹窗
|
||||
val imgList = mViewModel?.picList?.value
|
||||
val title = mBinding.questionseditTitle.text.toString().trim()
|
||||
val content = mBinding.questionseditContent.text.toString().trim()
|
||||
|
||||
if (imgList != null && imgList.size > 0 || title.isNotEmpty() || content.isNotEmpty()) {
|
||||
DialogUtils.showCancelAlertDialog(this, "提示"
|
||||
, if (mViewModel?.questionEntity == null) "确定放弃提问吗?" else "确定放弃编辑吗?"
|
||||
, "再想想", " 放弃", null) { finish() }
|
||||
return
|
||||
}
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,244 @@
|
||||
package com.gh.gamecenter.qa.questions.edit
|
||||
|
||||
import android.app.Application
|
||||
import android.arch.lifecycle.AndroidViewModel
|
||||
import android.arch.lifecycle.LiveData
|
||||
import android.arch.lifecycle.MediatorLiveData
|
||||
import android.content.Intent
|
||||
import android.provider.MediaStore
|
||||
import android.text.TextUtils
|
||||
import com.gh.base.fragment.WaitingDialogFragment
|
||||
import com.gh.common.util.GsonUtils
|
||||
import com.gh.common.util.UploadUtils
|
||||
import com.gh.common.util.UrlFilterUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.mvvm.NetworkBoundResource
|
||||
import com.gh.gamecenter.mvvm.Resource
|
||||
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.retrofit.service.ApiService
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.HttpException
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by khy on 28/04/18.
|
||||
*/
|
||||
class QuestionEditViewModel(application: Application) : AndroidViewModel(application) {
|
||||
companion object {
|
||||
const val QUESTION_TAG_MAX_COUNT = 5
|
||||
const val PIC_MAX_AMOUNT = 3
|
||||
const val QUESTION_TITLE_MIN_LENGTH = 6
|
||||
const val QUESTION_CONTENT_MAX_LENGTH = 300
|
||||
const val QUESTION_TITLE_MAX_LENGTH = 50
|
||||
const val PIC_MAX_FILE_SIZE = 10 * 1024 * 1024
|
||||
}
|
||||
|
||||
private val mApiService: ApiService = RetrofitManager.getInstance(getApplication()).api
|
||||
|
||||
var communityId: String? = null
|
||||
|
||||
val processDialog = MediatorLiveData<WaitingDialogFragment.WaitingDialogData>()
|
||||
val titleTags = MediatorLiveData<List<String>>()
|
||||
|
||||
var uploadImageSubscription: Disposable? = null
|
||||
|
||||
// post data
|
||||
var title: String? = ""
|
||||
var content: String? = ""
|
||||
val picList = MediatorLiveData<MutableList<String>>()
|
||||
var defaultTags: MutableList<String> = ArrayList()
|
||||
var questionEntity: QuestionsDetailEntity? = null
|
||||
val selectedTags: MutableList<String> = ArrayList()
|
||||
|
||||
/**
|
||||
* 获取默认标签和确定当前communityId
|
||||
*/
|
||||
fun getDefaultTag() {
|
||||
communityId = if (questionEntity != null) questionEntity?.communityId
|
||||
else UserManager.getInstance().community.id
|
||||
mApiService
|
||||
.getCommunitiesTags(communityId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<List<String>>() {
|
||||
override fun onResponse(response: List<String>?) {
|
||||
defaultTags = response as MutableList<String>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查标题是否符合规则
|
||||
* 根据问题标题获取相应标签(问题编辑无需获取)
|
||||
*/
|
||||
fun checkTitleAndLoadTitleTag() {
|
||||
if (TextUtils.isEmpty(title)) {
|
||||
Utils.toast(getApplication(), "标题不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查标题长度限制
|
||||
title?.trim()
|
||||
title = title?.replace(" ", "")
|
||||
if (title!!.length < QUESTION_TITLE_MIN_LENGTH) {
|
||||
Utils.toast(getApplication(), "标题至少${QUESTION_TITLE_MIN_LENGTH}个字")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查标题结尾是否存在问号,没则主动加上
|
||||
if (title!!.length <= QUESTION_TITLE_MAX_LENGTH) {
|
||||
val endString = title?.substring(title!!.length - 1, title!!.length)
|
||||
if ("?" != endString && "?" != endString)
|
||||
title += "?"
|
||||
}
|
||||
|
||||
selectedTags.clear() // 清空已选择的标签
|
||||
if (questionEntity == null) {
|
||||
loadTitleTags()
|
||||
} else {
|
||||
titleTags.postValue(null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据问题标题获取相应标签(标签默认选中)
|
||||
*/
|
||||
private fun loadTitleTags() {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
|
||||
mApiService
|
||||
.getQuestionTagsByTitle(communityId, UrlFilterUtils.getFilterQuery("title", title))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<List<String>>() {
|
||||
override fun onResponse(response: List<String>?) {
|
||||
titleTags.postValue(response)
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
|
||||
Utils.toast(getApplication(), R.string.request_failure_normal_hint)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择动作(选中标签/移除已选中的标签)
|
||||
*/
|
||||
fun selectTag(tag: String): Boolean {
|
||||
return when {
|
||||
selectedTags.contains(tag) -> {
|
||||
selectedTags.remove(tag)
|
||||
false
|
||||
}
|
||||
selectedTags.size < QUESTION_TAG_MAX_COUNT -> {
|
||||
selectedTags.add(tag)
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
Utils.toast(getApplication(), R.string.questionsdetail_max_tag_hint)
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查图片是否符合规则并上传图片
|
||||
* @param picPath 图片本地路径
|
||||
*/
|
||||
fun uploadPic(data: Intent) {
|
||||
val selectedImage = data.data ?: return
|
||||
val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
|
||||
|
||||
val application: Application = getApplication()
|
||||
|
||||
val cursor = application.contentResolver.query(selectedImage, filePathColumn, null, null, null)
|
||||
?: return
|
||||
cursor.moveToFirst()
|
||||
|
||||
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
|
||||
val picPath = cursor.getString(columnIndex)
|
||||
cursor.close()
|
||||
|
||||
Utils.log("picturePath = " + picPath)
|
||||
val file = File(picPath)
|
||||
if (file.length() > PIC_MAX_FILE_SIZE) {
|
||||
Utils.toast(getApplication(), R.string.suggestion_pic_hint)
|
||||
return
|
||||
} else {
|
||||
val picList = picList.value
|
||||
if (picList != null && picList.size >= PIC_MAX_AMOUNT) {
|
||||
Utils.toast(getApplication(), R.string.questions_edit_maxpic_hint)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("上传中...", true))
|
||||
uploadImageSubscription = UploadUtils.compressAndUploadImage(picPath, object : UploadUtils.OnUploadImageListener {
|
||||
override fun onSuccess(imageUrl: String) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("上传中...", false))
|
||||
val list = picList.value ?: ArrayList()
|
||||
list.add(imageUrl)
|
||||
picList.postValue(list)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable?) {
|
||||
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("上传中...", false))
|
||||
if (e != null && e is HttpException && e.code() == 403) {
|
||||
Utils.toast(getApplication(), "图片违规")
|
||||
} else {
|
||||
Utils.toast(getApplication(), "图片上传失败,请检查网络")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除以上传的图片
|
||||
* @param picPath 图片成功上传后的URL
|
||||
*/
|
||||
fun removePic(picPath: String) {
|
||||
val list = picList.value
|
||||
if (list != null && list.remove(picPath)) {
|
||||
picList.postValue(list)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交问题
|
||||
*/
|
||||
fun postQuestion(): LiveData<Resource<ResponseBody>> {
|
||||
val entity = QuestionsDetailEntity()
|
||||
entity.title = title
|
||||
entity.description = content
|
||||
entity.tags = selectedTags
|
||||
entity.images = if (picList.value != null) {
|
||||
picList.value!!
|
||||
} else {
|
||||
ArrayList()
|
||||
}
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), GsonUtils.getInstance().toJson(entity))
|
||||
val observable = if (questionEntity != null) {
|
||||
questionEntity?.tags = entity.tags
|
||||
questionEntity?.images = entity.images
|
||||
questionEntity?.title = entity.title
|
||||
questionEntity?.description = entity.description
|
||||
mApiService.patchQuestions(body, questionEntity?.id) // patch
|
||||
} else {
|
||||
mApiService.postQuestions(body, communityId) // add
|
||||
}
|
||||
|
||||
return NetworkBoundResource<ResponseBody>(observable).asLiveData()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,214 @@
|
||||
package com.gh.gamecenter.qa.questions.edit
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.arch.lifecycle.Observer
|
||||
import android.arch.lifecycle.ViewModelProviders
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import com.gh.base.fragment.BaseDialogWrapperFragment
|
||||
import com.gh.base.fragment.BaseFragment
|
||||
import com.gh.base.fragment.WaitingDialogFragment
|
||||
import com.gh.common.util.AskErrorResponseUtils
|
||||
import com.gh.common.util.DisplayUtils
|
||||
import com.gh.common.util.LoginUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.mvvm.Status
|
||||
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
|
||||
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
|
||||
import com.google.android.flexbox.FlexboxLayout
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import kotterknife.bindView
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by khy on 28/04/18.
|
||||
*/
|
||||
class TagsSelectFragment : BaseFragment<String>() {
|
||||
|
||||
companion object {
|
||||
fun getInstance(): TagsSelectFragment {
|
||||
val fragment = TagsSelectFragment()
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
private val mTagFl by bindView<FlexboxLayout>(R.id.questions_edit_tag)
|
||||
private val mAddTagBtn by bindView<View>(R.id.questions_edit_tag_add)
|
||||
private val mPostBtn by bindView<View>(R.id.questions_edit_tag_positive)
|
||||
private val mCancelBtn by bindView<View>(R.id.questions_edit_tag_cancel)
|
||||
|
||||
private var mViewModel: QuestionEditViewModel? = null
|
||||
|
||||
private val mAllTags: MutableList<String> = ArrayList() // 所有标签集合
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.questions_edit_tag
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (activity != null) mViewModel = ViewModelProviders.of(activity!!).get(QuestionEditViewModel::class.java)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
initTags()
|
||||
|
||||
mAddTagBtn.setOnClickListener {
|
||||
if (mViewModel?.selectedTags?.size!! < QuestionEditViewModel.QUESTION_TAG_MAX_COUNT) {
|
||||
showAddTagDialog()
|
||||
} else {
|
||||
toast(R.string.questionsdetail_max_tag_hint)
|
||||
}
|
||||
}
|
||||
|
||||
mCancelBtn.setOnClickListener {
|
||||
val fragment = parentFragment
|
||||
(fragment as? BaseDialogWrapperFragment)?.dismiss()
|
||||
}
|
||||
|
||||
mPostBtn.setOnClickListener {
|
||||
mViewModel?.postQuestion()?.observe(this, Observer { it ->
|
||||
when (it?.status) {
|
||||
Status.SUCCESS -> {
|
||||
mViewModel?.processDialog?.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
|
||||
toast("提交成功")
|
||||
if (mViewModel?.questionEntity != null) { // 修改问题
|
||||
val data = Intent()
|
||||
data.putExtra(QuestionsDetailEntity.TAG, mViewModel?.questionEntity)
|
||||
activity?.setResult(Activity.RESULT_OK, data)
|
||||
} else {
|
||||
val data = JSONObject(it.data?.string())
|
||||
startActivity(QuestionsDetailActivity.getIntent(context, data.getString("_id"), "(回答编辑)"))
|
||||
}
|
||||
activity?.finish()
|
||||
}
|
||||
Status.ERROR -> {
|
||||
mViewModel?.processDialog?.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
|
||||
if (!LoginUtils.userPostErrorToast(it.exception, context, false)) {
|
||||
toast("提交失败")
|
||||
AskErrorResponseUtils.errorResponseControl(context, it.exception)
|
||||
}
|
||||
}
|
||||
Status.LOADING -> {
|
||||
mViewModel?.processDialog?.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun initTags() {
|
||||
// 添加标签
|
||||
val mDefaultTag = mViewModel?.defaultTags ?: ArrayList()
|
||||
|
||||
if (mViewModel?.questionEntity == null) {
|
||||
val mTitleTag = (mViewModel?.titleTags?.value ?: ArrayList()) as MutableList
|
||||
// 添加默认标签(如果标题标签与默认标签重复则选中)
|
||||
for (s in mDefaultTag.reversed()) {
|
||||
val contains = mTitleTag.contains(tag)
|
||||
addTag(s, contains)
|
||||
if (contains) mTitleTag.remove(tag)
|
||||
}
|
||||
// 未匹配到默认标签的默认选中在前排
|
||||
for (s in mTitleTag) {
|
||||
addTag(s, true)
|
||||
}
|
||||
} else {
|
||||
val tags = mViewModel?.questionEntity?.tags ?: ArrayList()
|
||||
for (s in mDefaultTag) {
|
||||
if (!tags.contains(s))
|
||||
addTag(s, false)
|
||||
}
|
||||
for (s in tags.reversed()) {
|
||||
addTag(s, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showAddTagDialog() {
|
||||
view?.visibility = View.GONE
|
||||
val dialog = Dialog(context!!)
|
||||
val view = View.inflate(context, R.layout.dialog_modify_nickname, null)
|
||||
val title = view.findViewById<TextView>(R.id.dialog_nickname_title)
|
||||
val input = view.findViewById<EditText>(R.id.dialog_nickname_input)
|
||||
title.text = "新建标签"
|
||||
input.hint = ""
|
||||
input.setSelection(input.text.length)
|
||||
// 取消按钮
|
||||
view.findViewById<TextView>(R.id.dialog_nickname_cancel).setOnClickListener { dialog.dismiss() }
|
||||
// 确定按钮
|
||||
view.findViewById<TextView>(R.id.dialog_nickname_confirm).setOnClickListener {
|
||||
if (!TextUtils.isEmpty(input.text.toString().trim())) {
|
||||
addTag(input.text.toString().trim(), true)
|
||||
dialog.dismiss()
|
||||
} else {
|
||||
toast(R.string.vote_empty_hint)
|
||||
}
|
||||
}
|
||||
dialog.setOnDismissListener {
|
||||
Util_System_Keyboard.hideSoftKeyboard(activity)
|
||||
this.view?.visibility = View.VISIBLE
|
||||
}
|
||||
dialog.setCancelable(false)
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
dialog.setContentView(view)
|
||||
dialog.show()
|
||||
mBaseHandler.postDelayed({ Util_System_Keyboard.showSoftKeyboard(context, input) }, 300)
|
||||
}
|
||||
|
||||
private fun addTag(tag: String, isSelect: Boolean) {
|
||||
if (isSelect && mAllTags.contains(tag)) { // 标签已存在
|
||||
if (!mViewModel?.selectedTags?.contains(tag)!!) { // 标签已存在且未选择
|
||||
for (i in 0 until mTagFl.childCount) {
|
||||
val tagView = mTagFl.getChildAt(i) as TextView
|
||||
val text = tagView.text
|
||||
if (text != null && text.toString() == tag) {
|
||||
mViewModel?.selectedTags?.add(tag)
|
||||
tagView.setBackgroundResource(R.drawable.comment_border_bg)
|
||||
tagView.setTextColor(ContextCompat.getColor(context!!, R.color.theme))
|
||||
}
|
||||
}
|
||||
}
|
||||
toast("标签已存在")
|
||||
return
|
||||
}
|
||||
|
||||
val view = LayoutInflater.from(context).inflate(R.layout.questionsdedit_tag_item, null)
|
||||
val tagTv = view as TextView
|
||||
tagTv.text = tag
|
||||
val params = FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
params.setMargins(0, DisplayUtils.dip2px(context, 5f), DisplayUtils.dip2px(context, 15f), DisplayUtils.dip2px(context, 5f))
|
||||
tagTv.layoutParams = params
|
||||
mTagFl.addView(view, 0)
|
||||
|
||||
tagTv.setOnClickListener({
|
||||
if (mViewModel?.selectTag(tagTv.text.toString())!!) {
|
||||
tagTv.setBackgroundResource(R.drawable.comment_border_bg)
|
||||
tagTv.setTextColor(ContextCompat.getColor(context!!, R.color.theme))
|
||||
} else {
|
||||
tagTv.setBackgroundResource(R.drawable.border_suggest_bg)
|
||||
tagTv.setTextColor(ContextCompat.getColor(context!!, R.color.content))
|
||||
}
|
||||
})
|
||||
|
||||
if (isSelect) {
|
||||
mViewModel?.selectedTags?.add(tag)
|
||||
tagTv.setBackgroundResource(R.drawable.comment_border_bg)
|
||||
tagTv.setTextColor(ContextCompat.getColor(context!!, R.color.theme))
|
||||
}
|
||||
mAllTags.add(tag)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
package com.gh.gamecenter.qa.questions.edit.pic
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.provider.MediaStore
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.gh.common.util.ClickUtils
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.ImageUtils
|
||||
import com.gh.common.util.NetworkUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.SuggestionActivity.MEDIA_STORE_REQUEST
|
||||
import com.gh.gamecenter.qa.questions.edit.QuestionEditViewModel
|
||||
import com.gh.gamecenter.suggest.SuggestPicViewHolder
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
import com.lightgame.utils.Utils
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by khy on 5/05/18.
|
||||
*/
|
||||
class QuestionsEditPicAdapter(context: Context, viewModel: QuestionEditViewModel) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
|
||||
|
||||
private val mViewModel: QuestionEditViewModel = viewModel
|
||||
private var picList: MutableList<String> = ArrayList()
|
||||
private var mAgreePostPic: Boolean = false
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val view = mLayoutInflater.inflate(R.layout.suggest_pic_item, parent, false)
|
||||
return SuggestPicViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
if (holder is SuggestPicViewHolder) {
|
||||
if (position == itemCount - 1 && picList.size < QuestionEditViewModel.PIC_MAX_AMOUNT) {
|
||||
holder.delate.visibility = View.GONE
|
||||
ImageUtils.display(holder.icon, R.drawable.suggest_add_pic_icon)
|
||||
} else {
|
||||
holder.icon.setImageURI(picList[position])
|
||||
holder.delate.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener {
|
||||
if (!ClickUtils.isFastDoubleClick(R.id.menu_question_post) && position == itemCount - 1
|
||||
&& picList.size < QuestionEditViewModel.PIC_MAX_AMOUNT
|
||||
&& mContext is Activity) {
|
||||
if (NetworkUtils.isWifiConnected(mContext) || mAgreePostPic) {
|
||||
addPic(mContext as Activity)
|
||||
} else {
|
||||
mAgreePostPic = true
|
||||
DialogUtils.showAlertDialog(mContext,
|
||||
"警告",
|
||||
"当前使用移动网络,上传图片会消耗流量,确定上传吗?",
|
||||
"继续上传", "取消",
|
||||
{ addPic(mContext as Activity) }, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
holder.delate.setOnClickListener {
|
||||
mViewModel.removePic(picList[position])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addPic(activity: Activity) {
|
||||
try {
|
||||
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
|
||||
activity.startActivityForResult(intent, MEDIA_STORE_REQUEST)
|
||||
} catch (e: Exception) {
|
||||
Utils.toast(mContext, R.string.media_image_hint)
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return if (picList.size >= QuestionEditViewModel.PIC_MAX_AMOUNT) picList.size else picList.size + 1
|
||||
}
|
||||
|
||||
fun notifyPicList(picPath: MutableList<String>) {
|
||||
picList = ArrayList(picPath)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
package com.gh.gamecenter.qa.questions.edit.tip
|
||||
|
||||
import android.content.Context
|
||||
import android.databinding.DataBindingUtil
|
||||
import android.text.Html
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.BaseAdapter
|
||||
import android.widget.Filter
|
||||
import android.widget.Filterable
|
||||
import com.gh.common.util.DisplayUtils
|
||||
import com.gh.common.util.UrlFilterUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.QuestionEditTitleSearchItemBinding
|
||||
import com.gh.gamecenter.qa.entity.QuestionsIndexEntity
|
||||
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* Created by khy on 3/05/18.
|
||||
*/
|
||||
class QuestionTitleTipAdapter(private val context: Context, title: AutoCompleteTextView, communityId: String?) : BaseAdapter(), Filterable {
|
||||
|
||||
var questionList: MutableList<QuestionsIndexEntity> = ArrayList()
|
||||
var mTitleView = title
|
||||
var mCommunityId = communityId
|
||||
var mSearchKey: String? = null
|
||||
|
||||
override fun getView(pos: Int, convertView: View?, parent: ViewGroup?): View {
|
||||
val view: View
|
||||
val binding: QuestionEditTitleSearchItemBinding
|
||||
if (convertView == null) {
|
||||
binding = DataBindingUtil.bind(LayoutInflater.from(context).inflate(R.layout.question_edit_title_search_item, convertView, false))!!
|
||||
view = binding.root
|
||||
view.tag = binding
|
||||
} else {
|
||||
view = convertView
|
||||
binding = view.tag as QuestionEditTitleSearchItemBinding
|
||||
}
|
||||
val entity = questionList[pos]
|
||||
binding.entity = entity
|
||||
binding.questionsEditIndexTitle.text = Html.fromHtml(replayKeyword(entity.title))
|
||||
view.setOnClickListener({
|
||||
val tracers = "(问题编辑)+(标题自动搜索)"
|
||||
context.startActivity(QuestionsDetailActivity.getIntent(context, entity.id, tracers))
|
||||
})
|
||||
return view
|
||||
|
||||
}
|
||||
|
||||
private fun replayKeyword(title: String): String {
|
||||
var translationKey = escapeExprSpecialWord(mSearchKey)
|
||||
return if (TextUtils.isEmpty(translationKey)) title else title.replace(translationKey?.toRegex()!!, getHtmlKeyword())
|
||||
}
|
||||
|
||||
// 特殊符合转译
|
||||
private fun escapeExprSpecialWord(s: String?): String? {
|
||||
var keyword = s
|
||||
if (!keyword.isNullOrEmpty()) {
|
||||
val fbsArr = arrayOf("\\", "$", "(", ")", "*", "+", ".", "[", "]", "?", "^", "{", "}", "|")
|
||||
for (key in fbsArr) {
|
||||
if (keyword!!.contains(key)) {
|
||||
keyword = keyword.replace(key, "\\" + key)
|
||||
}
|
||||
}
|
||||
}
|
||||
return keyword
|
||||
}
|
||||
|
||||
private fun getHtmlKeyword(): String {
|
||||
return "<font color=\"#ff4147\">$mSearchKey</font>"
|
||||
}
|
||||
|
||||
override fun getItem(pos: Int): Any {
|
||||
return questionList[pos]
|
||||
}
|
||||
|
||||
override fun getItemId(pos: Int): Long {
|
||||
return pos.toLong()
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return questionList.size
|
||||
}
|
||||
|
||||
override fun getFilter(): Filter {
|
||||
return QuestionTitleFilter()
|
||||
}
|
||||
|
||||
inner class QuestionTitleFilter : Filter() {
|
||||
|
||||
override fun performFiltering(prefix: CharSequence?): FilterResults {
|
||||
val results = FilterResults()
|
||||
if (prefix.isNullOrBlank()) return results
|
||||
RetrofitManager
|
||||
.getInstance(context).api
|
||||
.getAskSearchByTitle(mCommunityId, UrlFilterUtils.getFilterQuery("keyword", prefix.toString()), 1)
|
||||
.subscribe(object : Response<List<QuestionsIndexEntity>>() {
|
||||
override fun onResponse(response: List<QuestionsIndexEntity>?) {
|
||||
results.values = response
|
||||
results.count = response!!.size
|
||||
mSearchKey = prefix.toString()
|
||||
}
|
||||
})
|
||||
return results
|
||||
}
|
||||
|
||||
override fun publishResults(constant: CharSequence?, results: FilterResults?) {
|
||||
if (results != null && results.count > 0) {
|
||||
questionList = results.values as ArrayList<QuestionsIndexEntity>
|
||||
} else {
|
||||
questionList.clear()
|
||||
}
|
||||
if (questionList.size > 2) {
|
||||
mTitleView.dropDownHeight = DisplayUtils.dip2px(context, 200F)
|
||||
} else {
|
||||
mTitleView.dropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,7 @@ import com.gh.gamecenter.baselist.LoadType;
|
||||
import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment;
|
||||
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity;
|
||||
import com.gh.gamecenter.qa.ask.QuestionEditActivity;
|
||||
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity;
|
||||
import com.gh.gamecenter.qa.entity.AnswerEntity;
|
||||
import com.gh.gamecenter.qa.entity.Questions;
|
||||
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity;
|
||||
|
||||
@ -16,7 +16,7 @@ import android.widget.TextView;
|
||||
import com.gh.base.BaseActivity;
|
||||
import com.gh.common.util.CheckLoginUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.qa.ask.QuestionEditActivity;
|
||||
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity;
|
||||
import com.lightgame.utils.Util_System_Keyboard;
|
||||
|
||||
import butterknife.BindView;
|
||||
|
||||
@ -19,7 +19,7 @@ import com.gh.gamecenter.baselist.LoadType;
|
||||
import com.gh.gamecenter.baselist.NormalListViewModel;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity;
|
||||
import com.gh.gamecenter.qa.ask.QuestionEditActivity;
|
||||
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity;
|
||||
import com.gh.gamecenter.qa.entity.AskSearchEntity;
|
||||
import com.gh.gamecenter.qa.entity.Questions;
|
||||
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity;
|
||||
|
||||
Reference in New Issue
Block a user