RecyclerView in Fragment not populating - kotlin

So I've been wrestling with this for days and I need some help. I've made this code work in an activity, but then I move it to a fragment it doesn't work. Everything else is the same between the two.
Using the debugger with the working Activity, the line
apiService = retrofit.create<HomeJsonApiService>(HomeJsonApiService::class.java)
goes to getItemCount(). However in the fragment it goes directly to onCreateView in the Fragment. I've attached my code below. Thanks in advance for the help! And be gentle. I'm still new to this :)
First is my fragment:
class TabHomeActivity : Fragment() {
val itemList = ArrayList<HomeCards>()
lateinit var adapter: HomeCardsAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var binding = FragmentTabHomeActivityBinding.inflate(layoutInflater)
adapter = HomeCardsAdapter()
var rv = binding.rvHomeCards
rv.adapter = adapter
loadData()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.cards_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
private fun loadData() {
ApiManager.getInstance().service.listHeroes()
.enqueue(object : Callback<ResponseData<List<HomeCards>>> {
override fun onResponse(
call: Call<ResponseData<List<HomeCards>>>,
response: Response<ResponseData<List<HomeCards>>>
) {
val listData: List<HomeCards> = response.body()!!.data
// updating data from network to adapter
itemList.clear()
itemList.addAll(listData)
adapter.updateData(itemList)
adapter.notifyDataSetChanged()
}
override fun onFailure(call: Call<ResponseData<List<HomeCards>>>, t: Throwable) {
}
})
}
}
The HTTP request:
data class ResponseData<T> (
val code: Int,
val data: T
)
interface HomeJsonApiService {
#GET("marvel-heroes.asp?h=2")
fun listHeroes(): retrofit2.Call<ResponseData<List<HomeCards>>>
}
class ApiManager {
private var apiService: HomeJsonApiService? = null
init {
createService()
}
val service: HomeJsonApiService get() = apiService!!
private fun createService() {
val loggingInterceptor =
HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
override fun log(message: String) {
Log.i("Retrofit", message)
}
})
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
val client = OkHttpClient.Builder()
.readTimeout(30, TimeUnit.SECONDS)
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.build()
val retrofit: Retrofit = Retrofit.Builder()
.client(client)
.baseUrl("https://www.mywebsite.com/jsonfolder/JSON/")
.addConverterFactory(GsonConverterFactory.create())
.build()
apiService = retrofit.create(HomeJsonApiService::class.java)
}
companion object {
private var instance: ApiManager? = null
fun getInstance(): ApiManager {
return instance ?: synchronized(this) {
ApiManager().also { instance = it }
}
}
}
}
And my adapter:
class HomeCardsAdapter() : RecyclerView.Adapter<HomeCardsAdapter.ViewHolder>() {
private lateinit var itemList: List<HomeCards>
lateinit var context: Context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
context = parent.context
val view = LayoutInflater.from(context).inflate(R.layout.cards_home, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return if (::itemList.isInitialized) itemList.size else 0
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind()
}
fun updateData(list: List<HomeCards>) {
itemList = list;
notifyDataSetChanged()
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
//var binding = ActivityMainBinding(layoutInflater(inf))
fun bind() {
val item = itemList.get(adapterPosition)
ViewHolder(itemView).itemView.findViewById<TextView>(R.id.cardHomeTitle).text = item.name
ViewHolder(itemView).itemView.findViewById<TextView>(R.id.cardHomeTitle).text = item.superheroName
Glide.with(context)
.load(item.photo)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.circleCrop()
.into(ViewHolder(itemView).itemView.findViewById<ImageView>(R.id.cardHomeIcon))
}
}
}
class HomeCards {
#SerializedName("superhero_name")
var superheroName: String = ""
var name: String = ""
var photo: String = ""
}

