Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从Kotlin中的ViewModel填充UI_Android_User Interface_Kotlin_Mvvm_Android Viewmodel - Fatal编程技术网

Android 从Kotlin中的ViewModel填充UI

Android 从Kotlin中的ViewModel填充UI,android,user-interface,kotlin,mvvm,android-viewmodel,Android,User Interface,Kotlin,Mvvm,Android Viewmodel,这是我第一次使用Android架构。我已经决定使用MVVM结构,但我一直不知道如何使用从数据库中提取的数据设置XML中的文本视图 通过查看日志,我发现对我的数据库(Firestore)的函数调用确实检索到了正确的数据文档。我是从Activity、ViewModel还是片段中设置UI元素?(请注意,我使用的是导航栏和控制器) 请协助我,我的代码如下: 我的单一活动: class HomeActivity : AppCompatActivity() { // Create the thre

这是我第一次使用Android架构。我已经决定使用MVVM结构,但我一直不知道如何使用从数据库中提取的数据设置XML中的文本视图

通过查看日志,我发现对我的数据库(Firestore)的函数调用确实检索到了正确的数据文档。我是从Activity、ViewModel还是片段中设置UI元素?(请注意,我使用的是导航栏和控制器)

请协助我,我的代码如下:

我的单一活动:

class HomeActivity : AppCompatActivity() {

    // Create the three objects for the fragments
    lateinit var homeFragment: HomeFragment
    lateinit var visitsFragment: VisitsFragment
    lateinit var profileFragment: ProfileFragment

    // ViewModels
    lateinit var customerViewModel: CustomerViewModel



    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home)

        // Initialize the bottom nav bar and navigation controller and then merge them
        val bottomNavigationView = findViewById<BottomNavigationView>(R.id.btm_nav)
        val navigationController = findNavController(R.id.fragmentHost)
        bottomNavigationView.setupWithNavController(navigationController)
        // Create app bar config object so that you can rename the bar ontop with the tab name
        val appBarConfiguration = AppBarConfiguration(setOf(R.id.homeFragment,R.id.visitsFragment,R.id.profileFragment))
        setupActionBarWithNavController(navigationController,appBarConfiguration)

        // View Model
        customerViewModel = ViewModelProvider(this).get(CustomerViewModel::class.java)
        customerViewModel.retrieveCustomer().observe(this, Observer { it })
    }


    // This function creates the menu object by inflating it with the resource we gave it (menu resource).
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_main,menu);
        return true
    }
    // This function checks which menu item was selected and performs the task associated with the item selected.
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        val id = item.itemId;

        // If Log Out menu item was selected
        if (id == R.id.menuLogOut){
            // Sign the user out
            FirebaseAuth.getInstance().signOut()
            // Finish this activity
            finish()
            // Start the initial activity
            val intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
            // Display the message to the user
            Toast.makeText(this, "Successfully Signed Out", Toast.LENGTH_SHORT).show()
            return true
        }

        return super.onOptionsItemSelected(item)
    }
}
我的XML文件(配置文件\u片段):

最后,我要填充的视图

一旦导航到ProfileFragment,您需要将所有逻辑移到ProfileFragment,此时将设置ProfileFragment数据。 例如:

轮廓片段

class ProfileFragment : Fragment() {

private val customerViewModel: CustomerViewModel by viewModels()

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    val view = inflater.inflate(R.layout.fragment_profile, container, false)
    val name = view.findViewById<TextView>(R.id.name)
    val surname = view.findViewById<TextView>(R.id.surname)
    val email = view.findViewById<TextView>(R.id.email)
    val contact = view.findViewById<TextView>(R.id.contact)

    //calling initially here
    customerViewModel.retrieveCustomer()
    customerViewModel.liveData.observe(viewLifecycleOwner, Observer {
        //customer index at 0
        val customer = it[0]
        name.text = customer.name
        surname.text = customer.surname
        email.text = customer.email
        contact.text = customer.contactNo
    })

