Reputation: 1180
l have created a list view and the code working fine . also created a search box . I want to implement search functionality on the basis of particular fields of the list. l used list adapter in Separated class is not in main activity class . l want use search bar filter in class list adapter .
main activity class
package com.iraqairoirt.iraqairports
import android.app.AlertDialog
import android.os.AsyncTask
import android.support.design.widget.TabLayout
import android.support.v7.app.AppCompatActivity
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_arrivel.*
import kotlinx.android.synthetic.main.fragment_dep.*
import org.json.JSONArray
import org.json.JSONObject
import java.net.HttpURLConnection
import java.net.URL
import android.widget.TextView
import com.iraqairoirt.iraqairports.flightsDep.ListAdapteDep
import com.iraqairoirt.iraqairports.flightsArr.ListAdapteArr
class MainActivity : AppCompatActivity() {
private var mSectionsPagerAdapter: SectionsPagerAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val url = "xxxxxxxxxxxxxxxxxxxxxxx"
Arr().execute(url)
Dep().execute(url)
setSupportActionBar(toolbar)
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager)
// Set up the ViewPager with the sections adapter.
container.adapter = mSectionsPagerAdapter
container.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs))
tabs.addOnTabSelectedListener(TabLayout.ViewPagerOnTabSelectedListener(container))
}
// full class for json api
inner class Arr : AsyncTask<String, String, String>(){
val progressDialog = AlertDialog.Builder(this@MainActivity)
val dialogView = layoutInflater.inflate(R.layout.progress_dialog,null)
val message = dialogView.findViewById<TextView>(R.id.message_id)
val dialog = progressDialog.create()
override fun onPreExecute() {
super.onPreExecute()
dialog.setMessage("loading")
dialog.setCancelable(false)
dialog.show()
}
// for build connection
override fun doInBackground(vararg url: String?): String{
var text : String
val connection = URL(url[0]).openConnection() as HttpURLConnection
try {
connection.connect()
text = connection.inputStream.use { it.reader().use{reader -> reader.readText()} }
} finally{
connection.disconnect()
}
return text
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson(result)
dialog.dismiss();
}
override fun onProgressUpdate(vararg text: String?) {
}
private fun handleJson (jsonString: String?){
val schedule = pluginData.getJSONObject("schedule")
val arrivals = schedule.getJSONObject("arrivals")
// val data = arrivals.getJSONObject("data")
val jsonArray = JSONArray(arrivals.get("data").toString())
val list = ArrayList<FlightShdu>()
var x = 0
while (x < jsonArray.length()){
val jsonObject = jsonArray.getJSONObject(x)
list.add(FlightShdu(
jsonObject.getJSONObject("flight").getJSONObject("identification").getJSONObject("number").getString("default"),
jsonObject.getJSONObject("flight").getJSONObject("airline").getString("short"),
jsonObject.getJSONObject("flight").getJSONObject("status").getJSONObject("generic").getJSONObject("status").getString("text"),
jsonObject.getJSONObject("flight").getJSONObject("airline").getJSONObject("code").getString("icao"),
jsonObject.getJSONObject("flight").getJSONObject("time").getJSONObject("scheduled").getString("arrival"),
jsonObject.getJSONObject("flight").getJSONObject("airport").getJSONObject("origin").getJSONObject("code").getString("iata"),
jsonObject.getJSONObject("flight").getJSONObject("aircraft").getJSONObject("model").getString("text"),
// for more information
jsonObject.getJSONObject("flight").getJSONObject("time").getJSONObject("real").getString("departure"),
jsonObject.getJSONObject("flight").getJSONObject("time").getJSONObject("estimated").getString("arrival"),
// jsonObject.getJSONObject("flight").getJSONObject("time").getJSONObject("estimated").getString("arrival"),
jsonObject.getJSONObject("flight").getJSONObject("aircraft").getString("registration"),
jsonObject.getJSONObject("flight").getJSONObject("status").getJSONObject("generic").getJSONObject("status").getString("diverted"),
arrivals.getString("timestamp"),
jsonObject.getJSONObject("flight").getJSONObject("status").getString("icon")
))
x++
}
list.forEach(::println)
val adapter = ListAdapteArr(this@MainActivity, list)
flight_arrivel_list.adapter = adapter
}
}
/**
* A [FragmentPagerAdapter] that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
inner class SectionsPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment? {
return when (position) {
0 -> {
fragment_Arr()
}
1 ->{
fragment_Dep()
}
2->{
fragment_Weather()
}
else-> {
return null
}
}
}
override fun getCount(): Int {
// Show 3 total pages.
return 2
}
}
}
List Adapter
class ListAdapteArr (val context: MainActivity, val list: ArrayList<FlightShdu>): BaseAdapter() {
@SuppressLint("ViewHolder", "NewApi")
override fun getView(p0: Int, convertView: View?, parent: ViewGroup?): View {
val view : View = LayoutInflater.from(context).inflate(R.layout.arr_list,parent,false)
val searchBar = view.findViewById(R.id.searchFlightId) as MaterialSearchBar
Airport.text= list.Airport
return view
}
override fun getItem(p0: Int): Any {
return list [p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getCount(): Int {
return list.size
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/flight_arrivel_list"
style="@style/Widget.AppCompat.ListView"
android:paddingStart="10sp"
android:paddingEnd="10sp"
android:paddingTop="0dp" android:layout_alignParentStart="true" android:layout_alignParentTop="true"
android:layout_marginTop="58dp" android:layout_marginStart="0dp"/>
<com.mancj.materialsearchbar.MaterialSearchBar
style="@style/MaterialSearchBarLight"
app:mt_speechMode="true"
app:mt_hint="Custom hint"
app:mt_maxSuggestionsCount="10"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/searchBar" />
</RelativeLayout>
l added search bar filter to search on any item inside listview but the there still not funcation to do this
Upvotes: 0
Views: 3228
Reputation: 385
In your activity perform your search on your list and reassign the value(keep a val baseList
and var filteredList
so you can default back to the original if need be. First of all we want to move the nested adapter to the top of the activity so we can access it after its instantiated. We also want to use two lists for this so aff the baseList
and filteredList
as i have below the private lateinit var adapter: ListAdapteArr? = null
at the top of the activity.
private lateinit var adapter: ListAdapteArr? = null
private var baseList: List<FlightShdu> = listOf()
private var filteredList: MutableList<FlightShdu> = mutableListOf()
In your handleJson()
method, once the list has been populated with all the FlightShdu
objects, assign it to the baseList
baseList = list
Then assign your private lateinit var adapter
:
adapter = ListAdapteArr(this@MainActivity, baseList)
flight_arrivel_list.adapter = adapter
Have a method that takes the edit text search term and compares it with your list
fun searchList() {
filteredList.clear()
baseList.forEach {
if (it.contains(search.text.toString())) {
filteredList.add(it)
}
}
adapter.updateList(filteredList)
Then within your adapter change:
val list: ArrayList<FlightShdu>
to var list: ArrayList<FlightShdu>
and have a method like:
fun updateList(filteredList: List<FlightShdu>) {
list.clear()
list.addAll(filteredList)
notifyDataSetChanged()
}
With the updated list in activity, call the method with adapter.updateList(filteredList)
I would also recommend using a recyclerview
instead of a listview
RecyclerView vs. ListView
You could also look into using DiffUtils
as it offers nice smooth animations when transitioning between lists in the adapter. This answer was just to get the ball rolling for you.
val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = newList[newItemPosition] == oldList[oldItemPosition]
override fun getOldListSize(): Int = oldList.size
override fun getNewListSize(): Int = newList.size
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = newList[newItemPosition] == oldList[oldItemPosition]
}
diffResult.dispatchUpdatesTo(adapter)
Upvotes: 1