The main problem is:
var binding = FragmentTabHomeActivityBinding.inflate(layoutInflater)
That is inside on onCreate but onCreateView is returning another view inflater.inflate(R.layout.cards_home, container, false)
So you are applying the adapter to a recycler that is on the binding, but the view on the screen is inflated from the layout. Change it to this:
private lateinit var binding: FragmentTabHomeActivityBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
binding = FragmentTabHomeActivityBinding.inflate(layoutInflater, container, false)
return binding.root
}
And move the code from from onCreate to onViewCreated but make sure to use the lateinit binding
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
adapter = HomeCardsAdapter()
var rv = binding.rvHomeCards
rv.adapter = adapter
loadData()
}
After that there is a problem in your adapter: private lateinit var itemList: List<HomeCards> very specifically List<HomeCards>. The method notifyDataSetChanged doesn't work by changing or updating the reference of the data structure but when the collection is modified. Change it to this:
private val list = mutableListOf<HomeCards>()
override fun getItemCount(): Int {
return list.size()
}
fun updateData(list: List<HomeCards>) {
this.itemList.clear()
this.itemList.addAll(list)
notifyDataSetChanged()
}

If onResponse() gets called and provides response, verify that code updating UI is running on main/ui thread. Common source of issue when working with network (other threads).
activity?.runOnUiThread {
itemList.clear()
itemList.addAll(listData)
adapter.updateData(itemList)
adapter.notifyDataSetChanged()
}

Related

i want to add next page (every page is 10) to my recyclerview but it delet my last page

