I want update progress bar in parent activity where recycler view is located.when user clicked on each radio buttons add a number to progress bar I have done it but I don't know how can I pass data from recycler view adapter to parent activity.
enter image description here
class MbtiQuestionAdapter(val questionList: QuestionList) :
RecyclerView.Adapter<QuestionViewHolder>() {
var maps = arrayListOf<HashMap<String, String>>()
var i = 0
var e = 0
var n = 0
var t = 0
var j = 0
var p = 0
var f = 0
var s = 0
var typeQuestion = ""
var testnumbers = 0
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QuestionViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val cellForRow = layoutInflater.inflate(
AminAmix.com.socialpersonality.R.layout.question_row,
parent,
false
)
return QuestionViewHolder(cellForRow)
}
#SuppressLint("ResourceAsColor")
override fun onBindViewHolder(holder: QuestionViewHolder, position: Int) {
//val question = questions.get(position)
if (questionList.questions[position].tip != "") {
holder.view.txtTitletipsQuestionRow.visibility = View.VISIBLE
// holder.view.imgtips.visibility = View.VISIBLE
holder.view.txtTipsQuestion.visibility = View.VISIBLE
holder.view.txtTipsQuestion.text = questionList.questions[position].tip
} else {
holder.view.imageView15.visibility = View.INVISIBLE
holder.view.shapeBlue.visibility = View.VISIBLE
holder.view.shapeGreen.visibility = View.VISIBLE
holder.view.shapeCircle.visibility = View.VISIBLE
}
holder.view.txtAmountQuestion.text = questionList.questions.size.toString()
holder.view.txtCurrentQuestion.text = (position + 1).toString()
val question = questionList.questions.get(position).title
Log.i("Position", position.toString())
val answers = questionList.questions.get(position).answers
var valueOfRadio = ""
if (questionList.questions.get(position).type == "range") {
holder.view.cardAB.visibility = View.INVISIBLE
for (answer in answers) {
val value = answer.value
typeQuestion = answer.title
Log.i("Position2", value.toString())
if (answer.title == "Agree") {
holder.view.txtQuestionDisAgree.text = answer.title
} else {
holder.view.txtQuestionAgree.text = answer.title
}
}
holder.view.radioGroup.setOnCheckedChangeListener { group, checkedId ->
if (checkedId == AminAmix.com.socialpersonality.R.id.radioButton_middle) {
Log.i("Radio", "0")
valueOfRadio = "0"
}
if (checkedId == AminAmix.com.socialpersonality.R.id.radioButton_agree1) {
Log.i("Radio", "1")
valueOfRadio = "1"
}
if (checkedId == AminAmix.com.socialpersonality.R.id.radioButton_agree2) {
Log.i("Radio", "2")
valueOfRadio = "2"
}
if (checkedId == AminAmix.com.socialpersonality.R.id.radioButton_disagree1) {
Log.i("Radio", "-1")
valueOfRadio = "-1"
}
if (checkedId == AminAmix.com.socialpersonality.R.id.radioButton_disagree_2) {
Log.i("Radio", "-2")
valueOfRadio = "-2"
}
val checked = group.findViewById(checkedId) as RadioButton
val list: ArrayList<String> = ArrayList()
list.add(checked.getText().toString())
Log.i("Chekkk", list.toString())
Log.i(
"checkedId", position.toString()
)
var idIf = ""
var typeIf = ""
var testValue = 0
var map = HashMap<String, String>();
var radioInt = valueOfRadio.toInt()
var selectedAnswers = questionList.questions[position].answers
if (radioInt > 0) {
for (answer in selectedAnswers) {
if (answer.title == "Agree") {
typeIf = answer.type
testValue = answer.value
holder.view.txtQuestionDisAgree.setTextColor(Color.parseColor("#5E5E5E"));
holder.view.txtQuestionAgree.setTextColor(Color.parseColor("#B2B2B2"));
holder.view.txtCurrentQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtAmountQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtCurrentQuestion2.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtTitleQuestions.setTextColor(Color.parseColor("#0B6095"));
holder.view.questionsTik.visibility = View.VISIBLE
}
}
} else if (radioInt < 0) {
for (answer in selectedAnswers) {
if (answer.title == "Disagree") {
typeIf = answer.type
testValue = answer.value
holder.view.txtQuestionAgree.setTextColor(Color.parseColor("#5E5E5E"));
holder.view.txtQuestionDisAgree.setTextColor(Color.parseColor("#B2B2B2"));
holder.view.txtCurrentQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtAmountQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtCurrentQuestion2.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtTitleQuestions.setTextColor(Color.parseColor("#0B6095"));
holder.view.questionsTik.visibility = View.VISIBLE
}
}
} else {
holder.view.txtQuestionAgree.setTextColor(Color.parseColor("#B2B2B2"));
holder.view.txtQuestionDisAgree.setTextColor(Color.parseColor("#B2B2B2"));
holder.view.txtCurrentQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtAmountQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtCurrentQuestion2.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtTitleQuestions.setTextColor(Color.parseColor("#0B6095"));
holder.view.questionsTik.visibility = View.VISIBLE
}
var absolutResultRadio = Math.abs(valueOfRadio.toInt())
// map["Q" + "_" + idIf.toString() + "_" + typeIf.toString()] = valueOfRadio
map["Q" + (position + 1).toString()] =
typeIf.toString() + "_" + absolutResultRadio * testValue
var con = maps.any { it.containsKey("Q" + (position + 1).toString()) }
if (maps.any { con == true }) {// filter
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
maps.removeIf { it.containsKey("Q" + (position + 1)) }
testnumbers = testnumbers - 1
}
testnumbers = testnumbers + 1
maps.add(map)
Log.i("maps", "in dare ejra mishe")
} else {
maps.add(map)
testnumbers = testnumbers + 1
}
}
Log.i ( "testnumber2" , testnumbers.toString())
} else {
holder.view.cardRange.visibility = View.INVISIBLE
holder.view.radioButtonFirstAAndB.text = answers[0].title
holder.view.radioButtonSecondAAndB.text = answers[1].title
holder.view.radioGroup2.setOnCheckedChangeListener { group, checkedId ->
if (checkedId == AminAmix.com.socialpersonality.R.id.radioButtonFirstAAndB) {
Log.i("Radio", "1")
valueOfRadio = "1"
}
if (checkedId == AminAmix.com.socialpersonality.R.id.radioButtonSecondAAndB) {
Log.i("Radio", "-1")
valueOfRadio = "-1"
}
val checked = group.findViewById(checkedId) as RadioButton
val list: ArrayList<String> = ArrayList()
list.add(checked.getText().toString())
Log.i("Chekkk", list.toString())
Log.i(
"checkedId", position.toString()
)
var idIf = ""
var typeIf = ""
var testValue = 0
var map = HashMap<String, String>();
var radioInt = valueOfRadio.toInt()
var selectedAnswers = questionList.questions[position].answers
if (radioInt > 0) {
typeIf = selectedAnswers[0].type
testValue = selectedAnswers[0].value
holder.view.txtCurrentQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtAmountQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtCurrentQuestion2.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtTitleQuestions.setTextColor(Color.parseColor("#0B6095"));
holder.view.questionsTik.visibility = View.VISIBLE
} else if (radioInt < 0) {
typeIf = selectedAnswers[1].type
testValue = selectedAnswers[1].value
holder.view.txtCurrentQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtAmountQuestion.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtCurrentQuestion2.setTextColor(Color.parseColor("#0B6095"));
holder.view.txtTitleQuestions.setTextColor(Color.parseColor("#0B6095"));
holder.view.questionsTik.visibility = View.VISIBLE
}
var absolutResultRadio = Math.abs(valueOfRadio.toInt())
// map["Q" + "_" + idIf.toString() + "_" + typeIf.toString()] = valueOfRadio
map["Q" + (position + 1).toString()] =
typeIf.toString() + "_" + absolutResultRadio * testValue
var con = maps.any { it.containsKey("Q" + (position + 1).toString()) }
if (maps.any { con == true }) {// filter
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
maps.removeIf { it.containsKey("Q" + (position + 1)) }
}
maps.add(map)
Log.i("maps", "in dare ejra mishe")
} else {
maps.add(map)
}
}
}
Log.i("mapSize", maps.toString())
Log.i("mapSize", maps.size.toString())
if (maps.size.toInt() == questionList.questions.size
) {
Log.i("maps", "Halaaaaaaaaaaa in dare ejra mishe")
Log.i("Mapss", "SomeText: " + Gson().toJson(maps))
val dataOfTestToJson = Gson().toJson(maps).toString()
val eRegex = Regex("E_(\\d+)")
val iRegex = Regex("I_(\\d+)")
val sRegex = Regex("S_(\\d+)")
val nRegex = Regex("N_(\\d+)")
val fRegex = Regex("F_(\\d+)")
val tRegex = Regex("T_(\\d+)")
val pRegex = Regex("P_(\\d+)")
val jRegex = Regex("J_(\\d+)")
e = eRegex.findAll(dataOfTestToJson).map { it.groupValues[1].toInt() }.sum()
i = iRegex.findAll(dataOfTestToJson).map { it.groupValues[1].toInt() }.sum()
s = sRegex.findAll(dataOfTestToJson).map { it.groupValues[1].toInt() }.sum()
n = nRegex.findAll(dataOfTestToJson).map { it.groupValues[1].toInt() }.sum()
f = fRegex.findAll(dataOfTestToJson).map { it.groupValues[1].toInt() }.sum()
t = tRegex.findAll(dataOfTestToJson).map { it.groupValues[1].toInt() }.sum()
p = pRegex.findAll(dataOfTestToJson).map { it.groupValues[1].toInt() }.sum()
j = jRegex.findAll(dataOfTestToJson).map { it.groupValues[1].toInt() }.sum()
val data = JSONObject()
data.put("E", e)
data.put("I", i)
data.put("S", s)
data.put("N", n)
data.put("T", t)
data.put("F", f)
data.put("J", j)
data.put("P", p)
Log.i(
"dataSexy",
data.toString()
)
Log.i(
"mapsSexy",
"I = $i" + " " + "E = $e" + " " + "S= $s" + " " + "N = $n" + " " + "F = $f" + " " + "T = $t" + " " + "P = $p" + " " + "J = $j"
)
val context = holder.view.context
val intent = Intent(context, LoadingMbtiActivity::class.java)
intent.putExtra("e", e.toString())
intent.putExtra("i", i.toString())
intent.putExtra("s", s.toString())
intent.putExtra("n", n.toString())
intent.putExtra("f", f.toString())
intent.putExtra("t", t.toString())
intent.putExtra("p", p.toString())
intent.putExtra("j", j.toString())
intent.putExtra("data", data.toString())
context.startActivity(intent)
(context as Activity).finish()
}
holder.view.txtQuestionInRow.text = question
}
override fun getItemCount(): Int {
return questionList.questions.size
}
override fun getItemViewType(position: Int): Int {
return position
}
}
class QuestionViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
}
tps://i.stack.imgur.com/aQiS4.png
class MBTITEST : AppCompatActivity() {
lateinit var token: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_mbtitest)
window.statusBarColor = ContextCompat.getColor(this, R.color.black)
val preferences: SharedPreferences =
applicationContext.getSharedPreferences("SOCIAL_PERSONALITY", Context.MODE_PRIVATE)
token = preferences.getString("TOKEN", null).toString() //second parameter default value.
var tokenBAr = "Bearer $token"
getQuestions(tokenBAr)
}
fun getQuestions(token: String) {
val apilnterface: APIInterface = APIClient().getClient()!!.create(APIInterface::class.java)
var call: Call<QuestionList> = apilnterface.getQuestions(token)
call.enqueue(object : Callback<QuestionList> {
override fun onResponse(
call: Call<QuestionList>,
response: Response<QuestionList>
) {
if (response.code() == 200) {
// Toast.makeText(
// this#MBTITEST,
// "Testatol GolMohammadi",
// Toast.LENGTH_LONG
// )
// .show()
// Log.w("RESGetID", "${response.body().toString()}")
val dataFromResponse = response.body()
val questionList = dataFromResponse?.questions
val size = questionList?.size
val title = questionList?.get(0)?.title
print(questionList)
Log.w("QuestionListDaDa", questionList.toString())
Log.w("QuestionListDaDa", size.toString())
Log.w("QuestionListDaDa", title.toString())
runOnUiThread {
val layoutManager = LinearLayoutManager(
this#MBTITEST,
LinearLayoutManager.HORIZONTAL,
false
)
recycler_questions.layoutManager = layoutManager
recycler_questions.setHasFixedSize(true)
recycler_questions.adapter?.setHasStableIds(true)
Collections.shuffle(dataFromResponse?.questions)
recycler_questions.adapter =
dataFromResponse?.let { MbtiQuestionAdapter(it) }
txtCountTotal.text = questionList?.size.toString()
var mbtiAdapter = dataFromResponse?.let { MbtiQuestionAdapter(it) }
var testnumbers = mbtiAdapter?.testnumbers
textView15.setText(testnumbers.toString())
Log.i("testnumber", testnumbers.toString())
// btnShowRes.setOnClickListener {
// // dataFromResponse?.let { MbtiQuestionAdapter(it) }?.activateButtons(true)
// val intent = Intent(this#MBTITEST, ShowTestResultActivity::class.java)
// startActivity(intent)
// finish()
// }
}
}
if (response.code() == 400) {
try {
val jObjError = JSONObject(response.errorBody()!!.string())
Toast.makeText(
applicationContext,
jObjError.getString("message"),
Toast.LENGTH_LONG
).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, e.message, Toast.LENGTH_LONG).show()
}
}
if (response.code() == 401) {
try {
val preferences: SharedPreferences =
applicationContext.getSharedPreferences(
"SOCIAL_PERSONALITY",
Context.MODE_PRIVATE
)
preferences.edit().putString("TOKEN", "").apply()
val jObjError = JSONObject(response.errorBody()!!.string())
Toast.makeText(
applicationContext,
jObjError.getString("message"),
Toast.LENGTH_LONG
).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, e.message, Toast.LENGTH_LONG).show()
val intent = Intent(this#MBTITEST, FirstPageActivity::class.java)
startActivity(intent)
finish()
}
}
}
override fun onFailure(call: Call<QuestionList>, t: Throwable) {
Toast.makeText(
this#MBTITEST,
" Register is not ok",
Toast.LENGTH_LONG
)
.show()
}
})
}
}
like what #Arpit Shukla mentioned you can pass data between adapter and activity using lambdas or functions
add a function as a parameter to your adapter's constructor
class MbtiQuestionAdapter(val questionList: QuestionList,val onRadioButtonClick : (Int) -> Unit)
in your activity define a function to update your progress bar and it takes a number as a parameter or whatever you want
private fun updateProgressBar(testNumber : Int){
//update progress bar
}
pass the above function to adapter constructor when you initialize it
recycler_questions.adapter = dataFromResponse?.let { MbtiQuestionAdapter(it){number -> updateProgressBar(number)} }
lastly call the onRadioButtonClick in your adapter when you want to pass the number to your activity
onRadioButtonClick(number)
Related
I have a viewmodel that has a method. there are 4 conditions base on 4 Buttons that each condition can run separately by viewModelScope in this method.
Now I want to stop and restart each viewModelScope separately but I don't know how.
When I cancel the viewModelScope by job1.cancel(), I can't start it again.
This is my code that I want to handle that:
fun calculateDistance(tripId: Int) = viewModelScope.launch {
var currentCost: Double = 6500.0
var partCost: Double = 0.0
while (isActive) {
localRepository.getUnCalculatedLocation(tripId).collect { result ->
if (result.data!!.isNotEmpty()) {
result.data.forEach {
var passId = 0
val distance = Calculates.distance(
lat1 = if (it.latitude1 != 0.0) it.latitude1 else it.latitudeNet1,
lat2 = if (it.latitude2 != 0.0) it.latitude2 else it.latitudeNet2,
long1 = if (it.longitude1 != 0.0) it.longitude1 else it.longitudeNet1,
long2 = if (it.longitude2 != 0.0) it.longitude2 else it.longitudeNet2
)
localRepository.getPassId(it.tripId!!.toInt()).collect { id ->
if (id.data != null) {
passId = id.data
}
}
var passDistance = PassengerDistance(passId, distance)
_passDistance.postValue(passDistance)
localRepository.updateLocation(distance, it.id)
var uniqueId = ""
localRepository.getUniqueId(it.tripId).collect { uid ->
uniqueId = uid.data!!
}
when (passId) {
1 -> {
job1.launch {
_tripTime1.postValue(_tripTime1.value?.plus(2000))
if (distance == 0.0) {
if (secondCost1 < 10) secondCost1 += 2
else {
val expression: Expression =
Expression(_formula.value?.stoppingFormula)
val resultCost: EvaluationValue =
expression.with("T", secondCost1).evaluate()
currentCost =
if (_costPass1.value == null) constCost.toDouble() else _costPass1.value!!
partCost = resultCost.numberValue.toDouble()
_costPass1.postValue(resultCost.numberValue.toDouble() + currentCost)
secondCost1 = 0
}
} else {
val expression: Expression =
Expression(_formula.value?.movingFormula)
val resultCost: EvaluationValue =
expression.with("D", distance * 1000).evaluate()
val resultTest = (2109 / 200) * distance
currentCost =
if (_costPass1.value == null) constCost.toDouble() else _costPass1.value!!
partCost = resultCost.numberValue.toDouble()
var two = partCost * 2
Log.d(
"DISTANCE",
"actual cost is $partCost , Test: $resultTest"
)
_costPass1.postValue((resultCost.numberValue.toDouble() * 2) + currentCost)
_tripDistance1.postValue(
_tripDistance1.value?.plus(
distance
)
)
}
localRepository.updateCurrentCost(partCost, it.id!!)
val saveLocation = TripDetails(
id = it.id,
latitude1 = it.latitude1,
latitude2 = it.latitude2,
longitude1 = it.longitude1,
longitude2 = it.longitude2,
accuracy1 = it.accuracy1,
accuracy2 = it.accuracy2,
latitudeNet1 = it.latitudeNet1,
latitudeNet2 = it.latitudeNet2,
longitudeNet1 = it.longitudeNet1,
longitudeNet2 = it.longitudeNet2,
accuracy1Net = it.accuracy1Net,
accuracy2Net = it.accuracy2Net,
tripId = it.tripId,
distance = distance,
isCalculated = true,
isEnded = it.isEnded,
date = it.date,
cost = partCost,
uniqueId = uniqueId,
isMonitor = _isMonitor.value!!,
driverId = _driver.value?.data?.driverId!!
)
try {
repository.saveLocation(saveLocation).let { result ->
if (result.isSuccessful) {
Log.d("TAG", result.body()?.result.toString())
} else {
Log.d("TAG", result.body()?.message!!)
}
}
} catch (e: Exception) {
Log.d("Error", e.message.toString())
}
}
}
2 -> {
job2.launch {
_tripTime2.postValue(_tripTime2.value?.plus(2000))
if (distance == 0.0) {
if (secondCost2 < 10) secondCost2 += 2
else {
val expression: Expression =
Expression(_formula.value?.stoppingFormula)
val resultCost: EvaluationValue =
expression.with("T", secondCost2).evaluate()
currentCost =
if (_costPass2.value == null) constCost.toDouble() else _costPass2.value!!
_costPass2.postValue(resultCost.numberValue.toDouble() + currentCost)
partCost = resultCost.numberValue.toDouble()
secondCost2 = 0
}
} else {
val expression: Expression =
Expression(_formula.value?.movingFormula)
val resultCost: EvaluationValue =
expression.with("D", distance * 1000).evaluate()
currentCost =
if (_costPass2.value == null) constCost.toDouble() else _costPass2.value!!
_costPass2.postValue(resultCost.numberValue.toDouble() + currentCost)
partCost = resultCost.numberValue.toDouble()
_tripDistance2.postValue(_tripDistance2.value?.plus(distance))
}
val saveLocation = TripDetails(
id = it.id,
latitude1 = it.latitude1,
latitude2 = it.latitude2,
longitude1 = it.longitude1,
longitude2 = it.longitude2,
accuracy1 = it.accuracy1,
accuracy2 = it.accuracy2,
latitudeNet1 = it.latitudeNet1,
latitudeNet2 = it.latitudeNet2,
longitudeNet1 = it.longitudeNet1,
longitudeNet2 = it.longitudeNet2,
accuracy1Net = it.accuracy1Net,
accuracy2Net = it.accuracy2Net,
tripId = it.tripId,
distance = distance,
isCalculated = true,
isEnded = it.isEnded,
date = it.date,
cost = partCost,
uniqueId = uniqueId,
isMonitor = _isMonitor.value!!,
driverId = _driver.value?.data?.driverId!!
)
try {
repository.saveLocation(saveLocation).let { result ->
if (result.isSuccessful) {
Log.d("TAG", result.body()?.result.toString())
} else {
Log.d("TAG", result.body()?.message!!)
}
}
} catch (e: Exception) {
Log.d("Error", e.message.toString())
}
}
}
3 -> {
job3.launch {
_tripTime3.postValue(_tripTime3.value?.plus(2000))
if (distance == 0.0) {
if (secondCost3 < 10) secondCost3 += 2
else {
val expression: Expression =
Expression(_formula.value?.stoppingFormula)
val resultCost: EvaluationValue =
expression.with("T", secondCost3).evaluate()
currentCost =
if (_costPass3.value == null) constCost.toDouble() else _costPass3.value!!
_costPass3.postValue(resultCost.numberValue.toDouble() + currentCost)
partCost = resultCost.numberValue.toDouble()
secondCost3 = 0
}
} else {
val expression: Expression =
Expression(_formula.value?.movingFormula)
val resultCost: EvaluationValue =
expression.with("D", distance * 1000).evaluate()
currentCost =
if (_costPass3.value == null) constCost.toDouble() else _costPass3.value!!
_costPass3.postValue(resultCost.numberValue.toDouble() + currentCost)
partCost = resultCost.numberValue.toDouble()
_tripDistance3.postValue(_tripDistance3.value?.plus(distance))
}
val saveLocation = TripDetails(
id = it.id,
latitude1 = it.latitude1,
latitude2 = it.latitude2,
longitude1 = it.longitude1,
longitude2 = it.longitude2,
accuracy1 = it.accuracy1,
accuracy2 = it.accuracy2,
latitudeNet1 = it.latitudeNet1,
latitudeNet2 = it.latitudeNet2,
longitudeNet1 = it.longitudeNet1,
longitudeNet2 = it.longitudeNet2,
accuracy1Net = it.accuracy1Net,
accuracy2Net = it.accuracy2Net,
tripId = it.tripId,
distance = distance,
isCalculated = true,
isEnded = it.isEnded,
date = it.date,
cost = partCost,
uniqueId = uniqueId,
isMonitor = _isMonitor.value!!,
driverId = _driver.value?.data?.driverId!!
)
try {
repository.saveLocation(saveLocation).let { result ->
if (result.isSuccessful) {
Log.d("TAG", result.body()?.result.toString())
} else {
Log.d("TAG", result.body()?.message!!)
}
}
} catch (e: Exception) {
Log.d("Error", e.message.toString())
}
}
}
4 -> {
job4.launch {
_tripTime4.postValue(_tripTime4.value?.plus(2000))
if (distance == 0.0) {
if (secondCost4 < 10) secondCost4 += 2
else {
val expression: Expression =
Expression(_formula.value?.stoppingFormula)
val resultCost: EvaluationValue =
expression.with("T", secondCost4).evaluate()
currentCost =
if (_costPass4.value == null) constCost.toDouble() else _costPass4.value!!
_costPass4.postValue(resultCost.numberValue.toDouble() + currentCost)
partCost = resultCost.numberValue.toDouble()
secondCost4 = 0
}
} else {
val expression: Expression =
Expression(_formula.value?.movingFormula)
val resultCost: EvaluationValue =
expression.with("D", distance * 1000).evaluate()
currentCost =
if (_costPass4.value == null) constCost.toDouble() else _costPass4.value!!
_costPass4.postValue(resultCost.numberValue.toDouble() + currentCost)
partCost = resultCost.numberValue.toDouble()
_tripDistance4.postValue(_tripDistance4.value?.plus(distance))
}
val saveLocation = TripDetails(
id = it.id,
latitude1 = it.latitude1,
latitude2 = it.latitude2,
longitude1 = it.longitude1,
longitude2 = it.longitude2,
accuracy1 = it.accuracy1,
accuracy2 = it.accuracy2,
latitudeNet1 = it.latitudeNet1,
latitudeNet2 = it.latitudeNet2,
longitudeNet1 = it.longitudeNet1,
longitudeNet2 = it.longitudeNet2,
accuracy1Net = it.accuracy1Net,
accuracy2Net = it.accuracy2Net,
tripId = it.tripId,
distance = distance,
isCalculated = true,
isEnded = it.isEnded,
date = it.date,
cost = partCost,
uniqueId = uniqueId,
isMonitor = _isMonitor.value!!,
driverId = _driver.value?.data?.driverId!!
)
try {
repository.saveLocation(saveLocation).let { result ->
if (result.isSuccessful) {
Log.d("TAG", result.body()?.result.toString())
} else {
Log.d("TAG", result.body()?.message!!)
}
}
} catch (e: Exception) {
Log.d("Error", e.message.toString())
}
}
}
}
}
}
}
delay(2000)
}
}
Here there is a when statement that has 4 conditions. There are 4 Buttons for each conditions.
The a
The code is complicated. It's hard to understand the workflow.
If you want to run a new job for the phase and cancel it for some reason.
You have to create a new Job for each phase.
1 -> {
job1 = viewModelScope.launch {
...
4 -> {
job4 = viewModelScope.launch {
UPDATE based on comments:
In your code you define variables:
val job1 = viewModelScope
val job2 = viewModelScope
...
This is not a job definition, this is just a new variables with reference to the viewModelScope.
So when you call job1.cancel() it equals to call viewModelScope.cancel(). The result the viewModelScope is canceled and no coroutine can be started.
To change it you can refactor your code to use a job:
#field:Volatile
var job1: Job? = null
#field:Volatile
var job2: Job? = null
...
Create a new job for the each phase in fun calculateDistance(tripId: Int):
1 -> {
job1 = viewModelScope.launch {
2 -> {
job2 = viewModelScope.launch {
To cancel a job in the other code you have to use the following code:
job1?.cancel()
I am currently creating a chart to display statistics.
The problem is that on the combinedChart I can't display the lineDataChart
The expected result is this
The second image is the superposition of a barChart and a lineChart but the problem is i can't use properly the scroll mode because it will only scroll on one graph.
Here is the code for the first graph
class GraphCombinedChart (context: Context) : CombinedChart(context, null, 0) {
private var chart: CombinedChart? = null
private fun dtoToBarEntry(floats: List<Float>?) : ArrayList<BarEntry> {
return ArrayList<BarEntry>().apply {
floats?.forEachIndexed { index, fl ->
add(BarEntry((index + 1).toFloat() , fl))
}
}
}
private fun dtoToEntry(floats: List<Float>?) : ArrayList<Entry> {
return ArrayList<Entry>().apply {
floats?.forEachIndexed { index, fl ->
add(Entry((index + 1).toFloat() , fl))
}
}
}
fun setupChart(
values: List<PlayerGraphStatModel>?,
landScapeMode: Boolean = false
) {
val indexPerformanceList = dtoToEntry(values?.map { it.timePlayed.toFloat() }?.plus(values.map { it.timePlayed.toFloat() }))
val timePlayedList = dtoToBarEntry( values?.map { it.indexPerf }?.plus(values.map { it.indexPerf }))
val entryData = LineData(LineDataSet(indexPerformanceList, "").apply {
color = Color.White.hashCode()
setDrawValues(true)
})
val barEntryData = BarData(BarDataSet(timePlayedList, "").apply {
color = Color.AiaRed.hashCode()
setDrawValues(false)
})
val combinedData = CombinedData()
combinedData.setData(barEntryData)
combinedData.setData(entryData)
chart = this
formatChart(combinedData, landScapeMode)
configureXAxis()
configureYAxis()
chart?.renderer = BarChartRenderer(chart, chart?.animator, chart?.viewPortHandler)
}
private fun formatChart(combinedData: CombinedData, landScapeMode: Boolean = false) {
val barWidth = 0.75f
chart?.drawOrder = arrayOf(
DrawOrder.LINE,
DrawOrder.BAR,
DrawOrder.LINE,
)
chart?.data = combinedData
chart?.description?.isEnabled = false
chart?.legend?.isEnabled = false
chart?.barData?.barWidth = barWidth
chart?.animateY(1000)
chart?.isDoubleTapToZoomEnabled = false
chart?.setScaleEnabled(false)
chart?.isHorizontalScrollBarEnabled = true
// barChart?.setVisibleXRangeMaximum(8f)
// barChart?.moveViewToX(0f)
if (!landScapeMode) {
chart?.setVisibleXRangeMaximum(8f)
chart?.moveViewToX(11f)
}
chart?.resetViewPortOffsets()
chart?.resetZoom()
chart?.notifyDataSetChanged()
}
private fun configureXAxis() {
chart?.xAxis?.apply {
setDrawGridLines(false)
setDrawAxisLine(false)
setDrawLabels(true)
position = XAxis.XAxisPosition.BOTTOM
valueFormatter = MyXAxisFormatter()
granularity = 1f
labelRotationAngle = +0f
textColor = Color.White.hashCode()
textSize = 12f
textAlignment = TEXT_ALIGNMENT_CENTER
axisMinimum = data.xMin - 0.75f
axisMaximum = data.xMax + 0.75f
disableScroll()
}
}
private fun configureYAxis() {
chart?.axisRight?.apply {
setDrawGridLines(false)
legend?.isEnabled = true
isEnabled = false
}
chart?.axisLeft?.apply {
setAxisMinValue(0f)
setAxisMaxValue(100f)
valueFormatter = MyLeftAxisFormatter()
setDrawGridLines(true)
setDrawAxisLine(true)
textColor = Color.White.hashCode()
textSize = 14f
}
}
inner class MyXAxisFormatter : IndexAxisValueFormatter() {
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
return "${value.toInt()}"
}
}
inner class MyLeftAxisFormatter : IndexAxisValueFormatter() {
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
return "${value.toInt()}"
}
}
}
I have checked and the data is not empty.
Thank you for your help!
Now i am writing my small molar mass calculator and i can't fix one bug. In MainActivity.kt i fill array from my .xml file, after that i use Regex to parse user input. BUT if i type, for example "C" (carbon) in my program it doesn't recognize it. WHY?
MainActivity.kt:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adapter = MoleculeAdapter(this)
moleculeView.layoutManager = LinearLayoutManager(this)
moleculeView.setHasFixedSize(true)
moleculeView.adapter = adapter
val parser = resources.getXml(R.xml.elements)
val elements = Array(127) { Element() }
thread {
var i = 0
while (parser.eventType != END_DOCUMENT) {
if (parser.eventType == START_TAG && parser.name == "element") {
elements[i].number = parser.getAttributeIntValue(null, "number", 0)
elements[i].letter = parser.getAttributeValue(null, "letter")
elements[i].name = parser.getAttributeValue(null, "name")
val weight = parser.getAttributeValue(null, "weight")
elements[i].weight = if (weight.isNotEmpty()) weight.toFloat() else 0F
i++
}
parser.next()
}
parser.close()
}.join()
Log.i("elements:", elements.joinToString { it.toString() + "\n" })
val lowerCaseLetters = "abcdefghiklmnopqrstuy"
val elementsRegex = Regex("""[ABCDEFGHIKLMNOPRSTUVWXYZ]([$lowerCaseLetters]{2}|[$lowerCaseLetters]?)\d*""")
val digitsRegex = Regex("""\d+""")
formulaInput.doOnTextChanged { text, _, _, _ ->
lateinit var foundedElements: List<Element>
thread {
foundedElements = elementsRegex
.findAll(text ?: "")
.map {
elements.find { element ->
Log.i("value", it.value + " " + it.value)
if (it.value.filter { it.isLetter() } == element.letter) {
val number = digitsRegex.find(it.value)
if (number != null) {
try {
element.moleculeCount = number.value.toInt()
element.weight = element.weight * number.value.toInt()
} catch (e: NumberFormatException) { }
}
element.percentage = adapter.getTotalWeight(element.weight) * 100
true
} else false
}
}.filterNotNull().toList()
}.join()
adapter.insertElements(foundedElements)
}
}
}
Element.kt:
data class Element(var number: Int = -1,
var letter: String = "",
var name: String = "",
var weight: Float = 0F,
var percentage: Float = 100F,
var moleculeCount: Int = 1)
xml file item example:
<element
number="6"
letter="С"
name="Углерод"
weight="12.011" />
I can't believe it, in my xml file letter "С" was a cyrillic letter "C" (\u0421)! And because of this equals check "С" == "C" was failing.
Huge Thanks to Wiktor Stribiżew for his comment.
I need to download images from AWS S3 and update ImageViews inside a recycler view. I am using ViewModel for downloading files from S3. A file object is observing inside onBindViewHolder() method and once receive the file my intention was to update the image belongs with that particular holder.
But the problem is if there were two rows, then two images need to download. So each view holder will attach with the observer. After downloading the first file, both the image views inside the recycler view become updated with the first image and after downloading the second image, both images updated with the second image. I am a little bit confuse about working. Please help me with this.
I cannot use Glide for this. Because S3 have authentication. So, I need to use S3 library for downloading files.
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
val postUrl = listData[position].postUrl
val createdAt = listData[position].createdAt
val postImage = listData[position].postImage
val postVideo = listData[position].postVideo
val postVideoThumbnail = listData[position].postVideoThumbnail
val groupId = listData[position].groupId
val postStatus = listData[position].postStatus
val postId = listData[position].postId
val userId = listData[position].userId
val postHeading = listData[position].postHeading
val postDescription = listData[position].postDescription
val updatedAt = listData[position].updatedAt
val profileName = listData[position].userName
val profileImage = listData[position].profileImage
val likeCount = listData[position].likeCount
val commentCount = listData[position].commentCount
var key = ""
if(!profileImage.isNullOrEmpty()){
Glide.with(activity).load(profileImage) to holder.imgProfile
}
holder.textName.text = profileName.substring(0, 1).toUpperCase() + profileName.substring(1).toLowerCase()
holder.textPostedDateTime.text = SimpleDateFormat(POST_LIST_DATE_FORMAT).format(Date(createdAt))
holder.textPostHeading.text = postHeading
if(postDescription.isNullOrEmpty() || postDescription == "null"){
holder.textPostDescription.visibility = View.GONE
} else{
holder.textPostDescription.visibility = View.VISIBLE
holder.textPostDescription.text = postDescription
}
if(postUrl.isNullOrEmpty() || postUrl == "null"){
holder.textPostLink.visibility = View.GONE
} else{
holder.textPostLink.visibility = View.VISIBLE
holder.textPostLink.text = postUrl
}
if(postVideoThumbnail.isNullOrEmpty() || postVideoThumbnail == "null"){
holder.imgPostVideoPreview.visibility = View.GONE
} else{
holder.imgPostVideoPreview.visibility = View.VISIBLE
loadImageToFile(holder.imgPostVideoPreview, postVideoThumbnail, position)
key = postVideoThumbnail
}
if(postImage.isNullOrEmpty() || postImage == "null"){
holder.imgPostImagePreview.visibility = View.GONE
} else{
holder.imgPostImagePreview.visibility = View.VISIBLE
loadImageToFile(holder.imgPostImagePreview, postImage, position)
key = postImage
}
holder.textLikeCount.text = likeCount.toString()
holder.textCommentCount.text = commentCount.toString()
if(!isSelfPosts){
holder.layoutCommentLikeShare.visibility = View.VISIBLE
holder.imgAddComment.setOnClickListener { }
holder.imgAddLike.setOnClickListener { }
holder.imgShare.setOnClickListener { }
}
holder.itemView.setOnClickListener {
moveTOPostDetails(postId, listData[position], Environment.getExternalStorageDirectory().path + "/" + EXTERNAL_STORAGE_FOLDER_NAME + "/" + key.substring(key.lastIndexOf("/")+1))
}
}
class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val imgProfile: ImageView = itemView.imgProfile
val textName: TextView = itemView.textName
val textPostedDateTime: TextView = itemView.textPostedDateTime
val textPostHeading: TextView = itemView.textPostHeading
val textPostDescription: TextView = itemView.textPostDescription
val textPostLink: TextView = itemView.textPostLink
val imgPostVideoPreview: ImageView = itemView.imgPostVideoPreview
val imgPostImagePreview: ImageView = itemView.imgPostImagePreview
val textCommentCount: TextView = itemView.textCommentCount
val textLikeCount: TextView = itemView.textLikeCount
val layoutCommentLikeShare: LinearLayout = itemView.layoutCommentLikeShare
val imgAddComment: ImageView = itemView.imgAddComment
val imgAddLike: ImageView = itemView.imgAddLike
val imgShare: ImageView = itemView.imgShare
}
private fun moveTOPostDetails(postId: String, fetchPostsResponseModel: FetchPostsResponseModel, imageFileName: String){
val intent = Intent(activity, PostDetails::class.java)
intent.putExtra("POST_DETAILS", fetchPostsResponseModel)
intent.putExtra("IS_SELF_POST", isSelfPosts)
intent.putExtra("IMAGE_FILE_NAME", imageFileName)
activity.startActivity(intent)
}
private fun loadImageToFile(imageView: ImageView, key: String, position: Int){
var postListAdapterViewModel: PostListAdapterViewModel = ViewModelProviders.of(fragment).get(PostListAdapterViewModel::class.java)
postListAdapterViewModel.init(activity)
postListAdapterViewModel.getMediaFile()?.observe(fragment, Observer<File>{ file ->
var a=position
imageView.setImageURI(Uri.fromFile(file))
} )
postListAdapterViewModel.performDownload(key)
}
This is my viewmodel
class PostListAdapterViewModel(application: Application):AndroidViewModel(application){
private val file = MutableLiveData<File>()
private lateinit var context: Context
fun init(context: Context) {
this.context = context
AWSMobileClient.getInstance().initialize(context).execute()
}
fun performDownload(key : String){
val credentials = BasicAWSCredentials(AMAZON_S3_ACCESS_KEY, AMAZON_S3_SECRET_KEY)
val s3Client = AmazonS3Client(credentials)
val transferUtility = TransferUtility.builder()
.context(context)
.awsConfiguration(AWSMobileClient.getInstance().configuration)
.s3Client(s3Client)
.build()
val downloadObserver = transferUtility.download (
key,
File(Environment.getExternalStorageDirectory().path + "/" + EXTERNAL_STORAGE_FOLDER_NAME + "/" + key.substring(key.lastIndexOf("/")+1)))
// Attach a listener to get state updates
downloadObserver.setTransferListener(object : TransferListener {
override fun onStateChanged(id: Int, state: TransferState) {
if (state == TransferState.COMPLETED) {
// Handle a completed upload.
file.value = File(Environment.getExternalStorageDirectory().path + "/" + EXTERNAL_STORAGE_FOLDER_NAME + "/" + key.substring(key.lastIndexOf("/")+1))
}
}
override fun onProgressChanged(id: Int, current: Long, total: Long) {
try {
val done = (((current.toDouble() / total) * 100.0).toInt()) //as Int
Log.d("PostListAdapterVM", "DOWNLOAD - - ID: $id, percent done = $done")
}
catch (e: Exception) {
Log.e("PostListAdapterVM", "Trouble calculating progress percent", e)
}
}
override fun onError(id: Int, ex: Exception) {
Log.d("PostListAdapterVM", "DOWNLOAD ERROR - - ID: $id - - EX: ${ex.message.toString()}")
}
})
// If you prefer to poll for the data, instead of attaching a
// listener, check for the state and progress in the observer.
if (downloadObserver.state == TransferState.COMPLETED) {
// Handle a completed upload.
}
Log.d("PostListAdapterVM", "Bytes Transferrred: ${downloadObserver.bytesTransferred}")
}
fun getMediaFile(): MutableLiveData<File> {
return file
}
}
I am working on an android project in which I want to remove the item from vertical recycler view by swiping an item to right or left. As far as it comes to deleting the item, I am able to do that correctly. The issue arises after I delete the item and call notifyDataSetChanged().
Now while refreshing items, Adapter uses previous view holders to display cards. But while deleting an item I displaced some of its layouts to left and right. So when new item occupies the same view holder all the translation is preserved and
some views of the new item are thus created out of bounds of the screen(as I displaced that view holder while deleting the previous item that occupied that spot).
So my question is (solution to any one of the following will solve the issue I am facing),
Is there "free" function like c++ in Java? So that I can free that view holder.
How to make sure that recycler view doesn't reuse particular view holder?
How to reset layout of to the original state before all animations were done? So that I can just reset all translations
Thank you.
Edits:
Below are the codes for adapter and view holder if someone wants to have a look at them.
As view holder is too large to understand directly, SO here is summery for functions used in it:
init -> just set on click listener.
updateUI -> sets some more listener and set text and other fields from card.
pressDown -> is called when MotionEvent.ACTION_DOWN.
pressUP -> is called when MotionEvent.ACTION_UP.
animateViewDisappear -> listener for animation.
archive -> delete an element and tell adapter data is change.
pressMove -> sense when motion happens after clicking button.
toggleShowHideView -> change visibility of some view.
closeOpenedLayout -> Close some expanded layouts.
Adapter:
class LocalAdapter(var localCardsInfo : ArrayList<LocalModel>?,var fragment: LocalListingFragment) : RecyclerView.Adapter<LocalHolder>() {
fun refreshDataOnOrientationChange(mLocalCards : ArrayList<LocalModel>?){
if (localCardsInfo!!.size>0)
localCardsInfo!!.clear()
localCardsInfo = mLocalCards
notifyDataSetChanged()
}
override fun getItemCount(): Int {
return localCardsInfo!!.size
}
override fun onBindViewHolder(holder: LocalHolder, position: Int) {
if (localCardsInfo!=null)
holder.updateUI(position,localCardsInfo!![position])
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocalHolder {
val card_a : View = LayoutInflater.from(parent.context).inflate(R.layout.card_local_a,parent,false)
return LocalHolder(card_a,fragment)
}
}
view holder:
class LocalHolder(itemView : View,val fragment: LocalListingFragment) : RecyclerView.ViewHolder(itemView),OpenedLayoutManagerLocal{
private val TAG = "iotcontrollerapp.#Debug"
private var _xDelta: Float = 0f
private var originalDelta : Float = 0f
private var directionOut1 = false
private var directionOut = false
private var previousX = 0f
var isFavourite : Boolean = false
var isPropertyPanelOpen : Boolean = false
val deviceName : TextView = itemView.findViewById(R.id.deviceNameLocal)
val deviceRoom : TextView = itemView.findViewById(R.id.deviceRoomLocal)
val deviceOnOff : TextView = itemView.findViewById(R.id.deviceOnOffLocal)
val showHideLayout : LinearLayout = itemView.findViewById(R.id.showHideLayoutLocal)
val showHideProperties : TextView = itemView.findViewById(R.id.showHidePropertiesLocal)
val showHideButton : ImageView = itemView.findViewById(R.id.showHideButtonLocal)
val favouriteButton : ImageButton = itemView.findViewById(R.id.imageFavouriteButtonLocal)
val moveButton : MoveableViewImageButton = itemView.findViewById(R.id.imageMoveButtonLocal)
val changeFragmentToDetail : Button = itemView.findViewById(R.id.changePropertiesLocal)
val layoutForProperties : LinearLayout = itemView.findViewById(R.id.layoutForPropertyLocal)
val baseForProperties : LinearLayout = itemView.findViewById(R.id.baseForPropertyLocal)
private var model : LocalModel? = null
init {
itemView.elevation = 0f
showHideLayout.setOnClickListener({
isPropertyPanelOpen = !isPropertyPanelOpen
if (isPropertyPanelOpen){
if (openedLayoutManagerLocal != this)
openedLayoutManagerLocal?.closeOpenedLayout()
openedLayoutManagerLocal = this
showHideProperties.text = fragment.getString(R.string.close_property_panel)
showHideButton.setImageResource(R.drawable.animated_more_button_local)
}
else{
showHideProperties.text = fragment.getString(R.string.open_property_panel)
showHideButton.setImageResource(R.drawable.animated_more_button_reverse_local)
}
val mDrawable = showHideButton.drawable
if (mDrawable is Animatable)
{
(mDrawable as Animatable).start()
}
toggleShowHideView()
})
}
fun changeFavouriteButtonState(localModel: LocalModel){
isFavourite = !isFavourite
if (isFavourite){
favouriteButton.setImageResource(R.drawable.avd_heart_fill)
val a = favouriteButton.drawable
if(a is Animatable){
a.start()
}
ALL_STATIC_CONSTANTS_AND_METHODS.saveIsFavourite(fragment.activity as Context,localModel.roomName.trim() + "$" + localModel.deviceName,true)
}
else{
favouriteButton.setImageResource(R.drawable.avd_heart_break)
val a = favouriteButton.drawable
if(a is Animatable){
a.start()
}
ALL_STATIC_CONSTANTS_AND_METHODS.saveIsFavourite(fragment.activity as Context,localModel.roomName.trim() + "$" + localModel.deviceName,false)
}
}
fun updateUI(position : Int , localModel: LocalModel){
itemView.elevateLayoutLocal.visibility = View.VISIBLE
itemView.archiveLayout.visibility = View.VISIBLE
model = localModel
originalDelta = itemView.elevateLayoutLocal.x
changeFragmentToDetail.setOnClickListener({
fragment.handlerForDetail.sendEmptyMessage(position)
})
favouriteButton.setOnClickListener({
changeFavouriteButtonState(localModel)
})
moveButton.setOnTouchListener({v: View?, event: MotionEvent? ->
if (v == null || event == null) return#setOnTouchListener true
when (event.action){
MotionEvent.ACTION_UP -> {
v.performClick()
pressUP(v,event)
}
MotionEvent.ACTION_DOWN -> {
pressDown(v,event)
}
MotionEvent.ACTION_MOVE -> {
pressMove(v,event)
}
else -> {
Log.e(TAG,"Something happened")
}
}
return#setOnTouchListener true
})
isFavourite = (ALL_STATIC_CONSTANTS_AND_METHODS.getIsFavourite(fragment.activity as Context,localModel.roomName.trim() + "$" + localModel.deviceName) ?: false)
favouriteButton.setImageResource(if (isFavourite) R.drawable.vd_trimclip_heart_full else R.drawable.vd_trimclip_heart_empty)
deviceRoom.text = localModel.roomName.split("_").dropLast(1).toTypedArray().joinToString(" ")
deviceName.text = localModel.deviceName.split("_").dropLast(1).toTypedArray().joinToString(" ")
deviceOnOff.text = if (localModel.isON) fragment.getString(R.string.device_on_off_on) else fragment.getString(R.string.device_on_off_off)
val components = localModel.componentName.split(" ")
val value = localModel.value.split(" ")
val maxValue = localModel.maxValue.split(" ")
val minValue = localModel.minValue.split(" ")
if (layoutForProperties.childCount > 0)
layoutForProperties.removeAllViews()
if (components.size == value.size && minValue.size == maxValue.size && components.size == minValue.size){
for (i in 0 until components.size){
val layout : LinearLayout = LinearLayout.inflate(fragment.activity , R.layout.card_local_b , null) as LinearLayout
layout.findViewById<TextView>(R.id.propertyLocal).text = components[i].replace("_"," ")
layout.findViewById<TextView>(R.id.valueLocal).text = value[i]
layout.findViewById<TextView>(R.id.rangeLocal).text = minValue[i] + " to " + maxValue[i]
layoutForProperties.addView(layout)
}
}
}
private fun pressDown(imageButton: View, event: MotionEvent){
fragment.mLayoutManager?.setScrollEnabled(false)
openedLayoutManagerLocal?.closeOpenedLayout()
_xDelta = itemView.elevateLayoutLocal.x - event.rawX
}
private fun pressUP(imageButton: View, event: MotionEvent){
Log.e(TAG,"itemView.elevateLayoutLocal.x :: ${(itemView.elevateLayoutLocal.width / 3.toFloat()) - itemView.elevateLayoutLocal.x}")
val status = (itemView.elevateLayoutLocal.width / 3.toFloat()) < itemView.elevateLayoutLocal.x
val status1 = (itemView.elevateLayoutLocal.width / 2.toFloat()) < itemView.elevateLayoutLocal.x
itemView.elevateLayoutLocal.animate()
.x(if ((directionOut && status) || (status1 && directionOut1)) itemView.elevateLayoutLocal.width.toFloat() else originalDelta)
.setDuration(100)
.setListener(object : Animator.AnimatorListener{
override fun onAnimationCancel(animation: Animator?) {
if ((directionOut && status) || (status1 && directionOut1)) {
itemView.elevateLayoutLocal.visibility = View.GONE
val anim = ValueAnimator.ofInt(itemView.archiveLayout.measuredHeight, 0)
anim.addUpdateListener { valueAnimator ->
val `val` = valueAnimator.animatedValue as Int
val layoutParams = itemView.archiveLayout.layoutParams
layoutParams.height = `val`
itemView.archiveLayout.layoutParams = layoutParams
}
anim.addListener(animateViewDisappear(this#LocalHolder))
anim.duration = 1000
anim.start()
}else{
fragment.mLayoutManager?.setScrollEnabled(true)
}
}
override fun onAnimationEnd(animation: Animator?) {
if ((directionOut && status) || (status1 && directionOut1)) {
itemView.elevateLayoutLocal.visibility = View.GONE
val anim = ValueAnimator.ofInt(itemView.archiveLayout.measuredHeight, 0)
anim.addUpdateListener { valueAnimator ->
val `val` = valueAnimator.animatedValue as Int
val layoutParams = itemView.archiveLayout.layoutParams
layoutParams.height = `val`
itemView.archiveLayout.layoutParams = layoutParams
}
anim.addListener(animateViewDisappear(this#LocalHolder))
anim.duration = 1000
anim.start()
}else{
fragment.mLayoutManager?.setScrollEnabled(true)
}
}
override fun onAnimationRepeat(animation: Animator?) {
}
override fun onAnimationStart(animation: Animator?) {
}
}).start()
}
class animateViewDisappear(var i : LocalHolder) :Animator.AnimatorListener {
override fun onAnimationCancel(animation: Animator?) {
i.itemView.archiveLayout.visibility = View.GONE
i.itemView.elevateLayoutLocal.visibility = View.GONE
i.itemView.elevateLayoutLocal.x = i.originalDelta
val layoutParams = i.itemView.archiveLayout.layoutParams
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
i.itemView.archiveLayout.layoutParams = layoutParams
i.archived()
}
override fun onAnimationEnd(animation: Animator?) {
i.itemView.archiveLayout.visibility = View.GONE
i.itemView.elevateLayoutLocal.visibility = View.GONE
i.itemView.elevateLayoutLocal.x = i.originalDelta
val layoutParams = i.itemView.archiveLayout.layoutParams
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
i.itemView.archiveLayout.layoutParams = layoutParams
i.archived()
}
override fun onAnimationRepeat(animation: Animator?) {
}
override fun onAnimationStart(animation: Animator?) {
}
}
private fun archived(){
fragment.mLayoutManager?.setScrollEnabled(true)
if (model != null) {
ALL_STATIC_CONSTANTS_AND_METHODS.addToArchive(fragment.activity!!, model!!.roomName, model!!.deviceName)
fragment.mAdapter?.refreshDataOnOrientationChange(LocalDataService.ourInstance.getNonArchivedItems(fragment.activity!!))
}
}
private fun pressMove(imageButton: View, event: MotionEvent){
directionOut1 = itemView.elevateLayoutLocal.x >= (previousX)
directionOut = itemView.elevateLayoutLocal.x >= (previousX + 20)
previousX = itemView.elevateLayoutLocal.x
fragment.mLayoutManager?.setScrollEnabled(false)
itemView.elevateLayoutLocal.animate()
.x(event.rawX + _xDelta)
.setDuration(0)
.start()
}
fun toggleShowHideView(){
changeFragmentToDetail.visibility = if (isPropertyPanelOpen) View.VISIBLE else View.GONE
layoutForProperties.visibility = if (isPropertyPanelOpen) View.VISIBLE else View.GONE
baseForProperties.visibility = if (isPropertyPanelOpen) View.VISIBLE else View.GONE
}
override fun closeOpenedLayout() {
if (isPropertyPanelOpen){
isPropertyPanelOpen = !isPropertyPanelOpen
showHideProperties.text = fragment.getString(R.string.open_property_panel)
showHideButton.setImageResource(R.drawable.animated_more_button_reverse_local)
val mDrawable = showHideButton.drawable
if (mDrawable is Animatable)
{
(mDrawable as Animatable).start()
}
toggleShowHideView()
}
}
companion object {
var openedLayoutManagerLocal : OpenedLayoutManagerLocal? = null
}
}