Java 如何在片段中只调用函数一次android kotlin
当我的应用程序启动时,我调用一个使用翻新/gson的函数,并调用一个restapi,然后从那里将数据发送到适配器并放置在回收器视图中。我遇到的问题是,当我导航到另一个片段并再次返回时,会再次调用该函数,但旧数据仍保留在recycler视图中,这导致在我只希望它调用一次或在recycler视图中至少只有一组数据时,相同数据的多个副本位于recycler视图中 我尝试了从活动而不是片段调用函数,将函数放入onCreate方法和数学if-else表达式中,但都没有产生预期的效果 我的代码:Java 如何在片段中只调用函数一次android kotlin,java,android,kotlin,android-recyclerview,retrofit,Java,Android,Kotlin,Android Recyclerview,Retrofit,当我的应用程序启动时,我调用一个使用翻新/gson的函数,并调用一个restapi,然后从那里将数据发送到适配器并放置在回收器视图中。我遇到的问题是,当我导航到另一个片段并再次返回时,会再次调用该函数,但旧数据仍保留在recycler视图中,这导致在我只希望它调用一次或在recycler视图中至少只有一组数据时,相同数据的多个副本位于recycler视图中 我尝试了从活动而不是片段调用函数,将函数放入onCreate方法和数学if-else表达式中,但都没有产生预期的效果 我的代码: MainF
MainFragment.kt
class MainFragment : Fragment() {
private var text1list = mutableListOf<String>()
private var text2list = mutableListOf<String>()
private var text3list = mutableListOf<String>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_main, container, false)
view.see_codes.setOnClickListener {
findNavController().navigate(R.id.action_mainFragment_to_listFragment2)
}
TestGet()
return view
}
val BASE_URL = "https://run.mocky.io/v3/"
private fun TestGet() {
val api = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(SimpleApi::class.java)
GlobalScope.launch(Dispatchers.IO) {
val response = api.phonehome()
try {
for (Mlist in response.Mlist){
Log.d("MainActivity", "Result + $Mlist")
addToList(Mlist.text1, Mlist.text2, Mlist.text3)
}
withContext(Dispatchers.Main){
setUpRecyclerView()
}
}catch (e: Exception){
println("you messed up the connection some how")
}
}
}
private fun setUpRecyclerView() {
main_recyclerview.layoutManager = LinearLayoutManager(this.context)
main_recyclerview.adapter = MainAdapter(text1list,text2list,text3list)
}
private fun addToList(text1: String, text2: String, text3: String){
text1list.add(text1)
text2list.add(text2)
text3list.add(text3)
}
}
MainFragment.kt
类MainFragment:Fragment(){
private var text1list=mutableListOf()
private var text2list=mutableListOf()
私有变量text3list=mutableListOf()
覆盖创建视图(
充气器:布局充气器,容器:视图组?,
savedInstanceState:捆绑?
):查看{
val视图=充气机。充气(R.layout.fragment_main,容器,错误)
view.see_codes.setOnClickListener{
findNavController().导航(R.id.action\u main fragment\u到\u listFragment2)
}
TestGet()
返回视图
}
val BASE_URL=”https://run.mocky.io/v3/"
私人娱乐测试获取(){
val api=reformation.Builder()
.baseUrl(基本URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(SimpleApi::class.java)
GlobalScope.launch(Dispatchers.IO){
val response=api.phonehome()
试一试{
for(响应中的Mlist.Mlist){
Log.d(“主活动”,“结果+$Mlist”)
addToList(Mlist.text1、Mlist.text2、Mlist.text3)
}
withContext(Dispatchers.Main){
setUpRecyclerView()
}
}捕获(e:例外){
println(“你怎么搞砸了连接”)
}
}
}
私人娱乐设置回收视图(){
main\u recyclerview.layoutManager=LinearLayoutManager(this.context)
main_recyclerview.adapter=main适配器(text1列表、text2列表、text3列表)
}
私人娱乐添加列表(text1:String,text2:String,text3:String){
text1list.add(text1)
text2list.add(text2)
text3list.add(text3)
}
}
我的适配器
MainAdapter.kt
class MainAdapter(
private var text1: List<String>, private var text2: List<String>, private var text3: List<String>) : RecyclerView.Adapter<MainAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var itemtext1 : TextView = itemView.findViewById(R.id.note_text_view_1)
var itemtext2 : TextView = itemView.findViewById(R.id.note_text_view_2)
var itmetext3 : TextView = itemView.findViewById(R.id.note_text_View_3)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.carditem,parent,false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return text1.size
}
override fun onBindViewHolder(holder: MainAdapter.ViewHolder, position: Int) {
holder.itemtext1.text = text1[position]
holder.itemtext2.text = text2[position]
holder.itmetext3.text = text3[position]
}
}
maintadapter.kt
类主适配器(
private-var text1:List,private-var text2:List,private-var text3:List):RecyclerView.Adapter(){
内部类ViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){
var itemtext1:TextView=itemView.findViewById(R.id.note\u text\u view\u 1)
var itemtext2:TextView=itemView.findViewById(R.id.note\u text\u view\u 2)
var itmetext3:TextView=itemView.findViewById(R.id.note\u text\u View\u 3)
}
重写CreateViewHolder(父级:ViewGroup,viewType:Int):MainAdapter.ViewHolder{
val v=LayoutFlater.from(parent.context)。充气(R.layout.carditem,parent,false)
返回视窗支架(v)
}
重写getItemCount():Int{
返回text1.size
}
覆盖BindViewHolder(支架:MainAdapter.ViewHolder,位置:Int){
holder.itemtext1.text=text1[位置]
holder.itemtext2.text=text2[位置]
holder.itmetext3.text=text3[位置]
}
}
感谢您抽出时间。您可以检查并查看RecyclerView.adapter是否为空。并据此采取行动 如果它不是
null
,则表示您已经查询并设置了适配器
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_main, container, false)
view.see_codes.setOnClickListener {
findNavController().navigate(R.id.action_mainFragment_to_listFragment2)
}
if (view.main_recyclerview.adapter == null) {
TestGet()
}
return view
}
如果问题只是RecyclerView中的重复数据,则可以在setUpRecyclerView()
函数中检查适配器是否为空
private fun setUpRecyclerView() {
if (main_recyclerview.adapter == null) {
main_recyclerview.layoutManager = LinearLayoutManager(this.context)
main_recyclerview.adapter = MainAdapter(text1list,text2list,text3list)
}
}
编辑:
作为最后手段,您可以创建一个名为扩展名
的单独kotlin文件或其他文件,其中包含一个对象,如下所示:
object Settings{
var recViewAlreadyUpdated : Boolean = false
}
此变量是在应用程序运行时创建的,只要应用程序存在,您就可以使用此标志将数据加载到您的RecyclerView中,如下所示:
if (!Settings.recViewAlreadyUpdated) {
TestGet()
Settings.recViewAlreadyUpdated = true
}
我认为正确的方法是只创建
RecyclerView
,它是Adapter
一次。然后你更新adapater存储的数据并调用notifyDataChanged()
我相信我已经找到了我的应用程序的问题所在,但首先要感谢Mehran B,是他为这个解决方案奠定了基础
问题在于代码顶部的变量的可变列表。他们保留了上一次函数调用的数据,只是添加到其中。因此,首先我试图通过清除所有可变列表中的数据来解决这个问题。嗯,我不知道该怎么做,但如果有人知道怎么做,请发表评论
所以我最终做的是
if (!Settings.recViewAlreadyUpdated) {
TestGet()
Settings.recViewAlreadyUpdated = true
}else{
text1list = mutableListOf()
text2list = mutableListOf()
text3list = mutableListOf()
TestGet()
}
我所做的是重写或创建一个新的mutableListOf
(我不确定是哪个),如果这个函数以前没有使用过的话。再次感谢Mehran B虽然这里的概念似乎是正确的,但很难从OP的代码中判断这个解决方案是否有效。问题不包括如何声明或初始化main\u recyclerview
,因此我们不知道它是否会为null。我们可能需要更深一层,检查回收器视图是否有适配器。对不起,我的错。编辑了答案。您需要从正在加载片段的视图中获取recView引用。立即尝试抱歉,mehran,但是代码不起作用,它会使应用程序崩溃。它说:java.lang.NullPointerException:com.notifiyr.fragments.main.MainFragment.onCreateView(main