my recyclerview fragment:
this is the fragment that I set my recycler view , I want when touch the continue button (btn_continue) add the rest of the list, which is actually the next page, to my list when I click the button
But it deletes the previous list and displays the new list
and i use the kotlin coruotine, viewmodel and recyclerview
class AllUnpublishedAdsFragment : Fragment() {
lateinit var unpublishedAdsAdapter: UnpublishedAdsAdapter
var items = ArrayList<M_Ads>()
lateinit var loadMoreItems: ArrayList<M_Ads>
lateinit var scrollListener: RecyclerViewLoadMoreScroll
lateinit var mLayoutManager: RecyclerView.LayoutManager
val page = "1"
var newpage = page.toInt()
var navController: NavController? = null
lateinit var btn_continue: Button
private lateinit var viewModel: MainViewmodels
lateinit var token: String
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_all_unpublished_ads, container,
false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btn_continue = view.findViewById<Button>(R.id.btn_continueAds)
token = arguments?.getString(TOKEN_KEY).toString()
Log.i("TOKEN", token)
setupViewModel(token, page)
continueAds()
unpublishedAdsAdapter.itemClickListener = { item, position ->
val id = item.id
val bundle_id = Bundle()
bundle_id.putString(ID_KEY, id.toString())
navController = Navigation.findNavController(view)
//view.findNavController().navigate(R.id.action_UnpublishedAds_to_Detail,
bundle_id)
navController!!.navigate(
R.id.action_allUnpublishedAdsFragment_to_adsDetailFragment,
bundle_id
)
}
}
private fun setupViewModel(token: String, page: String) {
LoadingDialog.show(requireContext(), { ld ->
recy_unpublished_ads.layoutManager = LinearLayoutManager(activity)
val decoration = DividerItemDecoration(activity, DividerItemDecoration.VERTICAL)
recy_unpublished_ads.addItemDecoration(decoration)
viewModel = ViewModelProvider(this).get(MainViewmodels::class.java)
unpublishedAdsAdapter = UnpublishedAdsAdapter()
recy_unpublished_ads.adapter = unpublishedAdsAdapter
viewModel.adsListObserve().observe({ lifecycle }, { model ->
items.clear()
items.addAll(model.adsList!!)
unpublishedAdsAdapter.setUpdateData(items)
ld.dismiss()
btn_continue.visibility = View.VISIBLE
})
viewModel.getAdsList(token, page)
})
}
fun continueAds() {
var isTouched=false
btn_continue.setOnClickListener {
isTouched=true
newpage = newpage + 1
Log.i("CONTINUE", newpage.toString())
setupViewModel(token, newpage.toString())
unpublishedAdsAdapter.notifyDataSetChanged()
isTouched=false
}
}
RetrofitInstance class
class RetrofitInstance {
companion object{
fun getRetrofitInstance (): Retrofit{
// val interceptor = HttpLoggingInterceptor()
// interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
// val client: OkHttpClient = OkHttpClient.Builder().addInterceptor(interceptor).build()
val okHttpClient: OkHttpClient = OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.build()
return Retrofit.Builder()
.baseUrl(BASEURL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
}
}
}
my adapter:
class UnpublishedAdsAdapter : RecyclerView.Adapter<UnpublishedAdsAdapter.MyViewHolder>() {
var items = ArrayList<M_Ads>()
var itemClickListener: ((item: M_Ads, position: Int) -> Unit)? = null
lateinit var mcontext: Context
class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
class LoadingViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
fun setUpdateData(items: ArrayList<M_Ads>) {
this.items = items
notifyDataSetChanged()
}
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val img_ads = view.findViewById<ImageView>(R.id.img_recy_ads)
val txt_title = view.findViewById<TextView>(R.id.txt_recy_ads_title)
val txt_accountType = view.findViewById<TextView>(R.id.txt_recy_ads_acctype)
fun bind(data: M_Ads) {
txt_title.setText(data.title)
txt_accountType.setText(data.accountType)
if (!data.image1.equals("")) {
Picasso.with(img_ads.context).load(data.image1).into(img_ads)
} else {
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
mcontext = parent.context
return if (viewType == Constant.VIEW_TYPE_ITEM) {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.row_recy_unpublished_ads, parent, false)
MyViewHolder(view)
} else {
val view =
LayoutInflater.from(mcontext).inflate(R.layout.progress_loading, parent, false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
view.progressbar.indeterminateDrawable.colorFilter =
BlendModeColorFilter(Color.WHITE, BlendMode.SRC_ATOP)
} else {
view.progressbar.indeterminateDrawable.setColorFilter(
Color.WHITE,
PorterDuff.Mode.MULTIPLY
)
}
MyViewHolder(view)
}
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.bind(items.get(position))
handleClick(holder)
}
fun handleClick(holder: UnpublishedAdsAdapter.MyViewHolder) {
holder.itemView.setOnClickListener {
val position = holder.adapterPosition
itemClickListener?.invoke(items.get(position), position)
}
}
override fun getItemCount(): Int {
return items.size
}
my Viewmodel:
class MainViewmodels:ViewModel() {
lateinit var getAds:MutableLiveData<Main_ModelAds>
init {
getAds= MutableLiveData<Main_ModelAds>()
}
fun adsListObserve():MutableLiveData<Main_ModelAds>{
return getAds
}
fun getAdsList(token:String,page:String){
viewModelScope.launch(Dispatchers.IO) {
try {
Log.i("ERRORRES",token + "")
val retrofitInstance=RetrofitInstance.getRetrofitInstance().create(RetrofitService::class.java)
val response=retrofitInstance.unPublishedAdsList(token,page)
getAds.postValue(response)
}catch (ex:Exception){
Log.i("ERRORRES", ex.message.toString() + "")
}
}
}
What you want here is to update the list that you are showing when the user clicks the button.
In this case you should use ListAdapter.
You can refer to this article for implementation:
https://developer.android.com/reference/androidx/recyclerview/widget/ListAdapter

Flow with Room in Kotlin

i am new to kotlin android i am trying to use room with flow my code as follows
my entity as follows
#Entity(tableName = "user_data")
data class User (
#PrimaryKey(autoGenerate = true)
val id:Int,
val firstName:String,
val lastName:String,
val age:Int)
my database class as follows
#Database(entities = [User::class],version = 1,exportSchema = false)
abstract class UserDatabase :RoomDatabase(){
abstract fun userDao():UserDao
companion object{
#Volatile
private var INSTANCE:UserDatabase?=null
fun getDataBaseInstance(context:Context):UserDatabase
{
var tempInstance= INSTANCE
if(tempInstance!=null)
{
return tempInstance
}
synchronized(this)
{
val instance=Room.databaseBuilder(context.applicationContext,UserDatabase::class.java,"user_database")
.build()
INSTANCE=instance
return instance
}
}
}
}
my dao as follows
#Dao
interface UserDao {
#Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun addUser(user:User) :Long
#Query("SELECT * from user_data")
fun fetchUserData(): Flow<List<User>>
}
my repository as follows
class UserRepository(private val userDao:UserDao) {
suspend fun addUser(user:User){
val rowid:Long=userDao.addUser(user)
}
fun readAllUserData():Flow<List<User>>
{
val temp=userDao.fetchUserData()
return temp
}
}
my view model as follows
class UserViewModel(application: Context) :ViewModel() {
private lateinit var _readAllData:MutableLiveData<List<User>>
private var repository: UserRepository
private var _firstName:String="Akshay"
val firstName:String get()=_firstName
private var _lastName:String=""
val lastName:String get()=_lastName
private var _age:String = ""
val age:String get()=_age
val readAllData:LiveData<List<User>> get()=_readAllData
init {
val userDao= UserDatabase.getDataBaseInstance(application).userDao()
repository=UserRepository(userDao)
}
fun setFirstName(name:String)
{
_firstName=name
}
fun setLastName(name:String)
{
_lastName=name
}
fun setAge(name:String)
{
_age=name
}
fun addUserToDB()
{
viewModelScope.launch(Dispatchers.IO) {
println("Inside addUserDB")
repository.addUser(User(0,_firstName,_lastName,_age.toInt()))
}
}
fun readDataFromUserTable():LiveData<List<User>>
{
return repository.readAllUserData().asLiveData()
}
}
class UserViewModelFactory(private val context: Context):ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if(modelClass.isAssignableFrom(UserViewModel::class.java))
{
return UserViewModel(context)as T
}
throw IllegalArgumentException("Unknown class")
}
my fragment as follows
class ListFragment : Fragment() {
private var binding:FragmentListBinding?=null
private val sharedViewModel:UserViewModel by activityViewModels {UserViewModelFactory(requireContext())}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val fragmentBinding=FragmentListBinding.inflate(inflater,container,false);
binding=fragmentBinding
return fragmentBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.apply {
viewModel=sharedViewModel
lifecycleOwner=viewLifecycleOwner
listFragment=this#ListFragment
ToastCount()
}
}
private fun ToastCount() {
var temp=sharedViewModel.readDataFromUserTable()
Toast.makeText(requireContext(), temp.size.toString(),Toast.LENGTH_SHORT).show()
}
fun addNewUser()
{ findNavController().navigate(R.id.action_listFragment_to_addFragment)
}
}
I can add data I see data in my database inspector but I can not read data it always return me null in my ViewModel ... I have added all necessary dependencies somebody please guild me what is it I am doing wrong? Thanks in advance

RecyclerView adapter inside a fragment is not updating when data changes

I have an activity that contains 2 tabs and each tab has a fragment inside ViewPager. Each fragment have a RecyclerView.
When I navigate to another activity the data inside the Fragments should be updated. Although the data is being sent correctly to the fragment, the original data is displayed.
I tried using notifyDataSetChanged() method inside the fragment but it didn't work.
I also tried calling it from the activity like:
if (!pickedItemsList.isNullOrEmpty() && notScannedItemsFragment != null && notScannedItemsFragment.isAdded)
{
notScannedItemsFragment.notScannedItemsAdapter.notifyDataSetChanged()
}
However, it didn't work too.
That's how I am initiating the fragment:
override fun initFragments(savedInstanceState: Bundle?, pickedItemsList: ArrayList<OrderDetail>, remainigItemsList: ArrayList<OrderDetail>) {
val listener: ItemsInteractionListener = object : ItemsInteractionListener {
override fun onSwipeToRefresh() {
presenter.onSwipeToRefresh()
}
}
if (!pickedItemsList.isNullOrEmpty() && notScannedItemsFragment != null && notScannedItemsFragment.isAdded) {
notScannedItemsFragment.notScannedItemsAdapter.notifyDataSetChanged()
scannedItemsFragment = ScannedItemsFragment().newInstance(remainingItemsList)
notScannedItemsFragment = NotScannedItemsFragment().newInstance(pickedItemsList)!!
} else {
scannedItemsFragment = ScannedItemsFragment().newInstance(arrayListOf())
notScannedItemsFragment = NotScannedItemsFragment().newInstance(allItemsList)!!
}
scannedItemsFragment.setListener(listener)
notScannedItemsFragment.setListener(listener)
}
allItemList is the original list and pickedItemsList and remainingItemsList are the lists after the changes (that I got from the other activity)
This is one of the fragments classes:
class NotScannedItemsFragment : BaseFragment() {
private var listener: ItemsInteractionListener? = null
lateinit var notScannedItemsAdapter: OrderItemListingAdapter
private var itemRemainingCount: Int = 0
lateinit var notScannedItems: ArrayList<OrderDetail>
lateinit var recyclerView: RecyclerView
lateinit var fragmentView: View
fun newInstance(notScannedItems: ArrayList<OrderDetail>): NotScannedItemsFragment? {
val notScannedItemsFragment = NotScannedItemsFragment()
val args = Bundle()
val order = Gson().toJson(notScannedItems)
args.putString(IntentConstants.EXTRA_NOT_SCANNED_ITEM_LIST, order)
notScannedItemsFragment.setArguments(args)
return notScannedItemsFragment
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val str = arguments?.getString(IntentConstants.EXTRA_NOT_SCANNED_ITEM_LIST)
notScannedItems = Gson().fromJson(
str,
object : TypeToken<List<OrderDetail?>?>() {}.type
) as ArrayList<OrderDetail>
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
fragmentView = inflater.inflate(R.layout.fragment_not_scanned_items, container, false)
recyclerView = fragmentView.notScannedItemListing
return fragmentView
}
fun setListener(listener: ItemsInteractionListener) {
this.listener = listener
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setUpRecycler(view)
super.onViewCreated(view, savedInstanceState)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
}
private fun setUpRecycler(view: View) {
imageLoader = ImageLoader(context)
notScannedItemsAdapter = OrderItemListingAdapter(
false,
imageLoader,
object : ImageClickListener {
override fun onImageClick(
itemName: String,
itemQuantity: Int,
url: String,
barcodes: List<String>?
) {
startImageFullViewActivity(itemName, itemQuantity, url, barcodes)
}
})
notScannedItemsAdapter.addItem(notScannedItems)
notScannedItemsAdapter.notifyDataSetChanged()
view.notScannedItemListing.apply {
view.notScannedItemListing.layoutManager = LinearLayoutManager(context)
view.notScannedItemListing.setHasFixedSize(true)
view.notScannedItemListing.isNestedScrollingEnabled = false
adapter = notScannedItemsAdapter
}
notScannedItemsAdapter.printList()
}
fun showOrderItemListing(notScannedItems: ArrayList<OrderDetail>) {
this.notScannedItems = notScannedItems
itemRemainingCount = notScannedItems.size
}
fun getItemsRemainingCount(): Int{
return notScannedItems.size
}
fun clearItems() {
notScannedItemsAdapter.clearItems()
}
fun updateAdapterContent(pickedItemsList: ArrayList<OrderDetail>) {
if(this::notScannedItemsAdapter.isInitialized ) {
notScannedItemsAdapter.clearItems()
notScannedItemsAdapter.addItem(notScannedItems)
notScannedItemsAdapter.notifyDataSetChanged()
}
}
}
It turns out since I'm getting the list from arguments it's not updating with the new list. As stated here: Anything initialized in onCreate() is preserved if the Fragment is paused and resumed.
So I added a boolean variable loadListFromArgs and I only loaded the list from args if it's true and when I call updateAdapterContent I set it to false.

how to send a Cursor instance from one fragment to a fragment which contains a recyclerview with same activity in kotlin

I am still doing my first steps with app development, so i would appreciate any kind of feedback for my code.
To my problem. I got two Fragments, "ListFragment.kt" and "SetListFilters.kt". My intention is to create a cursor instance in SetListFilters and then when I press a "apply"-button i perform a popBackStack while sending the cursor instance to ListFrament. To my understanding ListFragment will call OnCreateView() and there i want to pass the new cursor to my adapter so that the Recyclerview get filtered. I tried so many things but nothing worked for me. I hope you can help me. Here is my Code:
class SetListFilters(var transactionDB: SQLiteDatabase, var adapter: TransactionAdapter):Fragment(R.layout.fragment_set_list_filters), DataPassListener {
private lateinit var gridView : GridView
private lateinit var btnYearFilter : Button
private lateinit var btnMonthFilter : Button
private lateinit var btnWeekFilter : Button
private lateinit var btnRevenueFilter : Button
private lateinit var btnExpeneseFilter : Button
private lateinit var btnNeutralFilter : Button
private lateinit var btnSbmtFilter : Button
private lateinit var tvShowAmountFilter : TextView
private lateinit var sbAmountFilters : SeekBar
private val viewModel: ListViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_set_list_filters, container, false)
setUpViews(view)
setUpButtonOnclick()
setUpSeekbar()
val arrayAdapter: ArrayAdapter<CategoryEnum> = ArrayAdapter<CategoryEnum>(activity!!, android.R.layout.simple_list_item_multiple_choice, CategoryEnum.values())
gridView.setAdapter(arrayAdapter)
// When the user clicks on the GridItem
/*gridView.setOnItemClickListener(OnItemClickListener { a, v, position, id ->
val o: Any = gridView.getItemAtPosition(position)
})*/
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.filters.observe(viewLifecycleOwner, Observer { set ->
// Update the selected filters UI
}
}
fun onFilterSelected(filter: Filter) = viewModel.addFilter(filter)
fun onFilterDeselected(filter: Filter) = viewModel.removeFilter(filter)
private fun upDateQueryForDB(){
}
private fun getAllItemsNeu(): Cursor {
val selArgs = arrayOf("r")
return transactionDB!!.query(
TransactionList.TransactionEntry.TABLE_NAME,
null,
"type = ?",
selArgs,
null,
null,
TransactionList.TransactionEntry.COLUMN_CREATEDAT + " DESC")
}
private fun setUpViews(view: View){
gridView = view.findViewById(R.id.gvCategoryFilter )
btnExpeneseFilter = view.findViewById(R.id.btnExpenseFilter)
btnMonthFilter = view.findViewById(R.id.btnMonthFilter)
btnWeekFilter = view.findViewById(R.id.btnWeekFilter)
btnNeutralFilter = view.findViewById(R.id.btnNeutralFilter)
btnRevenueFilter = view.findViewById(R.id.btnRevenueFilter)
btnSbmtFilter = view.findViewById(R.id.btnSbmtFilter)
btnYearFilter = view.findViewById(R.id.btnYearFilter)
sbAmountFilters = view.findViewById(R.id.seekBar)
tvShowAmountFilter = view.findViewById(R.id.tvFilterAmount)
}
private fun setUpButtonOnclick(){
btnExpeneseFilter.setOnClickListener { changeButtonAppearance(btnExpeneseFilter) }
btnMonthFilter.setOnClickListener { changeButtonAppearance(btnMonthFilter) }
btnWeekFilter.setOnClickListener { changeButtonAppearance(btnWeekFilter) }
btnNeutralFilter.setOnClickListener { changeButtonAppearance(btnNeutralFilter) }
btnRevenueFilter.setOnClickListener { changeButtonAppearance(btnRevenueFilter) }
btnYearFilter.setOnClickListener { changeButtonAppearance(btnYearFilter) }
btnSbmtFilter.setOnClickListener{
mainActivity.passDataCom(getAllItemsNeu())
activity!!.supportFragmentManager.popBackStack()
}
}
private fun changeButtonAppearance(button:Button) {
if(button.tag == "notPressed"){
button.setBackgroundResource(R.drawable.rounded_select_button_pressed)
button.setTextColor(Color.WHITE)
button.tag = "pressed"
}else{
button.setBackgroundResource(R.drawable.rounded_select_button)
button.setTextColor(ContextCompat.getColor(context!!,R.color.mainBlue))
button.tag ="notPressed"
}
}
private fun setUpSeekbar(){
sbAmountFilters.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {
// Display the current progress of SeekBar
tvShowAmountFilter.text = "< $i"
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
// Do something
//Toast.makeText(context!!,"start tracking",Toast.LENGTH_SHORT).show()
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
// Do something
//Toast.makeText(context!!,"stop tracking",Toast.LENGTH_SHORT).show()
if(tvShowAmountFilter.text.toString()=="< 0"){
tvShowAmountFilter.text = "none"
}
}
})
}
override fun onAttach(context: Context) {
super.onAttach(context)
try{
mCallback = (OnImageClickListener) //folled the tutorial, dont know what to replace it with
}
}
}
class ListFragment:Fragment(R.layout.fragment_list) {
lateinit var transactionDB : SQLiteDatabase
lateinit var adapter : TransactionAdapter
private lateinit var filterBtn : ImageButton
private lateinit var flActBtn : FloatingActionButton
var mCursorFilter : Cursor? = null
private val viewModel: ListViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val dbHelper = TransactionDBHelper(activity)
transactionDB = dbHelper.writableDatabase
adapter = TransactionAdapter(activity!!, getAllItems())
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.filteredList.observe(viewLifecycleOwner, Observer { list ->
//TODO
}
}
private fun addRandomTransactionItem() {
var a = 1234.56
for (i in 0..10) {
if(i%2==0){
transactionDB.execSQL("INSERT INTO transactionList (type, amount, category, createdAt) VALUES('r', ${a}, 'K', CURRENT_TIMESTAMP)")
adapter.swapCursor(getAllItems())
}else if(i%5==0){
transactionDB.execSQL("INSERT INTO transactionList (type, amount, category, createdAt) VALUES('ne', ${a}, 'K', CURRENT_TIMESTAMP)")
adapter.swapCursor(getAllItems())
}else if(i%6==0){
transactionDB.execSQL("INSERT INTO transactionList (type, amount, category, createdAt) VALUES('ne', ${a}, 'K', CURRENT_TIMESTAMP)")
adapter.swapCursor(getAllItems())
}else{
transactionDB.execSQL("INSERT INTO transactionList (type, amount, category, createdAt) VALUES('e', ${a}, 'K', CURRENT_TIMESTAMP)")
adapter.swapCursor(getAllItems())
}
}
}
private fun getAllItems(): Cursor {
return transactionDB!!.query(
TransactionList.TransactionEntry.TABLE_NAME,
null,
null,
null,
null,
null,
TransactionList.TransactionEntry.COLUMN_CREATEDAT + " DESC")
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_list, container, false)
val rvRecyclerView = view.findViewById<RecyclerView>(R.id.rvRecyclerView)
rvRecyclerView.layoutManager = LinearLayoutManager(activity)
if(mCursorFilter!=null){
adapter.swapCursor(mCursorFilter!!)
}
rvRecyclerView.adapter = this.adapter
rvRecyclerView.addItemDecoration(MarginItemDecoration(10))
flActBtn = view.findViewById(R.id.floatingActionButton)
flActBtn.setOnClickListener {
var ft:FragmentTransaction = activity!!.supportFragmentManager.beginTransaction()
ft.replace(R.id.flFrameLayout, AddItemFragment(transactionDB, adapter))
ft.addToBackStack(null)
ft.commit()
}
filterBtn=view.findViewById(R.id.ibFilterBtn)
filterBtn.setOnClickListener {
var ft:FragmentTransaction = activity!!.supportFragmentManager.beginTransaction()
ft.replace(R.id.flFrameLayout, SetListFilters(transactionDB, adapter))
ft.addToBackStack(null)
ft.commit()
}
addRandomTransactionItem()
return view
}
}
class MainActivity() : AppCompatActivity() {
var mCursorFilters: Cursor? = null
private val viewModel: ItemViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel.selectedItem.observe(this, Observer { item ->
// TODO
})
val homeFragment = HomeFragment()
val listFragment = ListFragment()
val profileFragment = ProfileFragment()
setCurrentFragment(homeFragment)
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationView)
bottomNavigationView.setOnNavigationItemSelectedListener {
var ft: FragmentTransaction = this.supportFragmentManager.beginTransaction()
when (it.itemId) {
R.id.pageHome -> ft.replace(R.id.flFrameLayout, homeFragment) // setCurrentFragment(homeFragment)
R.id.pageList -> ft.replace(R.id.flFrameLayout, listFragment) //setCurrentFragment(listFragment)
R.id.pageProfile -> ft.replace(R.id.flFrameLayout, profileFragment) //setCurrentFragment(profileFragment)
}
// ft.replace(R.id.flFrameLayout, AddItemFragment())
ft.addToBackStack(null)
ft.commit()
true
}
}
private fun setCurrentFragment(fragment: Fragment){
supportFragmentManager.beginTransaction().apply {
replace(R.id.flFrameLayout, fragment)
commit()
}
}
}

Get Wifi scan Result List in Kotlin

I want to receive all avaiable wifi to a ResultList using broadcastReceiver override method onReceive(). Don't know why I cannot go into my override method ( Can't catch breakpoint at println("On receive active") )
After that I checked resultList by "If" statement but it occures that resultList is empty.
What am I doing wrong ?
My code below :
class AddNewDeviceFragment : Fragment() {
var resultList = ArrayList<ScanResult>()
private var adapter: NewDeviceAdapter = NewDeviceAdapter(arrayListOf())
private lateinit var model: NewDeviceViewModel
private lateinit var rootView: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
rootView = inflater.inflate(R.layout.fragment_addnewdevice, container, false)
return rootView
}
override fun onStart() {
super.onStart()
var newDevicesRecycledView = rootView.findViewById(R.id.newDevicesRecycledView) as RecyclerView
newDevicesRecycledView.layoutManager = LinearLayoutManager(activity)
newDevicesRecycledView.adapter = adapter
//ViewModel
model = ViewModelProviders.of(this).get(NewDeviceViewModel::class.java)
//LiveData
model.getNewDevices()
.observe(viewLifecycleOwner, Observer<MutableList<NewDevice>> { newDevices ->
adapter.addDevice(newDevices)
})
refreshButton.setOnClickListener { startScan() }
}
fun startScan() {
model.clearAllData()
val wifiManager = context?.getSystemService(Context.WIFI_SERVICE) as WifiManager
val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(p0: Context?, p1: Intent?) {
resultList = wifiManager.scanResults as ArrayList<ScanResult>
println("On receive active")
for (result in resultList) {
model.addNewDevice(NewDevice(result.SSID.toString()))
}
}
}
if (!wifiManager.isWifiEnabled) {
Toast.makeText(activity, "Wifi is disable... We need to enable it", Toast.LENGTH_LONG).show()
wifiManager.setWifiEnabled(true)
}
context?.registerReceiver(broadcastReceiver, IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
if(resultList.isEmpty())
Toast.makeText(activity,"ResultList empty",Toast.LENGTH_LONG).show()
wifiManager.startScan()
Toast.makeText(activity,"Scanning Wifi",Toast.LENGTH_LONG).show()
}
}