在Android中使用RecyclerView保存/还原片段状态

时间:2018-12-07 10:06:41

标签: android android-fragments kotlin android-recyclerview

我创建了一个Android应用程序,该应用程序连接到GitHub API,并显示某些用户的存储库列表。列表由recyclerView显示。切换片段时,我试图保存和还原列表。我试图将列表保存到变量并将其添加到recyclerView。但这不起作用。

我的片段:

class MainFragment : Fragment() {

lateinit var recyclerView: RecyclerView
var responseSave:List<GitHubPOJO> = ArrayList()
var posts: MutableList<GitHubPOJO> = ArrayList()
lateinit var btn:Button

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(R.layout.fragment_main, container, false)
    btn = view.findViewById(R.id.button)
    btn.setOnClickListener {
        posts = ArrayList()

        val name:String = view!!.findViewById<EditText>(R.id.editText).text.toString()
        recyclerView = view!!.findViewById(R.id.posts_recycle_view)
        val layoutManager = LinearLayoutManager(this.activity!!)
        recyclerView.layoutManager = layoutManager

        val adapter = PostsAdapter(posts)
        recyclerView.adapter = adapter
        //HIDE KEYBOARD
        val inputMethodManager = this.activity!!.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        if(activity!!.currentFocus !=null) {
            inputMethodManager.hideSoftInputFromWindow(this.activity!!.currentFocus!!.windowToken, 0)
        }
        val service = Retrofit.Builder()
            .baseUrl("https://api.github.com/") // CHANGE API
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(GitHubService::class.java)
        service.retrieveRepositories(name)
            .enqueue(object : Callback<List<GitHubPOJO>> {
                override fun onResponse(call: Call<List<GitHubPOJO>>, response: Response<List<GitHubPOJO>>) {
                    responseSave = response.body()!!
                    posts.addAll(responseSave)
                    response.body()?.forEach { println ("TAG_: $it")}
                    recyclerView.adapter?.notifyDataSetChanged()
                }

                override fun onFailure(call: Call<List<GitHubPOJO>>, t: Throwable) {
                    //Toast.makeText(this@MainFragment, "Error occurred while networking", Toast.LENGTH_SHORT).show()
                }
            })
        recyclerView.addOnItemTouchListener(
            ClickListener(this.activity!!, recyclerView, object : ClickListener.OnItemClickListener {
                override fun onLongItemClick(view: View?, position: Int) {
                }

                override fun onItemClick(view: View, position: Int) {
                    val url = posts!![position].htmlUrl
                    println("URL =  $url")
                    view.findNavController().navigate(MainFragmentDirections.actionMainFragmentToWebFragment(url))


                }
            })
        )
    }
    return view
}

还有我的代码 onResume:

override fun onResume() {
    super.onResume()
    val adapter = PostsAdapter()
    adapter.updateAdapterList(responseSave.toMutableList())
    println("RESUME")
    println(responseSave)
}

当我打印responseSave时,我看到我的列表在那里。但是它没有出现在RecyclerView中。

片段由标准导航库处理。

活动代码:

class MainActivity : AppCompatActivity(){

private lateinit var navController: NavController
private lateinit var mNavView:NavigationView
private lateinit var mDrawerLayout:DrawerLayout



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

    mDrawerLayout = findViewById(R.id.drawer_layout)
    mNavView = findViewById(R.id.nav_view)

    navController = this.findNavController(R.id.myNavHostFragment)
    NavigationUI.setupActionBarWithNavController(this, navController,mDrawerLayout)
    NavigationUI.setupWithNavController(mNavView, navController)
}

override fun onSupportNavigateUp(): Boolean {
    val navController = this.findNavController(R.id.myNavHostFragment)
    return NavigationUI.navigateUp(mDrawerLayout,navController)
}}

我的 RecyclerView适配器代码

class PostsAdapter(private var posts: MutableList<GitHubPOJO>? = ArrayList()) : RecyclerView.Adapter<PostsAdapter.ViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val v = LayoutInflater.from(parent.context).inflate(R.layout.post_item, parent, false)
    return ViewHolder(v)
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val post = posts!![position]
        holder.post.text = post.name
    holder.site.text = post.fullName     // Change what you wanna see
}
fun updateAdapterList(newList: MutableList<GitHubPOJO>) {
    posts!!.clear()
    posts!!.addAll(newList)
    notifyDataSetChanged()
}

override fun getItemCount(): Int {
    return posts?.size ?: 0
}

inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    var post: TextView = itemView.findViewById<View>(R.id.postitem_post) as TextView
    var site: TextView = itemView.findViewById<View>(R.id.postitem_site) as TextView
}}

2 个答案:

答案 0 :(得分:0)

在您的适配器中添加类似方法;

bool onlyLettersAndWhitespace = Regex.IsMatch(input, @"\A[\p{L}\s]+\Z");

然后在您的fun updateAdapterList(newList: MutableList<GitHubPOJO>) { oldList.clear() oldList.addAll(newList) notifyDataSetChanged() } 中调用它并传递更新后的列表

答案 1 :(得分:-1)

问题出在您的onResume方法上。您没有在RecylerView中添加适配器和LayoutManager,因此它无法显示数据。尝试将RecylerView初始化代码从onClickListener移到onResume方法:

 recyclerView = view!!.findViewById(R.id.posts_recycle_view)
 val layoutManager = LinearLayoutManager(this.activity!!)
 recyclerView.layoutManager = layoutManager
 val adapter = PostsAdapter(posts)
 recyclerView.adapter = adapter    

尽管在onCreateView方法中使用此初始化代码会更好,因为这是片段从后堆栈返回到前视图时调用的第一个生命周期方法。