简体   繁体   English

如何使用 api 创建视图模型?

[英]how to create a viewmodel with api?

class MainActivity : AppCompatActivity() {类 MainActivity : AppCompatActivity() {

how to create a viewModel class from the mainActivity class so that the data from the parse doesn't change when the orientation is changed or the data remains intact.如何从 mainActivity 类创建一个 viewModel 类,以便在更改方向或数据保持不变时,来自解析的数据不会改变。 The point is how to do a viewModel with api.how to create a viewmodel with api?重点是如何用api做一个viewModel。如何用api创建一个viewmodel?

private var listData: ArrayList<DataUsers> = ArrayList()
private lateinit var adapter: UsersAdapter

companion object {
    internal val TAG = MainActivity::class.java.simpleName
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val textbar: TextView = findViewById(R.id.toolbar)
    textbar.text = title
    setSupportActionBar(toolbarr)
    adapter = UsersAdapter(listData)

    recyclerViewConfig()
    searchData()
    getDataHome()
}

private fun searchData() {
    user_search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
        override fun onQueryTextSubmit(query: String): Boolean {
            if (query.isEmpty()) {
                return true
            } else {
                listData.clear()
                getDataSearch(query)
            }
            return true
        }

        override fun onQueryTextChange(newText: String): Boolean {
            return false
        }
    })
}

private fun recyclerViewConfig() {
    recycleView.layoutManager = LinearLayoutManager(recycleView.context)
    recycleView.setHasFixedSize(true)
    recycleView.addItemDecoration(
        DividerItemDecoration(
            recycleView.context,
            DividerItemDecoration.VERTICAL
        )
    )
}

private fun getDataHome() {
    progressBar.visibility = View.VISIBLE
    val client = AsyncHttpClient()
    client.addHeader("Authorization", "token -----")
    client.addHeader("User-Agent", "request")
    val url = "https://api.github.com/users"
    client.get(url, object : AsyncHttpResponseHandler() {
        override fun onSuccess(
            statusCode: Int,
            headers: Array<Header>,
            responseBody: ByteArray
        ) {
            progressBar.visibility = View.INVISIBLE
            val result = String(responseBody)
            Log.d(TAG, result)
            try {
                val jsonArray = JSONArray(result)
                for (i in 0 until jsonArray.length()) {
                    val jsonObject = jsonArray.getJSONObject(i)
                    val username: String = jsonObject.getString("login")
                    getDataDetail(username)
                }
            } catch (e: Exception) {
                Toast.makeText(this@MainActivity, e.message, Toast.LENGTH_SHORT)
                    .show()
                e.printStackTrace()
            }
        }

        override fun onFailure(
            statusCode: Int,
            headers: Array<Header>,
            responseBody: ByteArray,
            error: Throwable
        ) {
            progressBar.visibility = View.INVISIBLE
            val errorMessage = when (statusCode) {
                401 -> "$statusCode : Bad Request"
                403 -> "$statusCode : Forbidden"
                404 -> "$statusCode : Not Found"
                else -> "$statusCode : ${error.message + " GIT"}"
            }
            Toast.makeText(this@MainActivity, errorMessage, Toast.LENGTH_LONG)
                .show()
        }
    })
}



private fun getDataDetail(id: String) {
   progressBar.visibility = View.VISIBLE
    val client = AsyncHttpClient()
    client.addHeader("Authorization", "token -------")
    client.addHeader("User-Agent", "request")
    val url = "https://api.github.com/users/$id"
    client.get(url, object : AsyncHttpResponseHandler() {
        override fun onSuccess(
            statusCode: Int,
            headers: Array<Header>,
            responseBody: ByteArray
        ) {
           progressBar.visibility = View.INVISIBLE
            val result = String(responseBody)
            Log.d(TAG, result)
            try {
                val jsonObject = JSONObject(result)
                val username: String? = jsonObject.getString("login").toString()
                val name: String? = jsonObject.getString("name").toString()
                val avatar: String? = jsonObject.getString("avatar_url").toString()
                val company: String? = jsonObject.getString("company").toString()
                val location: String? = jsonObject.getString("location").toString()
                val repository: Int = jsonObject.getInt("public_repos")
                val followers: Int = jsonObject.getInt("followers")
                val following: Int = jsonObject.getInt("following")
                listData.add(
                    DataUsers(
                        username,
                        name,
                        avatar,
                        company,
                        location,
                        repository,
                        followers,
                        following
                    )
                )
                showRecyclerList()
            } catch (e: Exception) {
                Toast.makeText(this@MainActivity, e.message, Toast.LENGTH_SHORT)
                    .show()
                e.printStackTrace()
            }
        }

        override fun onFailure(
            statusCode: Int,
            headers: Array<Header>,
            responseBody: ByteArray,
            error: Throwable
        ) {
           progressBar.visibility = View.INVISIBLE
            val errorMessage = when (statusCode) {
                401 -> "$statusCode : Bad Request"
                403 -> "$statusCode : Forbidden"
                404 -> "$statusCode : Not Found"
                else -> "$statusCode : ${error.message + " DETAIL"}"
            }
            Toast.makeText(this@MainActivity, errorMessage, Toast.LENGTH_LONG)
                .show()
        }
    })
}

