constraintLayout 退档

整理问题编辑代码位置
This commit is contained in:
kehaoyuan
2018-07-11 16:50:40 +08:00
parent ca07f10c9d
commit 80d2e2c488
14 changed files with 912 additions and 9 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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)
}
}

View File

@ -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()
}
}

View File

@ -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()
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;