'An unexpected packet was received before the handshake. Dynamic EditTexts/Objectives two-way data binding
Trying to make two way data binding on dynamic objectives in row_add_objectives.xml Got rid of all the red squigglies, but it keeps crashing :c What is the order of things that happens in handshake, and where would I start to look for the aforementioned unexpected packet?
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
private var parentLinearLayout: LinearLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//setContentView(R.layout.activity_main)
setSupportActionBar(binding.toolbar)
////////////////added after///////////////// theres one more slash on rh
val button: Button = findViewById(R.id.btnGOTOQuestScreen)
button.setOnClickListener {
val intent = Intent(this@MainActivity, QuestScreenActivity::class.java)
startActivity(intent)
}
////////////////////////////////////////////
val navController = findNavController(R.id.nav_host_fragment_content_main)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
parentLinearLayout = findViewById(R.id.parent_linear_layout)
binding.fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val languages = resources.getStringArray(R.array.Languages)
// access the spinner
val spinner = findViewById<Spinner>(R.id.spinner)
if (spinner != null) {
val adapter = ArrayAdapter(this,
android.R.layout.simple_spinner_item, languages)
spinner.adapter = adapter
spinner.onItemSelectedListener = object :
AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>,
view: View, position: Int, id: Long) {
Toast.makeText(this@MainActivity,
getString(R.string.selected_item) + " " +
"" + languages[position], Toast.LENGTH_SHORT).show()
}
override fun onNothingSelected(parent: AdapterView<*>) {
// write code to perform some action
}}}}
fun onDelete(view: View) {
parentLinearLayout!!.removeView(view.parent as View)
}
fun onAddField(view: View) {
val inflater =
getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val rowView: View = inflater.inflate(R.layout.row_add_objective, null)
parentLinearLayout!!.addView(rowView, parentLinearLayout!!.childCount - 1)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> true
// else -> super.onOptionsItemSelected(item)
else -> {return false}
}
}}
row_add_objective.xml
<?xml version="1.0" encoding="utf-8"?>
<layout> <data>
<variable
name="ObjModel"
type="com.example.questeditorblank.ObjModel">
</variable>
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="0dp"
android:paddingBottom="0dp">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<EditText
android:id = "@+id/edit_objective_name"
android:background="@color/light_background"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:layout_weight = "1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="@={ObjModel.obj}"></EditText>
<FrameLayout
android:background="@color/grey"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/spinner_GoalType"
android:layout_width="150dp"
android:layout_height="40dp"></androidx.appcompat.widget.AppCompatSpinner>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/image_remove"
android:layout_width="25dp"
android:layout_height="25dp"
android:src = "@drawable/ic_close"></ImageView>
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/ic_close"
android:onClick="onDelete" />
</FrameLayout>
</LinearLayout>
<EditText
android:id = "@+id/edit_objective_description"
android:background="@color/light_background"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight = "1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text = "@={ObjModel.desc}">
</EditText>
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/edit_objective_description"/>
</LinearLayout>
</layout>
ObjModel.kt
import android.content.Context
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
class ObjModel(context: Context) : BaseObservable() {
var check: Boolean = false
public var goalType: Quest.GoalType = Quest.GoalType.Default
var requiredAmount: Int? = null;
var currentAmount: Int = 0;
@get:Bindable
var desc: String? = null
get() = if (field == null) {
""
} else field
set(desc) {
field = desc
notifyPropertyChanged(BR.desc)
}
@get:Bindable
var obj: String? = "make objective"
get() = if (field == null) {
""
} else field
set(obj) {
field = obj
notifyPropertyChanged(BR.obj)
}
EditTextBindingAdapters.kt
@BindingAdapter("textChangedListener")
fun bindTextWatcher(editText: EditText, textWatcher: TextWatcher) {
editText.addTextChangedWatcher(textWatcher)
}
private fun EditText.addTextChangedWatcher(textWatcher: TextWatcher) {
}
Quest.kt
class Quest(/*val id: Int,
val title: String,
var active: Boolean = true,
val publisher: String = "Kirik",
var author: String = "Kirik",
val featuredImage: String,
val rating: Int = 0,
val sourceUrl: String,
val ingredients: List<Any> = listOf(),
var dateAdded: String,
var dateUpdated: String,
val categories: List<Quest> = TODO()
val allSubCats: Array<List<GoalType>> =
categories.map { it. subCategories }.toTypedArray()
var objectives: MutableList<QuestObjective> = mutableListOf(),*/
): BaseObservable(){
// Given
val id: Int = 0
val title: String = ""
var active: Boolean = true
val publisher: String = "Kirik"
var author: String = "Kirik"
val featuredImage: String? =null
val rating: Int = 0
val sourceUrl: String = ""
val ingredients: List<Any> = listOf()
lateinit var dateAdded: String
lateinit var dateUpdated: String
var objectives: MutableList<QuestObjective> = mutableListOf()
class QuestObjective{
var obj: String= "make objective"
var desc: String? = null
var check: Boolean = false
public var goalType: GoalType = GoalType.Default
var requiredAmount: Int? = null;
var currentAmount: Int = 0;
fun IsReached(): Boolean {
return (currentAmount >= requiredAmount!!)
}
fun ItemCollected() {
if (goalType == GoalType.Gathering){
currentAmount++;
}
}
}
companion object {
}
fun onCreate(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
dateAdded = LocalDateTime.now().toString()
}
}
override fun equals(other: Any?): Boolean {
return super.equals(other)
}
override fun toString(): String {
return super.toString()
}
private fun Quest(): Quest {
active = true
return this
}
fun addObjective( ){
var objective_new = QuestObjective()
objectives.add(objective_new)
print("save or cancel")
}
public enum class GoalType
{
Default,
Kill,
Fetch,
Escort,
Explore,
Do,
Gathering
}
fun saveQuest( ){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
dateUpdated = LocalDateTime.now().toString()
}
print("Saved, jk just printing")
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.Questeditorblank.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.Questeditorblank.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginBottom="16dp"
app:srcCompat="@android:drawable/ic_dialog_email" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="40dp"
android:layout_margin="5dp"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<EditText
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
android:inputType="phone" />
<Spinner
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:entries="@array/types"
android:gravity="right" />
<Button
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:background="@android:drawable/ic_delete"
android:onClick="onDelete" />
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:onClick="onAddField"
android:text="Add Field"
android:textColor="@android:color/background_dark" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