private fun getDataSearch(id: String) {
    progressBar.visibility = View.VISIBLE
    val client = AsyncHttpClient()
    client.addHeader("Authorization", "token ---------")
    client.addHeader("User-Agent", "request")
    val url = "https://api.github.com/search/users?q=$id"
    client.get(url, object : AsyncHttpResponseHandler() {
        override fun onSuccess(
            statusCode: Int,
            headers: Array<Header>,
            responseBody: ByteArray
        ) {
            progressBar.visibility = View.INVISIBLE
            val result = String(responseBody)
            Log.d(TAG, result)
            try {
                val jsonArray = JSONObject(result)
                val item = jsonArray.getJSONArray("items")
                for (i in 0 until item.length()) {
                    val jsonObject = item.getJSONObject(i)
                    val username: String = jsonObject.getString("login")
                    getDataDetail(username)
                }
            } catch (e: Exception) {
                Toast.makeText(this@MainActivity, e.message, Toast.LENGTH_SHORT)
                    .show()
                e.printStackTrace()
            }
        }

        override fun onFailure(
            statusCode: Int,
            headers: Array<Header>,
            responseBody: ByteArray,
            error: Throwable
        ) {
           progressBar.visibility = View.INVISIBLE
            val errorMessage = when (statusCode) {
                401 -> "$statusCode : Bad Request"
                403 -> "$statusCode : Forbidden"
                404 -> "$statusCode : Not Found"
                else -> "$statusCode : ${error.message + " GIT"}"
            }
            Toast.makeText(this@MainActivity, errorMessage, Toast.LENGTH_LONG)
                .show()
        }
    })
}

private fun showRecyclerList() {
    recycleView.layoutManager = LinearLayoutManager(this)
    val listDataAdapter =
        UsersAdapter(userFilterList)
    recycleView.adapter = adapter

    listDataAdapter.setOnItemClickCallback(object : UsersAdapter.OnItemClickCallback {
        override fun onItemClicked(dataUsers: DataUsers) {
            showSelectedData(dataUsers)
        }
    })
}

private fun showSelectedData(dataUsers: DataUsers) {
    val dataUser = DataUsers(
        dataUsers.username,
        dataUsers.name,
        dataUsers.avatar,
        dataUsers.company,
        dataUsers.location,
        dataUsers.repository,
        dataUsers.followers,
        dataUsers.following
    )
    val intentDetail = Intent(this@MainActivity, DetailActivity::class.java)
    intentDetail.putExtra(DetailActivity.EXTRA_DATA, dataUser)
    startActivity(intentDetail)
}

} }

class UsersAdapter(private var listData: ArrayList) : RecyclerView.Adapter<UsersAdapter.UserHolder>(), Filterable { class UsersAdapter(private var listData: ArrayList) : RecyclerView.Adapter<UsersAdapter.UserHolder>(), Filterable {

var userFilterList = ArrayList<DataUsers>()
private lateinit var mcontext: Context


init {
    userFilterList = listData
}

inner class UserHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    var imageAvatar: CircleImageView = itemView.avatar
    var name: TextView = itemView.user_name
    var company: TextView = itemView.company
}

private lateinit var onItemClickCallback: OnItemClickCallback

fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallback) {
    this.onItemClickCallback = onItemClickCallback
}

