6

Muszę odświeżyć widok listy nowymi danymi. Poniższy kod służy do uzyskiwania danych w OnCreateView, który jest w FragmentActivity po raz pierwszy.Android: nie można odświeżyć widoku listy przy użyciu CustomAdaptera

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, 
          savedInstanceState: Bundle?): View? { 
     val url = "something" 

     val request_queue = Volley.newRequestQueue(this.context) 
     val stringRequest = StringRequest(Request.Method.GET, url, 
       Response.Listener<String> { response -> 
        val pending_job = Gson().fromJson<ArrayList<HashMap<String, String>>>(
          response.toString(), 
          object : TypeToken<ArrayList<HashMap<String, String>>>() {}.type 
        ) 
        [email protected](rootView, R.id.pending_job_list, pending_job) 

        pending_job_list_layout.setOnRefreshListener(this) 

        request_queue.stop() 
       }, Response.ErrorListener { error -> 
      if (error.networkResponse != null) { 
       Toast.makeText(this.context, error.networkResponse.statusCode.toString(), Toast.LENGTH_SHORT).show() 
      } 
      request_queue.stop() 
     }) 
     request_queue.add(stringRequest) 
} 

showList jest funkcja ustawić CustomAdapter, który jest

fun showList(rootView: View, tab_id: Int, job_list: ArrayList<HashMap<String, String>>) { 

    // custom display ListView 
    val adapter: CustomAdapter = CustomAdapter(
      this.context, 
      job_list 
    ) 

    this_adapter = adapter 

    val listView = rootView.findViewById(tab_id) as ListView 
    listView.adapter = adapter 
} 

, a to CustomAdapter klasy

class CustomAdapter(internal var mContext: Context, 
       internal var job_list: ArrayList<HashMap<String, String>> 
       ) : BaseAdapter() { 

override fun getCount(): Int { 
    return job_list.size 
} 

override fun getItem(position: Int): Any? { 
    return null 
} 

override fun getItemId(position: Int): Long { 
    return 0 
} 

override fun getView(position: Int, view: View?, parent: ViewGroup): View { 
    val mInflater = mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 

    val item_view = mInflater.inflate(R.layout.activity_job_item, parent, false) 

    val job_name: MutableList<String> = arrayListOf() 
    job_list.mapTo(job_name) { it["BaseSiteName"] as String } 
    val nameView: TextView = item_view.findViewById(R.id.name) as TextView 
    nameView.text = job_name[position] 

    val job_date: MutableList<String> = arrayListOf() 
    job_list.mapTo(job_date) { it["PlanDt"] as String} 
    val dateView: TextView = item_view.findViewById(R.id.date) as TextView 
    dateView.text = job_date[position] 

    item_view.setOnClickListener{ 
     val intent: Intent = Intent(mContext, JobDetailActivity::class.java) 
     intent.putExtra("job", job_list[position]) 
     mContext.startActivity(intent) 
    } 

    return item_view 
} 

}

Jednakże chcę zrobić listę odświeżający. Napisałem poniższy kod, aby odświeżyć listę.

override fun onRefresh() { 
    Toast.makeText(this.context, "Refresh", Toast.LENGTH_SHORT).show() 
    val rootView = this_inflater!!.inflate(R.layout.fragment_pending_job, this_container, false) 

    val url = "something" 

    val request_queue = Volley.newRequestQueue(this.context) 
    val stringRequest = StringRequest(Request.Method.GET, url, 
      Response.Listener<String> { response -> 
       val pending_job = Gson().fromJson<ArrayList<HashMap<String, String>>>(
         response.toString(), 
         object : TypeToken<ArrayList<HashMap<String, String>>>() {}.type 
       ) 

       val adapter: CustomAdapter = CustomAdapter(
         this.context, 
         pending_job 
       ) 

       val listView = rootView.findViewById(R.id.pending_job_list) as ListView 
       listView.adapter = adapter 

       pending_job_list_layout.isRefreshing = false 

       pending_job_list_layout.setOnRefreshListener(this) 

       request_queue.stop() 
      }, Response.ErrorListener { error -> 
     if (error.networkResponse != null) { 
      Toast.makeText(this.context, error.networkResponse.statusCode.toString(), Toast.LENGTH_SHORT).show() 
     } 
     request_queue.stop() 
    }) 
    request_queue.add(stringRequest) 
} 

To tylko tworzy instancję CustomAdapter ponownie i przenosi ją ponownie do listy.

Po odświeżeniu nic na liście nie jest zmieniane.

+0

dlaczego nadmuchujesz swój widok fragmentu podczas odświeżania? powinieneś nadmuchać go na części 'onCreateView()'. Być może wziąłeś odwołanie listView do twojego Response.Listener z niewłaściwego katalogu głównego (tj. Ten, który został niedawno zawyżony) i dlatego aktualizacja nie jest wyświetlana. (Twój ekran używa starego rootView i nic na to nie zrobiłeś). –

+1

To jest zła implementacja, dlaczego nie tworzysz tablicy ArrayList z danymi publicznymi i ustawiasz ją ponownie? Mam na myśli tak: adapter.job_list = pending_job, a następnie wywołanie notifyDataSetChanged()? – mayosk

+0

Właśnie dodaje 'adapter.job_list' w' onRefresh', a następnie wywołaj 'adapter.notifyDataSetChanged()', więc działa! Dziękuję wszystkim za pomoc. – gameraroma

Odpowiedz

0

zdefiniować metodę UpdateData w klasie CustomAdapter który otrzyma nowe dane i zastępuje stare dane

fun UpdateData(new_job_list: ArrayList<HashMap<String, String>>){ 
     job_list.clear() 
     job_list.addAll(new_job_list) 
     notifyDataSetChanged() 
    } 

Teraz, gdy pojawi się nowe dane z volly, zamiast ponownie ustawienie adaptera dla ListView wystarczy użyć

adapter.UpdateData(pending_job) 
0

1.Way: Można dokonać tła słuchacza Asynctask Ty możesz słuchać swojego serwera w danych pętla continuous.When zmienionych niż można odświeżyć listview .W ten sposób jest łatwe, ale nie jest dobre dla wydajności.

2.Way: Możesz użyć bazy danych firebase. Ponieważ działa ona w czasie rzeczywistym.

3.Way: Jeśli nie chcesz zmienić swoją database.You mogą korzystać Google Cloud Messaging .you musi wdrożyć ten, dane application.When zarówno serwer i zmienił na serwerze słuchać i wysłać wiadomość z chmurą wiadomości do aplikacji dla Androida . Odśwież automatycznie list view.