    return view
}
class-ProfileFragment:Fragment(){
private val customerViewModel:customerViewModel by viewModels()
覆盖创建视图(
充气器:布局充气器,容器:视图组?,
savedInstanceState:捆绑?
):查看{
//为该碎片膨胀布局
val视图=充气机。充气(R.layout.fragment_外形,容器,假)
val name=view.findViewById(R.id.name)
val姓氏=view.findViewById(R.id.姓氏)
val email=view.findviewbyd(R.id.email)
val contact=view.findviewbyd(R.id.contact)
//最初在这里打电话
CustomerServiceModel.retrieveCustomer()
customerViewModel.liveData.observe(viewLifecycleOwner,Observer{
//客户指数为0
val customer=it[0]
name.text=customer.name
姓氏.text=客户.姓氏
email.text=customer.email
contact.text=customer.contactNo
})
返回视图
}
CustomerViewModel.kt

class CustomerViewModel(application: Application) : AndroidViewModel(application) {
var liveData = MutableLiveData<List<Customer>>()

fun retrieveCustomer(){
    //Your logic to get data from Firebase or any remote or db
    val listOfCustomer = mutableListOf<Customer>()
    val customer = Customer("name", "surname","email", "contqct")
    listOfCustomer.add(customer)
    liveData.postValue(listOfCustomer)
}
类CustomerViewModel(应用程序:应用程序):AndroidViewModel(应用程序){
var liveData=MutableLiveData()
乐趣检索客户(){
//从Firebase或任何远程数据库或数据库获取数据的逻辑
val listOfCustomer=mutableListOf()
val customer=客户(“姓名”、“姓氏”、“电子邮件”、“contqct”)
客户列表。添加(客户)
liveData.postValue(客户列表)
}
}

fragment_profile.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:id="@+id/name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Name"
    android:padding="8dp"
    android:textSize="24dp"
    />
<TextView
    android:id="@+id/surname"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Surname"
    android:padding="8dp"
    android:textSize="24dp"
    />
<TextView
    android:id="@+id/email"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Name"
    android:padding="8dp"
    android:textSize="24dp"
    />
<TextView
    android:id="@+id/contact"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Name"
    android:padding="8dp"
    android:textSize="24dp"
    />
</LinearLayout>


您可以共享配置文件片段代码吗?实际上,您需要在那里编写所有代码,因为数据与配置文件视图模型相关。配置文件片段代码为空。我还没有在那里做任何事情,因为我不确定在何处设置数据。您能给我一个示例,说明如何在片段中设置它吗需要更好地理解这个问题。从哪个布局和片段,上面的屏幕短片是从名为profile_fragment的片段显示出来的。我现在在上面的问题中添加了它。非常感谢!我花了几个小时在youtube上试着学习这个,但我没有找到任何关于这个的材料,即使是这么简单的显示。我很感激!一个洛杉矶人首先,当数据加载时,我想添加一个微调器或进度条,使其看起来更平滑。我应该在哪里添加这个?
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup


// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [ProfileFragment.newInstance] factory method to
 * create an instance of this fragment.
 */
class ProfileFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_profile, container, false)
    }

    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment ProfileFragment.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            ProfileFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}
class ProfileFragment : Fragment() {

private val customerViewModel: CustomerViewModel by viewModels()

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    val view = inflater.inflate(R.layout.fragment_profile, container, false)
    val name = view.findViewById<TextView>(R.id.name)
    val surname = view.findViewById<TextView>(R.id.surname)
    val email = view.findViewById<TextView>(R.id.email)
    val contact = view.findViewById<TextView>(R.id.contact)

    //calling initially here
    customerViewModel.retrieveCustomer()
    customerViewModel.liveData.observe(viewLifecycleOwner, Observer {
        //customer index at 0
        val customer = it[0]
        name.text = customer.name
        surname.text = customer.surname
        email.text = customer.email
        contact.text = customer.contactNo
    })

    return view
}
class CustomerViewModel(application: Application) : AndroidViewModel(application) {
var liveData = MutableLiveData<List<Customer>>()

fun retrieveCustomer(){
    //Your logic to get data from Firebase or any remote or db
    val listOfCustomer = mutableListOf<Customer>()
    val customer = Customer("name", "surname","email", "contqct")
    listOfCustomer.add(customer)
    liveData.postValue(listOfCustomer)
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:id="@+id/name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Name"
    android:padding="8dp"
    android:textSize="24dp"
    />
<TextView
    android:id="@+id/surname"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Surname"
    android:padding="8dp"
    android:textSize="24dp"
    />
<TextView
    android:id="@+id/email"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Name"
    android:padding="8dp"
    android:textSize="24dp"
    />
<TextView
    android:id="@+id/contact"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Name"
    android:padding="8dp"
    android:textSize="24dp"
    />
</LinearLayout>