I made a spinner with a drop-down menu and wanted to make a multiple-choice list. I used the following command but only one item is selected. I am new to this and am working on a uni project.
val dropdown = findViewById<Spinner>(R.id.selectRepeat)
val selectDays =
arrayOf(
"Only Once",
"Everyday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
) // Creating an array list
// set array in adapter
val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_multiple_choice, selectDays)
dropdown.adapter = adapter
dropdown.onItemSelectedListener =
object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(p0: AdapterView<*>?) {
TODO("Not yet implemented")
}
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
Toast.makeText(this#SetAlarm, "You have Selected " + selectDays[p2], Toast.LENGTH_LONG)
.show()
}
}
Related
Fragment Recyclerview code :
private fun initRecyclerView() {
bestSellersAdapter = BestSellerProductsAdapter(frag)
homeBinding.popularproductsRView.apply {
bestSellersAdapter.second(this#HomeFragment)
adapter = bestSellersAdapter
}
}
private fun getSection() {
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
roomProductVM.productFlow.collectLatest {
if (it.isEmpty()) {
categoryViewModel.getAllCategories()
} else {
bestSellersAdapter.setMutableArraylist(it)
bestSellersAdapter.notifyDataSetChanged()
}
}
}
}
based on condition i call this function(getSection) in onViewCreated
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRecyclerView()
getSection()
addcartviewModel.cartTableSuccessorNot.observe(viewLifecycleOwner) {
if(it.toInt() == variant_id) {
Toast.makeText(context,"Product Updated Successfully",Toast.LENGTH_SHORT).show() homeBinding.popularproductsRView.adapter?.notifyItemChanged(productPosition)
} else {
LoadingUtils.hideDialog()
Toast.makeText(context,"Failure in Cart Table", Toast.LENGTH_SHORT).show()
}
}
}
interface function in fragment : ( here i am taking product position from adapter )
override fun updatepro(position: Int, type: String, id: Int, cart_count: Int, is_notify: Boolean, product_id: Int, name: String, measurement: String,
variant_image: String, price: String, qty: String, stock: String, image: String, moq: String, unit: String) {
productPosition = position
variant_id = id
variant_qty = qty.toInt()
addcartviewModel.updateVariantTableinRoom(id,cart_count.toString(),is_notify,product_id)
addcartviewModel.insertVariantListintoCartTable(id,measurement,price,stock,image,moq,name,variant_image,unit,qty)
}
Adapter class :
class BestSellerProductsAdapter(var context: Context) : RecyclerView.Adapter<BestSellerProductsAdapter.BestSellerViewHolder>() {
var mutableList = mutableListOf<ProductWithVariants>()
fun setMutableArraylist(datas: MutableList<ProductWithVariants>) {
mutableList.clear()
mutableList.addAll(datas)
}
override fun onBindViewHolder(holder: BestSellerViewHolder, position: Int) {
var cart_count = mutableList[position].variantsList[0].cart_count
if(stock?.toInt()==0) {
holder.notify.visibility = View.VISIBLE
holder.addtocart.visibility = View.GONE
holder.pll_cart.visibility = View.GONE
} else if(cart_count == 0) {
holder.addtocart.visibility = View.VISIBLE
holder.pll_cart.visibility = View.GONE
holder.notify.visibility = View.GONE
} else {
holder.notify.visibility = View.GONE
holder.addtocart.visibility = View.GONE
holder.pll_cart.visibility = View.VISIBLE
holder.tv_cart.text = cart_count.toString()
}
holder.addtocart.setOnClickListener {
cart_count = ((cart_count ?: 0) + 1)
selectpro?.updatepro(position,"AddCart",mutableList[position].variantsList[0].id,mutableList[position].variantsList[0].cart_count!!.toInt(),false,mutableList[position].products.id,
mutableList[position].products.name.toString(),
mutableList[position].variantsList[0].measurement.toString() + mutableList[position].variantsList[0].measurement_unit_name.toString(),
mutableList[position].variantsList[0].image.toString(),
mutableList[position].variantsList[0].discounted_price.toString(),
cart_count.toString(),
stock.toString(),
mutableList[position].variantsList[0].image.toString(),
moq.toString(),
mutableList[position].variantsList[0].measurement_unit_name.toString()
)
}
var selectpro: selectproduct?=null
fun second(selectproduct: selectproduct) {
selectpro = selectproduct
}
interface selectproduct {
fun updatepro(position:Int,type:String,id:Int, cart_count:Int,is_notify:Boolean,product_id:Int,
name:String,measurement:String,variant_image:String,price:String,qty:String,
stock:String,image:String,moq:String,unit:String)
fun selectProduct(product: ProductWithVariants,position:Int)
}
Now i want to update the particular item of recycler view after Toast ( Product Updated Successfully ) in fragment .. how to do that
1 After response first find out the item position you want to update
in adapter
2 Also you have to update the list in adapter with new list of data
you get from the response.
then use below code to update particular item in adapter using
position.
adapter.notifyItemChanged(position)
On Login page and when pressing register, it takes you to register, but when clicking on register button on register page, it adds user to database regardless if info is provided or not and then takes you back to login page, where you are able to log in regardless if email and password is even entered. I want the validation to happen before the execution. I think it executes the validation process, but still continues to insert data (even if its blank) into the database.
import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import java.util.regex.Pattern
class MainActivity : AppCompatActivity() {
#SuppressLint("Recycle")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var emailValid = false
var usernameValid = false
var passwordValid = false
fun updateState() {
val allValid = emailValid && usernameValid && passwordValid
// enable the button if everything's cool - disable it if not!
// we're always setting the enabled state to match the current validation state,
// so it's always up to date and consistent
btn_register_reg.isEnabled = allValid
}
reg_username.addTextChangedListener(object :TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
// set the validation state for this field
usernameValid = usernameValidate(reg_username.text.toString())
// set/clear this field's error state as necessary
reg_username.error = if (usernameValid) null else "Please Enter Valid Username"
// since something has potentially changed, call the general update function
// so the global state can be checked and updated if necessary
updateState()
}
})
reg_email.addTextChangedListener(object :TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
// set the validation state for this field
emailValid = emailValidate(reg_email.text.toString())
// set/clear this field's error state as necessary
reg_email.error = if (emailValid) null else "Please Enter Valid Email Address"
// since something has potentially changed, call the general update function
// so the global state can be checked and updated if necessary
updateState()
}
})
reg_password.addTextChangedListener(object :TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
// set the validation state for this field
passwordValid = passwordValidate(reg_password.text.toString())
// set/clear this field's error state as necessary
reg_password.error = if (passwordValid) null else "Please Enter Valid Password"
// since something has potentially changed, call the general update function
// so the global state can be checked and updated if necessary
updateState()
}
})
reg_confirm_password.addTextChangedListener(object:TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
// set the validation state for this field
if(confirmValidate())
btn_register_reg.isEnabled = true
else {
btn_register_reg.isEnabled = false
reg_confirm_password.error = "Please Enter Valid Password"
}
}
})
//Connecting to our database
if(btn_register_reg.isEnabled){
//Connects my dbHelper from our database
val helper = MyDBHelper(applicationContext)
//Setting db variable to represent our database
val db = helper.readableDatabase
//Variable indicating execution of the query below
db.rawQuery("SELECT * FROM login_register", null)
btn_register_reg.setOnClickListener {
if(reg_username.text.toString() == "") {
reg_username.error = "Stop"
btn_register_reg.isEnabled = false
} else {
btn_register_reg.isEnabled = true
}
if(reg_email.text.toString() == "") {
reg_email.error = "Stop"
btn_register_reg.isEnabled = false
} else {
btn_register_reg.isEnabled = true
}
if(reg_password.text.toString() == "") {
reg_password.error = "Stop"
btn_register_reg.isEnabled = false
} else {
btn_register_reg.isEnabled = true
}
//Used to store our set of values
val cv = ContentValues()
cv.put("Username",reg_username.text.toString())
cv.put("Email",reg_email.text.toString())
cv.put("Password",reg_password.text.toString())
db.insert("login_register", null, cv)
reg_username.setText("")
reg_email.setText("")
reg_password.setText("")
reg_username.requestFocus()
Toast.makeText(applicationContext, "Added",Toast.LENGTH_SHORT).show()
val intent = Intent(this, MainActivity2::class.java)
startActivity(intent)
}
}
else{
Toast.makeText(applicationContext, "Invalid",Toast.LENGTH_SHORT).show()
}
}
private fun confirmValidate(): Boolean {
//Checks if the user's confirm password entry matches their password input
return if(reg_password.text.toString() == reg_confirm_password.text.toString()){
true
} else {
//When the confirm password field does not match the password field an error message is displayed
reg_confirm_password.error = "Password Does Not Match"
false
}
}
private fun passwordValidate(text: String?): Boolean {
//Pattern to be followed by the password input, it has to start with a capital letter,with a minimum length of 5 and maximum of 20, and has to end with number followed by special character
val p = Pattern.compile("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!#$%^&*-]).{5,20}$")
//Checks if user input matches pattern type
val m = p.matcher(text.toString())
//User input allowed when it matches pattern type
return m.matches()
}
private fun emailValidate(text: String?): Boolean {
//Pattern to be followed by the email input, it has to have the # symbol as well as a . domain
val p = Pattern.compile("[a-zA-Z0-9._-]+#[a-z]+\\.+[a-z]+")
//Checks if user input matches pattern type
val m = p.matcher(text.toString())
//User input allowed when it matches pattern type
return m.matches()
}
private fun usernameValidate(text: String?): Boolean {
//Pattern to be followed by the username input, it has to have at least 5 characters with a maximum of 30 allowed
val p = Pattern.compile("^(?=.{5,30}\$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+(?<![_.])\$")
//Checks if user input matches pattern type
val m = p.matcher(text.toString())
//User input allowed when it matches pattern type
return m.matches()
}
}
I have faced a problem which my spinner cannot show the item selected in the page. But for the selection of "All", it can show normally all item but when I click one of the selection in spinner, it will show nothing for me no matter the selection name is match with job name or not. Can some one help me?
override fun onResume() {
super.onResume()
val places=resources.getStringArray(R.array.place)
val arrayAdapter=ArrayAdapter(requireContext(),R.layout.dropdown_item,places)
val jobs=resources.getStringArray(R.array.job)
val arrayAdapter2=ArrayAdapter(requireContext(),R.layout.dropdown_item,jobs)
binding.spinnerPlace.setAdapter(arrayAdapter)
binding.spinnerJob.setAdapter(arrayAdapter2)
spinner_job.onItemSelectedListener=object : AdapterView.OnItemSelectedListener{
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
if (parent != null) {
if(parent.getItemAtPosition(position)=="All"){
tempArrayList.addAll(newArrayList)
val adapter=Search_Page_Adapter(requireContext(),tempArrayList)
newRecyclerView.adapter=adapter
newRecyclerView.layoutManager=LinearLayoutManager(requireContext())
}
else{
tempArrayList.clear()
val item=parent.getItemAtPosition(position).toString()
Toast.makeText(parent.context,"Selected:$item",Toast.LENGTH_SHORT).show()
if(item.isNotEmpty()){
newArrayList.forEach{
if(it.jobname?.lowercase(Locale.getDefault())!!.contains(item)){
tempArrayList.add(it)
}
val adapter=Search_Page_Adapter(requireContext(),tempArrayList)
newRecyclerView.adapter=adapter
newRecyclerView.layoutManager=LinearLayoutManager(requireContext())
}
}else{
tempArrayList.clear()
tempArrayList.addAll(newArrayList)
newRecyclerView.adapter!!.notifyDataSetChanged()
}
}
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
}
Try to change your onItemSelectedListener logic:
spinner_job.onItemSelectedListener=object : AdapterView.OnItemSelectedListener{
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
val item = parent.getItemAtPosition(position).toString()
if(item == "All") {
// `All` selected
tempArrayList.addAll(newArrayList)
val adapter=Search_Page_Adapter(requireContext(),tempArrayList)
newRecyclerView.adapter=adapter
newRecyclerView.layoutManager=LinearLayoutManager(requireContext())
}
else {
// Others selected
Toast.makeText(parent.context,"Selected:$item",Toast.LENGTH_SHORT).show()
if(item.isNotEmpty()){
newArrayList.forEach{
if(it.jobname?.lowercase(Locale.getDefault())!!.contains(item)){
tempArrayList.add(it)
}
val adapter=Search_Page_Adapter(requireContext(),tempArrayList)
newRecyclerView.adapter=adapter
newRecyclerView.layoutManager=LinearLayoutManager(requireContext())
}
} else {
tempArrayList.clear()
tempArrayList.addAll(newArrayList)
newRecyclerView.adapter!!.notifyDataSetChanged()
}
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
I migrated from paging 2 to paging 3. I tried to implement ItemKeyedDataSource of Paging 2 to Paging library 3. But the problem I was facing is, the same value(currentJodId) was passed as the nextkey in two sequential Pages loaded. And After that app crashes. but if I add "keyReuseSupported = true" in DataSource, app does not crash. But it started calling same item id as the nextkey.
JobSliderRestApi.kt
#GET("job/list/slides")
fun getDetailOfSelectedJob(
#Query("current_job") currentJodId: Int?,
#Query("limit") jobLimit: Int?,
#Query("search_in") fetchType: String?
): Single<Response<JobViewResponse>>
JobViewResponse.kt
data class JobViewResponse(
#SerializedName("data") val data: ArrayList<JobDetail>?
) : BaseResponse()
JobDetail.kt
data class JobDetail(
#SerializedName("job_id") val jobId: Int,
#SerializedName("tuition_type") val jobType: String?,
#SerializedName("class_image") val jobImage: String,
#SerializedName("salary") val salary: String,
#SerializedName("no_of_student") val noOfStudent: Int,
#SerializedName("student_gender") val studentGender: String,
#SerializedName("tutor_gender") val preferredTutor: String,
#SerializedName("days_per_week") val daysPerWeek: String?,
#SerializedName("other_req") val otherReq: String?,
#SerializedName("latitude") val latitude: Double?,
#SerializedName("longitude") val longitude: Double?,
#SerializedName("area") val area: String,
#SerializedName("tutoring_time") val tutoringTime: String?,
#SerializedName("posted_date") val postedDate: String?,
#SerializedName("subjects") val subjects: String,
#SerializedName("title") val title: String
)
JodSliderDataSource.kt
class JodSliderDataSource #Inject constructor(
private val jobSliderRestApi: JobSliderRestApi
): RxPagingSource<Int, JobDetail>() {
// override val keyReuseSupported = true
#ExperimentalPagingApi
override fun getRefreshKey(state: PagingState<Int, JobDetail>): Int? {
return state.anchorPosition?.let {
state.closestItemToPosition(it)?.jobId
}
}
override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, JobDetail>> {
return jobSliderRestApi.getDetailOfSelectedJob(42673, 2, "next").toSingle()
.subscribeOn(Schedulers.io())
.map { jobResponse -> toLoadResult(jobResponse.data) }
.onErrorReturn { LoadResult.Error(it) }
}
private fun toLoadResult(data: ArrayList<JobDetail>): LoadResult<Int, JobDetail> {
return LoadResult.Page(data = data, prevKey = null, nextKey = data.lastOrNull()?.jobId)
}
}
I was getting the same error and this is what worked for me. In the JodSliderDataSource class, toLoadResult method, set the nextKey parameter value by getting the page number from the response data and adding one.
private fun toLoadResult(
data: ArrayList<JobDetail>
): LoadResult<Int, JobDetail> {
return LoadResult.Page(
data = data,
prevKey = null,
nextKey = data.lastOrNull()?.jobId + 1 // Add one to the page number here.
)
}
How to search for data in RecyclerView?
I have model like this and I get data with retrofit. I have to make RecyclerView with model data like this and how to make Search from RecyclerView?
data class ListArticle(
#SerializedName("status") val status : String,
#SerializedName("totalResults") val totalResults : Int,
#SerializedName("articles") val articles : List<Articles>
)
data class Source (
#SerializedName("id") val id : String,
#SerializedName("name") val name : String
)
data class Articles (
#SerializedName("source") val source : Source,
#SerializedName("author") val author : String,
#SerializedName("title") val title : String,
#SerializedName("description") val description : String,
#SerializedName("url") val url : String,
#SerializedName("urlToImage") val urlToImage : String,
#SerializedName("publishedAt") val publishedAt : String,
#SerializedName("content") val content : String
)
Have to solve this question and I'm sorry for not completed question
just added this to your adapter
fun getFilter(): Filter? {
return articleFilter
}
private val articleFilter: Filter = object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults? {
val filteredList: MutableList<Articles> = ArrayList()
if (constraint == null || constraint.length == 0) {
filteredList.addAll(articles)
} else {
val filterPattern =
constraint.toString().toLowerCase().trim { it <= ' ' }
for (item in articles) {
if (item.title.toLowerCase().contains(filterPattern)) {
filteredList.add(item)
}
}
}
val results = FilterResults()
results.values = filteredList
return results
}
override fun publishResults(
constraint: CharSequence?,
results: FilterResults
) {
searchArticles = results.values as List<Articles>
notifyDataSetChanged()
}
}
fun setData(article: List<Articles>){
searchArticles = article
notifyDataSetChanged()
}