How to databind to onTextChanged for an EditText on Android?

后端 未结 9 1144
悲哀的现实
悲哀的现实 2020-11-30 01:41

In Yigit Boyar and George Mount\'s talk on Android Databinding they illustrate how easy it is to bind to TextWatcher\'s onTextChanged (at 13:41). O

相关标签:
9条回答
  • 2020-11-30 02:20

    I got it working like this:

    Fragment:

        class DiAtomicMoleculesFragment : Fragment() {
            private lateinit var binding: FragmentDiatomicMoleculesBinding
    
            override fun onCreateView(
                inflater: LayoutInflater,
                container: ViewGroup?,
                savedInstanceState: Bundle?
            ): View? {
                binding = FragmentDiatomicMoleculesBinding.inflate(layoutInflater, container, false)
                return binding.root
            }
    
            override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
                super.onViewCreated(view, savedInstanceState)
                val recyclerAdapter = DiAtomicMoleculesAdapter(onClickListener)
    
                binding.diRecyclerView.apply {
                    setHasFixedSize(true)
                    layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
                    adapter = recyclerAdapter
                }
    
                val viewModel = ViewModelProvider(this).get(DiAtomicMoleculesViewModel::class.java)
                viewModel.getDiAtomicMolecules().observe(viewLifecycleOwner, Observer { items ->
                    recyclerAdapter.setData(items)
                })
    
                viewModel.getDiAtomicMoleculesByName().observe(viewLifecycleOwner, Observer { items ->
                    recyclerAdapter.setData(items)
                })
    
                //this is important
                binding.viewModel = viewModel
            }
        }
    

    layout.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <data>
            <variable
                name="viewModel"
                type="com.mychemistry.viewmodel.DiAtomicMoleculesViewModel" />
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white">
    
            <androidx.appcompat.widget.AppCompatEditText
                android:id="@+id/di_search_box"
                android:layout_width="0dp"
                android:layout_height="50dp"
                android:gravity="center_vertical"
                android:hint="@string/search"
                android:paddingStart="10dp"
                android:paddingEnd="5dp"
                android:singleLine="true"
                android:textColor="@android:color/black"
                android:textColorHint="@android:color/darker_gray"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                android:onTextChanged="@{(text, start, before, count) -> viewModel.onTextChange(text)}"/>
    
    <!--     or this ->      android:afterTextChanged="@{(e) -> viewModel.onTextChange(e)}"/>-->
    
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/di_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@id/di_search_box" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    </layout>
    

    ViewModel:

    class DiAtomicMoleculesViewModel : ViewModel() {
        private val allLiveData = AppDatabase.getInstance().getDiAtomicMoleculeDao().getAll()
        private val filterLiveData = MutableLiveData<String>()
        private val searchByLiveData = Transformations.switchMap(filterLiveData, ::filter)
    
        fun getDiAtomicMolecules(): LiveData<List<DiAtomicMolecule>> {
            return allLiveData
        }
    
        private fun filter(text: String): LiveData<List<DiAtomicMolecule>> {
            return AppDatabase.getInstance().getDiAtomicMoleculeDao().find(text)
        }
    
        fun getDiAtomicMoleculesByName(): LiveData<List<DiAtomicMolecule>> {
            return searchByLiveData
        }
    
        fun onTextChange(e: Editable?) {
            filterLiveData.value = e?.toString()
        }
    
        fun onTextChange(text: CharSequence?) {
            filterLiveData.value = text?.toString()
        }
    }
    
    0 讨论(0)
  • 2020-11-30 02:25

    Im using this method to handle on text change listener in android databinding.1st in your ViewModel class create LiveData variable, And also create getText method which returns LiveData object.

    • public MutableLiveData<String> verifyCodes = new MutableLiveData<>();
    • public LiveData<String> getCodes(){ return verifyCodes; }

    Then in your xml files editText field set attribute on text bind with above liveData field

    • <EditText android:id="@+id/et_verification1st" android:layout_width="match_parent" android:layout_height="match_parent" android:text="@={viewModel.verifyCodes}"/>

    In databinding you already know how to create variable of viewModel class inside data tag i beleive.As example

    • <data> <variable name="viewModel" type="viewModel.VerifyUserActivityViewModel" /> </data>

    Ok now your activity you have to observe liveData object we created inside viewModel class

    • mViewModel.getCodes().observe(this,new Observer< String>(){ @Override public void onChange(String strings){ log.d("OnChange",strings); }});

    You can perform any logic when text changing inside onChange method

    0 讨论(0)
  • 2020-11-30 02:26

    If you just need text parameter after text has changed, you could use android:afterTextChanged binding adapter. for example:

    android:afterTextChanged="@{(text) -> viewModel.onTextChange(text)}"
    

    Then in your ViewModel just implement like this:

    fun onTextChange(editable: Editable?) {
        Log.d("TAG","New text: ${editable.toString()}")
    }
    

    Furthermore, there is android:beforeTextChanged which used to know old text before text change event, usage is same as android:afterTextChanged.

    0 讨论(0)
提交回复
热议问题