interface OnItemClickCallback {
    fun onItemClicked(dataUsers: DataUsers)
}

override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): UserHolder {
    val view: View = LayoutInflater.from(viewGroup.context)
        .inflate(R.layout.item_row_users, viewGroup, false)
    val sch = UserHolder(view)
    mcontext = viewGroup.context
    return sch
}

override fun getItemCount(): Int {
    return userFilterList.size
}

override fun onBindViewHolder(holder: UserHolder, position: Int) {
    val data = userFilterList[position]
    Glide.with(holder.itemView.context)
        .load(data.avatar)
        .apply(RequestOptions().override(250, 250))
        .into(holder.imageAvatar)
    holder.name.text = data.name
    holder.company.text = data.company
    holder.itemView.setOnClickListener {
        val dataUser = DataUsers(
            data.username,
            data.name,
            data.avatar,
            data.company,
            data.location,
            data.repository,
            data.followers,
            data.following
        )
        val intentDetail = Intent(mcontext, DetailActivity::class.java)
        intentDetail.putExtra(DetailActivity.EXTRA_DATA, dataUser)
        mcontext.startActivity(intentDetail)
    }
}

override fun getFilter(): Filter {
    return object : Filter() {
        override fun performFiltering(constraint: CharSequence): FilterResults {
            val charSearch = constraint.toString()
            userFilterList = if (charSearch.isEmpty()) {
                listData
            } else {
                val resultList = ArrayList<DataUsers>()
                for (row in userFilterList) {
                    if ((row.username.toString().toLowerCase(Locale.ROOT)
                            .contains(charSearch.toLowerCase(Locale.ROOT)))
                    ) {
                        resultList.add(
                            DataUsers(
                                row.username,
                                row.name,
                                row.avatar,
                                row.company,
                                row.location,
                                row.repository,
                                row.followers,
                                row.following
                            )
                        )
                    }
                }
                resultList
            }
            val filterResults = FilterResults()
            filterResults.values = userFilterList
            return filterResults
        }

        @Suppress("UNCHECKED_CAST")
        override fun publishResults(constraint: CharSequence, results: FilterResults) {
            userFilterList = results.values as ArrayList<DataUsers>
            notifyDataSetChanged()
        }
    }
}

Thanks to the usage of LiveData and Kotlin Coroutines we can avoid callbacks and have a really simple way to present our data to our views.多亏了LiveDataKotlin 协程的使用,我们可以避免回调,并有一种非常简单的方式将我们的数据呈现给我们的视图。

You should use the Jetpack recommended architecture of MVVM with Repository as DataSource.您应该使用 Jetpack 推荐的 MVVM 架构,将 Repository 作为数据源。 The flow of Project will be:项目流程如下:

You will have your json response via Retrofit in Repository as LiveData.您将通过Retrofit中的Retrofit作为 LiveData 获得 json 响应。 From repository it will be recieved by ViewModel as LiveData and View will always be observing the Live Data and will update UI accordingly.从存储库中,它会被 ViewModel 作为 LiveData 接收,View 将始终观察实时数据并相应地更新 UI。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何修复“无法创建 ViewModel 类的实例”? - How to fix 'Cannot create an instance of ViewModel class'? 如何为大量片段创建视图模型实例? - How to create viewmodel instance for a lot of fragments? 如何在不使用 kotlin ktx 的情况下创建视图模型? - How to create a viewmodel without using kotlin ktx? 如何从Activity中的API调用的ViewModel中获取错误? - How do i get error from ViewModel on API Call in Activity? 如何将多个 API 方法的参数传递给 ViewModel - How to pass parameters of more than one API Methods to ViewModel 如何使用 ViewModel 和 LiveData 进行改造 API 调用 - How to make retrofit API call using ViewModel and LiveData 如何使用来自 init{} 的 API 调用测试 ViewModel + Flow - How to test ViewModel + Flow with API call from init{} 如何使用 viewmodel + livedata 进行单元测试改造 api 调用? - How to do unit testing retrofit api calls with viewmodel + livedata? 如何在使用viewmodel时将动态参数传递给android中的api - How to pass dynamic parameters to rest api in android when using viewmodel 如何使用 SavedStateHandle 作为参数正确创建应用程序 ViewModel - How to correctly create a app wise ViewModel with SavedStateHandle as parameter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM