Cannot infer a type for this parameter please specify it explicitly? - kotlin

I have recently developed android app using Kotlin but I am getting the following error
Cannot infer a type for this parameter. Please specify it explicitly
below screenshot of the error
below my class where I am getting error
class AddBookingActivity : AppCompatActivity() {
#BindView(R.id.attendees_recycler_view)
internal var mAttendeeRecyclerView: RecyclerView? = null
#BindView(R.id.start_time_edit_text)
internal var mStartTime: EditText? = null
#BindView(R.id.end_time_edit_text)
internal var mEndTime: EditText? = null
private var mAttendeeName: EditText? = null
private var mAttendeeEmail: EditText? = null
private var mAttendeePhoneNumber: EditText? = null
private var mAttendeeAdapter: AttendeeAdapter? = null
private var mAlertDialog: AlertDialog? = null
private val mAttendeeItemList = ArrayList<AttendeeItem>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_booking)
ButterKnife.bind(this)
mAttendeeRecyclerView!!.layoutManager = LinearLayoutManager(this)
mAttendeeAdapter = AttendeeAdapter(this)
mAttendeeAdapter!!.setAttendeeList(mAttendeeItemList)
mAttendeeRecyclerView!!.adapter = mAttendeeAdapter
}
#OnClick(R.id.toolbar_back_button)
internal fun onBackButtonClicked() {
onBackPressed()
}
#OnClick(R.id.start_time_edit_text)
internal fun onStartTimeClicked() {
showTimePickerDialog(mStartTime)
}
#OnClick(R.id.end_time_edit_text)
internal fun onEndTimeClicked() {
showTimePickerDialog(mEndTime)
}
#OnClick(R.id.fab_add_attendee)
internal fun onAddAttendeeClicked() {
val inflater = this.layoutInflater
val dialogView = inflater.inflate(R.layout.add_attendee_view, null)
mAttendeeName = dialogView.findViewById(R.id.attendee_name)
mAttendeeEmail = dialogView.findViewById(R.id.attendee_email)
mAttendeePhoneNumber = dialogView.findViewById(R.id.attendee_phone_number)
mAlertDialog = AlertDialog.Builder(this, R.style.AlertDialog)
.setTitle("Input attendee details")
.setPositiveButton("Add") { dialog, which ->
val item = AttendeeItem()
item.name = mAttendeeName!!.text.toString()
item.email = mAttendeeEmail!!.text.toString()
item.phoneNumber = mAttendeePhoneNumber!!.text.toString()
mAttendeeItemList.add(item)
mAttendeeAdapter!!.setAttendeeList(mAttendeeItemList)
mAttendeeAdapter!!.notifyItemInserted(mAttendeeItemList.size)
}
.setNegativeButton("Cancel", null)
.setView(dialogView).create()
mAlertDialog!!.show()
}
private fun showTimePickerDialog(editText: EditText?) {
val myCalender = Calendar.getInstance()
val hour = myCalender.get(Calendar.HOUR_OF_DAY)
val minute = myCalender.get(Calendar.MINUTE)
#SuppressLint("DefaultLocale")
val myTimeListener = { view, hourOfDay, minute1 ->
if (view.isShown()) {
myCalender.set(Calendar.HOUR_OF_DAY, hourOfDay)
myCalender.set(Calendar.MINUTE, minute1)
editText!!.setText(String.format(String.format("%s:%s", hourOfDay.toString(), minute1.toString())))
}
}
val timePickerDialog = TimePickerDialog(this, android.R.style.Theme_Holo_Light_Dialog_NoActionBar, myTimeListener, hour, minute, true)
timePickerDialog.setTitle("Choose hour:")
timePickerDialog.window!!.setBackgroundDrawableResource(android.R.color.transparent)
timePickerDialog.show()
}
}

You have to specify the interface to help Kotlin compiler:
#SuppressLint("DefaultLocale")
val myTimeListener = TimePickerDialog.OnTimeSetListener { view, hourOfDay, minute1 ->
if (view.isShown()) {
myCalender.set(Calendar.HOUR_OF_DAY, hourOfDay)
myCalender.set(Calendar.MINUTE, minute1)
editText!!.setText(String.format(String.format("%s:%s", hourOfDay.toString(), minute1.toString())))
}
}

Related

Type mismatch: inferred type is CategoryQuran but MainAdapter.onSelectData

i am just trying to code for Get API, but when i write some code for that. it seems error, i took a few hours but i not get the point, can you guys help me?
this is the Activity (ActivityQuran)
class CategoryQuran : AppCompatActivity() {
var mainAdapter: MainAdapter? = null
var mProgressBar: ProgressDialog? = null
var modelMain: MutableList<ModelMain> = ArrayList()
private lateinit var adapter: MainAdapter
private lateinit var postArrayList: ArrayList<MainAdapter>
private lateinit var progressDialog: ProgressDialog
private val TAG = "MAIN_TAG"
private var isSearch = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail_artikel)
//setup progress dialog
progressDialog = ProgressDialog (this)
progressDialog.setTitle("Mohon Tunggu")
mProgressBar = ProgressDialog(this)
mProgressBar!!.setTitle("Mohon Tunggu")
mProgressBar!!.setCancelable(false)
mProgressBar!!.setMessage("Sedang menampilkan data...")
llAbout.setOnClickListener {
startActivity(Intent(this#CategoryQuran, AboutActivity::class.java)) }
llPP.setOnClickListener {
startActivity(Intent(this#CategoryQuran, PrivacyPolicyActivity::class.java)) }
llDisclaimer.setOnClickListener {
startActivity(Intent(this#CategoryQuran, DisclaimerActivity::class.java)) }
rvListArticles.setHasFixedSize(true)
rvListArticles.setLayoutManager(LinearLayoutManager(this))
//get data
listArticle
//search
searchBtn.setOnClickListener {
}
}
private val listArticle: Unit
private get() {
mProgressBar!!.show()
AndroidNetworking.get(BloggerApi.ListPost)
.setPriority(Priority.MEDIUM)
.build()
.getAsJSONObject(object : JSONObjectRequestListener {
override fun onResponse(response: JSONObject) {
try {
mProgressBar!!.dismiss()
val playerArray = response.getJSONArray("items")
for (i in 0 until playerArray.length()) {
val jsonObject1 = playerArray.getJSONObject(i)
val dataApi = ModelMain()
dataApi.title = jsonObject1.getString("title")
dataApi.content = jsonObject1.getString("content")
dataApi.labels = jsonObject1.getString("labels")
dataApi.url = jsonObject1.getString("url")
val datePost = jsonObject1.getString("published")
val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
val outputFormat = SimpleDateFormat("dd-MM-yyyy")
val date = inputFormat.parse(datePost)
val datePostConvert = outputFormat.format(date)
dataApi.published = datePostConvert
val jsonObject2 = jsonObject1.getJSONObject("author")
val authorPost = jsonObject2.getString("displayName")
dataApi.author = authorPost
val jsonObject3 = jsonObject2.getJSONObject("image")
val authorImage = jsonObject3.getString("url")
dataApi.authorImage = Uri.parse("http:$authorImage").toString()
modelMain.add(dataApi)
showListArticle()
}
} catch (e: JSONException) {
e.printStackTrace()
Toast.makeText(this#CategoryQuran,
"Gagal menampilkan data!", Toast.LENGTH_SHORT).show()
} catch (e: ParseException) {
e.printStackTrace()
Toast.makeText(this#CategoryQuran,
"Gagal menampilkan data!", Toast.LENGTH_SHORT).show()
}
}
override fun onError(anError: ANError) {
mProgressBar!!.dismiss()
Toast.makeText(this#CategoryQuran,
"Tidak ada jaringan internet!", Toast.LENGTH_SHORT).show()
}
})
}
private fun showListArticle(){
mainAdapter = MainAdapter(this#CategoryQuran, modelMain, this )
rvListArticles!!.adapter = mainAdapter
}
private fun searchPosts(query: String) {
mainAdapter = MainAdapter(this#CategoryQuran, modelMain, this)
rvListArticles!!.adapter = mainAdapter
}
override fun onSelected(modelMain: ModelMain) {
val intent = Intent(this#CategoryQuran, DetailArtikelActivity::class.java)
intent.putExtra("detailArtikel", modelMain)
startActivity(intent)
}
}
i got error in 'this'
private fun showListArticle(){
mainAdapter = MainAdapter(this#CategoryQuran, modelMain, this )
rvListArticles!!.adapter = mainAdapter
}
private fun searchPosts(query: String) {
mainAdapter = MainAdapter(this#CategoryQuran, modelMain, this)
rvListArticles!!.adapter = mainAdapter
}
both show 'Type mismatch: inferred type is CategoryQuran but MainAdapter.onSelectData! was expected'
Can you guys help me? please
Ok so the problem is i am have to add OnSelectData in my Class, in my case what i have to do is add MainAdaper.OnSelectData
so Before it like :
class CategoryQuran : AppCompatActivity() {
and after it like :
class CategoryQuran : AppCompatActivity(), MainAdapter.OnSelectData {
thats my fault, im too rush when i coding it

Data fetch from API not showing on recyclerview MVVM kotlin

I got blocked for this problem, Api will call and get the objects from the response and it will display on the recyclerview. But it is not showing,
fetchProductCategories will do the api call.
prepareProducts will handle the fetched from fetchProductCategories
Fragment:
#AndroidEntryPoint
class ProductsWelcomeFragment : BaseProductsFragment<ProductsWelcomeViewModel, ProductsWelcomeFragmentBinding>() {
private val TAG = "ProductsWelcomeFragment"
#Inject
lateinit var animationQueue: AnimationQueue
override fun getViewModelClass(): KClass<ProductsWelcomeViewModel> = ProductsWelcomeViewModel::class
override fun getContentViewRes(): Int = R.layout.products_welcome_fragment
private val cordovaViewModel: CordovaViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
/**
* Initialize only once when everytime accessing products screen.
* */
sharedViewModel.initialSetUpRequest()
viewModel.fetchProductCategories()
}
override fun onBindView() {
with(dataBinding) {
viewModel = this#ProductsWelcomeFragment.viewModel
title = getString(R.string.products_screen_welcome_header)
recyclerViewProducts.configure()
executePendingBindings()
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.productCategoriesLiveData.observe(viewLifecycleOwner) {
Log.i(TAG, it.toString())
viewModel.items.observe(viewLifecycleOwner) {
viewModel.prepareProducts()
}
}
viewModel.showProgress.observe(viewLifecycleOwner) {}
viewModel.failedAtRetrievingData.observe(viewLifecycleOwner) {
// showErrorScreen(true)
}
}
private fun RecyclerView.configure() {
with(dataBinding.recyclerViewProducts) {
addItemBindings(SectionHeaderItemViewBinder)
addItemBindings(SpaceItemViewDtoBinder)
addItemBindings(getListButtonItemViewBinder(ProductItem.NormalProduct::dto, ::onProductItemClick))
addItemBindings(getListBigtileItemViewBinder(ProductItem.FeaturedProduct::dto, ::onProductItemClick))
}
}
private fun onProductItemClick(product: ProductItem.NormalProduct) {
when (product.id) {
else -> { // TODO : )}
}
// TODO : implement move to another screen
}
private fun onProductItemClick(product: ProductItem.FeaturedProduct) {
// TODO : implement move to another screen
}
private fun showErrorScreen(isDataRetrievalError: Boolean) {
val dismissAction = ErrorHandlingAction(
getString(R.string.native_done),
null,
null,
ButtonType.PRIMARY
) { dismissDialog ->
dismissDialog.dismiss()
if (isDataRetrievalError) {
findNavController().popBackStack()
}
}
DialogFactory().showBottomDialog(
fragmentManager = parentFragmentManager,
window = requireActivity().window,
title = getString(R.string.native_error_title),
description = getString(R.string.online_identity_something_went_wrong_error_description),
iconId = R.drawable.ic_error_thick_exclamation_icon,
errorHandlingActions = arrayOf(dismissAction),
isHtmlDescription = true
)
}
private fun openCordovaScreen(destination: CordovaPage) {
cordovaViewModel.requestPage(destination)
findNavController().popBackStack(R.id.homeScreenMainFragment, false)
}
}
ViewModel:
#HiltViewModel
class ProductsWelcomeViewModel #Inject constructor(
private val productsRepository: ProductsRepository
) : BaseRequestViewModel(), ViewModelWithItems {
private val TAG = "ProductsWelcomeViewModel"
private val _failedAtRetrievingData = SingleLiveEvent<Boolean>()
val failedAtRetrievingData: LiveData<Boolean> = _failedAtRetrievingData
private val _showProgress = MutableLiveData<Boolean>()
val showProgress: LiveData<Boolean> = _showProgress
private val onProductCategories: SingleLiveEvent<ProductBasketsCategoriesModel?> = SingleLiveEvent()
val productCategoriesLiveData: LiveData<ProductBasketsCategoriesModel?> = onProductCategories
private val _items: MutableLiveData<List<Any>> = MutableLiveData()
override val items: LiveData<List<Any>> = _items
fun fetchProductCategories() {
viewModelScope.launch {
request({ productsRepository.getProductCategories() },
success = { response -> onProductCategories.value = response },
failure = { })
}
}
fun prepareProducts() {
_items.value = mutableListOf<Any>().apply {
productCategoriesLiveData.value?.embedded?.categories?.filter { categories ->
categories.isFeatured == true }?.let { filteredCategories ->
add(HeaderItem(ListSectionHeaderItemViewDto(
text = TextLine(
textRes = if (filteredCategories.isNotEmpty()) {
R.string.products_screen_welcome_header } else { null }
)
)
))
filteredCategories.toItems()?.let { addAll(it) }
}
productCategoriesLiveData.value?.embedded?.categories?.filter { categories ->
categories.isFeatured == false }.let { filteredCategories ->
if (filteredCategories != null) {
add(HeaderItem(ListSectionHeaderItemViewDto(
text = TextLine(
textRes = if (filteredCategories.isNotEmpty()) {
R.string.products_screen_welcome_header } else { null }
)
)
))
}
filteredCategories.toItems()?.let { addAll(it) }
}
}
}
private fun List<CategoriesItemModel>?.toItems(): List<ProductItem>? =
this?.mapIndexed { index, item ->
if (item.isFeatured == true) {
ProductItem.FeaturedProduct(
id = item.id as Any,
name = item.name,
dto = BigTileDto(
title = TextLine(text = item.name),
image = item.id.toString().let { toFeatureIcon(it, item.isFeatured) },
description = TextLine(item.description.toString()),
background = BackgroundType.SINGLE
)
)
} else {
ProductItem.NormalProduct(
id = item.id as Any,
name = item.name,
dto = ListButtonItemViewDto(
firstLine = TextLine(text = item.name),
rightDrawable = R.drawable.ic_arrow_right,
separatorDrawable = R.drawable.list_divider_margin_start_72dp,
background = index.indexToBackgroundType(this.size),
avatarDto = AvatarDto(iconBackgroundColor = R.color.ubs_concrete, avatarSize = AvatarDto.AvatarSize.SMALL_ICON_SIZE, iconId = toFeatureIcon(
item.id, item.isFeatured
)),
)
)
}
}
private fun toFeatureIcon(id: String?, isFeature: Boolean?): Int = if (ProductFeature.verify(id) == true) {
ProductFeature.icon()
} else { if (isFeature == true) { R.drawable.abc_vector_test } else {
R.drawable.balloon_illustration } }
}

Could not find Fragment constructor kotlin

When creating a popular fragment, I get an empty constructor error.
Please take a look at the code I wrote and how can I pass data when creating fragments?
mAdapter = SubPagerAdapter(childFragmentManager)
for (doc in it.docs!!) {
mAdapter.addFragment(
PopularFragment(doc.code, "#${doc.name}", 10),
doc.name
)
}
viewpager.adapter = mAdapter
tabs.setupWithViewPager(viewpager)
class PopularFragment(private val hashTagsCode: Int, private val title: String, private val ItemCount: Int) : Fragment() {
var mHashTagsCode = hashTagsCode
var mTitle = title
var mItemCount = ItemCount
}
You should always pass the data to Fragment using Bundle as arguments
class PopularFragment : Fragment() {
var mHashTagsCode = 0
lateinit var mTitle :String
var mItemCount = 0
companion object{
fun instance(hashTagsCode: Int, title: String, itemCount: Int){
val data = Bundle()
data.putString("hash_tag_codes", hashTagsCode)
data.putString("title", title)
data.putString("item_count", itemCount)
return PopularFragment().apply{
arguments = data
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
mItemCount = arguments?.getInt("item_count")?:0
mHashTagsCode = arguments?.getInt("hash_tag_codes")?:0
mTitle = arguments?.getString("title")
}
}
And for creating instance
mAdapter = SubPagerAdapter(childFragmentManager)
for (doc in it.docs!!) {
mAdapter
.addFragment(PopularFragment.intsance(doc.code, "#${doc.name}", 10),doc.name)
}
viewpager.adapter = mAdapter
tabs.setupWithViewPager(viewpager)

How to change recyclerview item and sub items when clicked and also get the data in the position clicked from a fragment?

I have 2 Recyclerviews in a fragment. Each item consists of 2 textview. When clicked, i want to change the color of item background and the 2 tvs and get the listofData(position) clicked also then send these s pieces of data to an activity.
The problem is 2 rvs each have its own adapter so i can't call the activity and check if data is selected from both adapters. And when i try it from the fragment i get the adapter position right but the view colors are not being changed correctly.
My RV element
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="2dp"
android:paddingBottom="10dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:background="#drawable/date_time_background"
android:elevation="0dp"
android:gravity="center"
android:layout_marginEnd="5dp"
android:orientation="vertical"
android:id="#+id/item_linear_layout">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/dateNameTV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Sat"
android:textColor="#color/black_65"
android:textSize="16sp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/dateNumTV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="23/5"
android:textColor="#color/black_65"
android:textSize="16sp" />
</LinearLayout>
My RV adapter
class TimesAdapter(private var availableTimes: List<String>?, private val onTimeListener: OnTimeListener) :
RecyclerView.Adapter<TimesAdapter.TimeViewHolder>() {
private var itemIndex = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TimeViewHolder {
val v = LayoutInflater.from(parent.context)
.inflate(R.layout.date_time_element, parent, false)
return TimeViewHolder(v, onTimeListener)
}
override fun getItemCount(): Int = availableTimes?.size!!
#SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: TimeViewHolder, position: Int) {
val currentDate: String? = availableTimes?.get(position) // i.e Sun 23/5
val parts = currentDate?.split(" ")
try {
val part1 = parts?.get(0)
holder.dateNameTV.text = part1
val part2 = parts?.get(1)
holder.dateNumTV.text = part2
} catch (e: IndexOutOfBoundsException) {
e.printStackTrace()
}
holder.itemLinearLayout.setOnClickListener {
itemIndex = position
notifyItemChanged(position)
}
val ctx = holder.itemLinearLayout.context
if (itemIndex == position) {
holder.itemLinearLayout.background = (loadDrawable(ctx, R.drawable.date_time_background_selected))
holder.dateNameTV.setTextColor(loadColor(ctx, android.R.color.white))
holder.dateNumTV.setTextColor(loadColor(ctx, android.R.color.white))
} else {
holder.itemLinearLayout.background = (loadDrawable(ctx, R.drawable.date_time_background))
holder.dateNameTV.setTextColor(loadColor(ctx, R.color.black_65))
holder.dateNumTV.setTextColor(loadColor(ctx, R.color.black_65))
}
}
class TimeViewHolder(itemView: View, onTimeListener: OnTimeListener) :
RecyclerView.ViewHolder(itemView), View.OnClickListener{
var dateNameTV: TextView = itemView.findViewById(R.id.dateNameTV)
var dateNumTV: TextView = itemView.findViewById(R.id.dateNumTV)
var itemLinearLayout: LinearLayout = itemView.findViewById(R.id.item_linear_layout)
private var onTimeListener: OnTimeListener? = null
init {
itemView.setOnClickListener(this)
this.onTimeListener = onTimeListener
}
override fun onClick(v: View?) {
onTimeListener?.onTimeClick(adapterPosition, itemView)
}
}
interface OnTimeListener{
fun onTimeClick(position: Int, itemView: View)
}
}
My fragment
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [DoctorAppointmentsFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class DoctorAppointmentsFragment : Fragment(),
DatesAdapter.OnDateListener, TimesAdapter.OnTimeListener {
private lateinit var datesRV: RecyclerView
private lateinit var timesRV: RecyclerView
private lateinit var linearLayoutManager: LinearLayoutManager
private lateinit var datesAdapter: DatesAdapter
private lateinit var timesAdapter: TimesAdapter
private lateinit var dateNameTV: TextView
private lateinit var dateNumTV: TextView
private lateinit var dateLinearLayout: LinearLayout
private var dates: List<String>? = null
private var times: List<String>? = null
private var isDateSelected = false
private var isTimeSelected = false
private var selectedDate: String? = null
private var selectedTime: String? = null
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_doctor_appointments, container, false)
datesRV = view.findViewById(R.id.datesRV)
datesRV.setHasFixedSize(true)
linearLayoutManager = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
linearLayoutManager.isAutoMeasureEnabled = false
datesRV.layoutManager = linearLayoutManager
timesRV = view.findViewById(R.id.timesRV)
timesRV.setHasFixedSize(true)
linearLayoutManager = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
linearLayoutManager.isAutoMeasureEnabled = false
timesRV.layoutManager = linearLayoutManager
val bookNowBT = view.findViewById<Button>(R.id.bookNowBT)
bookNowBT.setOnClickListener {
if (isDateSelected && isTimeSelected) {
val i = Intent(activity, ConfirmPaymentActivity::class.java)
i.putExtra(SELECTED_DATE, selectedDate)
i.putExtra(SELECTED_TIME, selectedTime)
startActivity(i)
}
}
getDoctorAvailableAppointments("7ab63fd2461bfb0008b72f5d8c0033fs", "basic")
return view
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment DoctorAppointmentsFragment.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
DoctorAppointmentsFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
private fun getDoctorAvailableAppointments(doctorID: String, type: String) {
setProgressDialog(this.requireActivity())
if (!InternetConnection.isInternetAvailable(this.requireActivity())) {
alertError(this.requireActivity(),
R.string.no_internet_connection,
R.string.check_internet_connection)
} else {
showProgressDialog()
val builder = ServiceBuilder()
val appointments = builder.getDoctorAvailableReservations()
val call = appointments.getDoctorAvailableReservations(
RequestAvailableReservations(doctorID,type))
call?.enqueue(object : Callback<ResponseAvailableReservations?> {
override fun onResponse(call: Call<ResponseAvailableReservations?>, response: Response<ResponseAvailableReservations?>) {
dismissProgressDialog()
if (!response.isSuccessful) {
alertError(requireActivity(),
R.string.code_not_200,
R.string.try_later)
return
}
val body: ResponseAvailableReservations? = response.body()
if (body == null) {
alertError(requireActivity(),
R.string.null_body,
R.string.try_later)
return
}
val status = body.status
val message = body.message
val data = body.data
if (status == null || message == null || data == null) {
alertError(requireActivity(),
R.string.null_body,
R.string.try_later)
return
}
if (status == "error") {
alertError(requireActivity(), R.string.error, message)
} else if (status == "success") {
dates = data.availableDatesList
datesAdapter = DatesAdapter(dates, this#DoctorAppointmentsFragment)
datesRV.adapter = datesAdapter
times = data.availableTimesList
timesAdapter = TimesAdapter(times, this#DoctorAppointmentsFragment)
timesRV.adapter = timesAdapter
}
}
override fun onFailure(call: Call<ResponseAvailableReservations?>, t: Throwable) {
t.printStackTrace()
dismissProgressDialog()
alertError(requireActivity(),
R.string.fail,
R.string.login_fail)
}
})
}
}
private var dateIndex = -1
override fun onDateClick(position: Int) {
selectedDate = dates?.get(position)
isDateSelected = true
Log.e("selectedDate", "selectedDate")
dateIndex = position
datesAdapter.notifyDataSetChanged()
}
private var timeIndex = -1
override fun onTimeClick(position: Int, itemView: View) {
// selectedTime = times?.get(position)
// isTimeSelected = true
// Log.e("isSelectedTime", "true")
// timeIndex = position
// timesAdapter.notifyItemChanged(position)
// Log.e("timeIndex", timeIndex.toString())
//
// val ctx = itemView.context
// if (timeIndex == position) {
// Log.e("timeIndex", "timeIndex == position")
//
// itemView.background = loadDrawable(ctx, R.drawable.date_time_background_selected)
// itemView.dateNameTV?.setTextColor(loadColor(ctx, android.R.color.white))
// itemView.dateNumTV?.setTextColor(loadColor(ctx, android.R.color.white))
// } else {
// itemView.background = (loadDrawable(ctx, R.drawable.date_time_background))
// itemView.dateNameTV.setTextColor(loadColor(ctx, R.color.black_65))
// itemView.dateNumTV.setTextColor(loadColor(ctx, R.color.black_65))
// }
}
}
Solved
For anyone interested i ended up using a very simple idea. Instead of accessing the RecyclerView selected element from outside the adapter, i did all i wanted to do inside the adapter and used 4 static variables in the Fragment. 2 booleans to check
if date and time are selected or not and 2 Strings having the date and time actually selected.
Inside the Fragment:
companion object {
#JvmStatic var isTimeSelected = false
#JvmStatic var selectedTime = ""
#JvmStatic var isDateSelected = false
#JvmStatic var selectedDate = ""
....
}
Inside the Adapter's onBindViewHolder()
holder.itemLinearLayout.setOnClickListener {
selectedDate = dates?.get(position)!!
isDateSelected = true
listener?.onDateClick(position)
selectedIndex = position
notifyDataSetChanged()
}
val ctx = holder.itemLinearLayout.context
if (selectedIndex == position) {
holder.itemLinearLayout.background = (loadDrawable(ctx, R.drawable.date_time_background_selected))
holder.dateNameTV.setTextColor(loadColor(ctx, android.R.color.white))
holder.dateNumTV.setTextColor(loadColor(ctx, android.R.color.white))
} else {
holder.itemLinearLayout.background = (loadDrawable(ctx, R.drawable.date_time_background))
holder.dateNameTV.setTextColor(loadColor(ctx, R.color.black_65))
holder.dateNumTV.setTextColor(loadColor(ctx, R.color.black_65))
}
And i made sure static variables don't have old values using this
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
isTimeSelected = false
selectedTime = ""
isDateSelected = false
selectedDate = ""
}
I know it's bad practice to put onClickListener inside onBindViewHolder but i don't konw if the static variables thing is good or bad practice. Either way it's working fine for now.
There is many ways to do this, And I recommend the first one.
Using shared ViewModels for communication between fragments in the same activity. The idea is that you will tie up the ViewModel with activity and every fragment can access this ViewModel and in this ViewModel you will have a LiveData object that holds the data and observing it from both fragments and every change in the value of LiveData will affect each fragment. Shared ViewModel
Using interfaces for communication between fragments and it's a hard thing to do these days. Basic communication between fragments
Using EventBus it's easy but not recommended while you can use ViewModel at the first solution. EventBus
Try this
TimesAdapter
class TimesAdapter(
availableTimes: List<String>
) : RecyclerView.Adapter<TimesAdapter.TimeViewHolder>() {
var availableTimes:List<String> = availableTimes
set(value) {
field = value
notifyDataSetChanged()
}
var listener:TimeSelectedListener?=null
var selectedIndex:Int = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TimeViewHolder {
return TimeViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.date_time_element, parent, false)
)
}
override fun getItemCount(): Int = availableTimes.count()
override fun onBindViewHolder(holder: TimeViewHolder, position: Int) {
val currentDate: String? = availableTimes[position] // i.e Sun 23/5
val parts = currentDate?.split(" ")
try {
val part1 = parts?.get(0)
val part2 = parts?.get(1)
holder.dateNameTV.text = part2
holder.dateNumTV.text = part1
} catch (e: IndexOutOfBoundsException) {
e.printStackTrace()
}
holder.itemLinearLayout.setOnClickListener {
listener?.onTimeClick(position)
selectedIndex = position
}
if (selectedIndex == position) {
// Selection Code
} else {
// De selection code
}
}
class TimeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var dateNameTV: TextView = itemView.findViewById(R.id.dateNameTV)
var dateNumTV: TextView = itemView.findViewById(R.id.dateNumTV)
var itemLinearLayout: LinearLayout = itemView.findViewById(R.id.item_linear_layout)
}
interface TimeSelectedListener {
fun onTimeClick(position: Int)
}
}
Usage from fragment
times = data.availableTimesList
timesAdapter = TimesAdapter(times).apply {
listener = object :TimesAdapter.TimeSelectedListener{
override fun onTimeClick(position: Int) {
// TODO here is where you should implement when an item is selected
}
}
}
timesRV.adapter = timesAdapter

how to put this arraylist in this method?

how to put this ArrayList in this method?
Could someone tell me how to pass this ArrayList in this method?
I added all the fragment code could anyone guide me?
I tried in several ways to pass this ArrayList but without success always remains blank the fragment
thanks
Array List
<string-array name="object_types">
method
private var issues: ArrayList<Issue> = ArrayList()
private fun getIssues() {
val stream = resources.openRawResource(R.raw.markers)
val inputString = stream.bufferedReader().use {
it.readText()
}
val klaxon = Klaxon()
JsonReader(StringReader(inputString)).use { reader -> // requires kotlin > 1.2 !!
reader.beginArray {
while (reader.hasNext()) { // requires "[]" array and not {"something": []}
val issue = klaxon.parse<Issue>(reader)
this.issues!!.add(issue!!)
} }
}
this.issues = Utils.markers
}
GalleryFragment
all fragment code follows below
class GalleryFragment : Fragment(), IssueItemOnClickListener {
private var productsRecyclerView: RecyclerView? = null
private var recyclerAdapter: IssueRecyclerViewAdapter? = null
private var recyclerLayoutManager: RecyclerView.LayoutManager? = null
private var issues: ArrayList<Issue> = ArrayList()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_gallery, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
getIssues()
this.productsRecyclerView = view.findViewById(R.id.issue_list_recycler_view) as RecyclerView
this.productsRecyclerView!!.setHasFixedSize(true)
// use a grid layout manager -> 2 columns
this.recyclerLayoutManager = GridLayoutManager(context, 2) as RecyclerView.LayoutManager?
this.productsRecyclerView!!.layoutManager = this.recyclerLayoutManager
this.recyclerAdapter = IssueRecyclerViewAdapter(this.issues, this)
this.productsRecyclerView!!.adapter = recyclerAdapter
}
override fun onIssueItemClick(pos: Int, issue: Issue) {
val args = Bundle()
val detailsFragment = IssueDetailsFragment()
args.putDouble("lat", issue.lat)
args.putDouble("lng", issue.lng)
args.putString("description", issue.description)
args.putString("name", issue.name)
args.putString("type", issue.type)
args.putString("imgUrl", issue.imgUrl)
detailsFragment.arguments = args
val ft = activity!!.supportFragmentManager.beginTransaction()
ft.replace(R.id.main_fragment_content, detailsFragment)
.setTransition(android.app.FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.addToBackStack(null).commit()
}
private fun getIssues() {
val stream = resources.openRawResource(R.raw.markers)
val inputString = stream.bufferedReader().use {
it.readText()
}
val klaxon = Klaxon()
JsonReader(StringReader(inputString)).use { reader -> // requires kotlin > 1.2 !!
reader.beginArray {
while (reader.hasNext()) { // requires "[]" array and not {"something": []}
val issue = klaxon.parse<Issue>(reader)
this.issues!!.add(issue!!)
}
}
}
this.issues = Utils.markers
}
}
[SOLVED]
CHANGE
private var issues: ArrayList<Issue> = ArrayList()
TO
private var object_values: ArrayList<Issue> = ArrayList()