I am trying to display navigation bar title in my TestProjectList class activity but the value is empty so, I am not able to see the Navigation bar tile. I am not sure why its showing empty Value. Your help is appreciated.
Model Class:
class TestProject(val name: String,val location: String)
Main Class:
private class ItemDetailAdapter(val TestProjectList:Array<TestProject>): RecyclerView.Adapter<ItemDetailViewHolder>()
{
override fun onBindViewHolder(p0: ItemDetailViewHolder, p1: Int) {
val TestProject=TestProjectList.get(p1)
p0?.customView?.TestProjectName?.text=TestProject.name
val TestProjectPicture=p0?.customView?.itemPicture
Picasso.get().load(TestProject.location).into(TestProjectPicture)
}
override fun getItemCount(): Int {
return TestProjectList.size
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ItemDetailViewHolder {
val layoutInflater=LayoutInflater.from(p0?.context)
val customView=layoutInflater.inflate(R.layout.items_details,p0,false)
return ItemDetailViewHolder(customView)
}
}
class ItemDetailViewHolder(val customView:View,var Title: TestProject?=null):RecyclerView.ViewHolder(customView)
{
companion object {
val ITEM_TITLE_KEY="TestProject"
}
init {
customView.setOnClickListener {
val intent= Intent(customView.context,TestProjectMenuList::class.java)
intent.putExtra(ITEM_TITLE_KEY,Title?.name)
print("Printting Title :$Title?.name")
println("Hello Test $ITEM_TITLE_KEY")
customView.context.startActivity(intent)
println("Test")
}
}
TestProjectList Class:
val navBarTitle=intent.getStringExtra(MainClass.ItemDetailViewHolder.ITEM_TITLE_KEY)
supportActionBar?.title=navBarTitle
When you are creating your viewholder in the adapter return ItemDetailViewHolder(customView) you aren't passing any value for the parameter Title. You aren't setting it up latter either, but you are populating the intent with intent.putExtra(ITEM_TITLE_KEY,Title?.name). In this case the value you will always retrieve from the intent will be null.
Model Class:
class TestProject(val name: String,val location: String)
Main Class:
private class ItemDetailAdapter(val TestProjectList:Array<TestProject>): RecyclerView.Adapter<ItemDetailViewHolder>()
{
override fun onBindViewHolder(p0: ItemDetailViewHolder, p1: Int) {
val TestProject=TestProjectList.get(p1)
p0?.customView?.TestProjectName?.text=TestProject.name
val TestProjectPicture=p0?.customView?.itemPicture
Picasso.get().load(TestProject.location).into(TestProjectPicture)
//Below code solved the Title Problem
p0?.Title=TestProject
}
override fun getItemCount(): Int {
return TestProjectList.size
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ItemDetailViewHolder {
val layoutInflater=LayoutInflater.from(p0?.context)
val customView=layoutInflater.inflate(R.layout.items_details,p0,false)
return ItemDetailViewHolder(customView)
}
}
class ItemDetailViewHolder(val customView:View,var Title: TestProject?=null):RecyclerView.ViewHolder(customView)
{
companion object {
val ITEM_TITLE_KEY="TestProject"
}
init {
customView.setOnClickListener {
val intent= Intent(customView.context,TestProjectMenuList::class.java)
intent.putExtra(ITEM_TITLE_KEY,Title?.name)
print("Printting Title :$Title?.name")
println("Hello Test $ITEM_TITLE_KEY")
customView.context.startActivity(intent)
println("Test")
}
}
TestProjectList Class:
val navBarTitle=intent.getStringExtra(MainClass.ItemDetailViewHolder.ITEM_TITLE_KEY)
supportActionBar?.title=navBarTitle
Related
I'm trying to have item removed from my list but I get following error
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public inline fun <T> MutableCollection<out TypeVariable(T)>.remove(element: TypeVariable(T)): Boolean defined in kotlin.collections
public inline fun <T> MutableList<TypeVariable(T)>.remove(index: Int): TypeVariable(T) defined in kotlin.collections
public inline fun <K, V> MutableMap<out TypeVariable(K), TypeVariable(V)>.remove(key: TypeVariable(K)): TypeVariable(V)? defined in kotlin.collections
Code
class EducationsAdapter(val context: Context?, private var educationList: MyEducations) : RecyclerView.Adapter<EducationsAdapter.EducationsAdapterViewHolder>() {
override fun getItemCount()= educationList.data.size
// other functions...
override fun onBindViewHolder(holder: EducationsAdapter.EducationsAdapterViewHolder, position: Int)
{
holder.educationDelete.setOnClickListener {
deleteMyEducations(currentItem.id, position)
}
}
//delete
private fun deleteMyEducations(id: String, position: Int) {
// ".remove" is returning error above
educationList.remove(position)
notifyDataSetChanged()
}
}
Any suggestions?
Update
My MyEducations class (rendering data coming from server)
data class MyEducations(
val data: List<Education>,
val message: String
) { }
data class Education(
val id: String,
val start: String,
val end: String,
val title: String,
val body: String,
val user: User,
val created_at: String,
val updated_at: String,
) {}
Update 2
I've made following changes
// add
val list = mutableListOf<MyEducations>()
private fun deleteMyEducations(id: String, position: Int) {
//changed to
list.remove(educationList.data[position])
notifyDataSetChanged()
}
What it does is make flashing remove of the item (meaning: for less than a second my item removes and back again to the list)!
Solved
//changed my list to `ArrayList<Education>`
class EducationsAdapter(val context: Context?, private var educationList: ArrayList<Education>) : RecyclerView.Adapter<EducationsAdapter.EducationsAdapterViewHolder>() {
// and my delete code to
private fun deleteMyEducations(id: String, position: Int) {
educationList.removeAt(position)
notifyItemRemoved(position)
notifyItemRangeChanged(position, educationList.size)
notifyDataSetChanged()
}
}
Also I had to change my class to ArrayList as well
data class MyEducations(
val data: ArrayList<Education>,
val message: String
) { }
Try With
val list = mutableListOf<MyEducations>()
private fun deleteMyEducations(id: String, position: Int) {
list.removeAt(position)
notifyDataSetChanged()
}
You should be able to delete with something like:
class EducationListAdapter: RecyclerView.Adapter<EducationListAdapter.EducationViewHolder>() {
var educationList: MutableList<Education> = mutableListOf()
override fun onBindViewHolder(holder: EducationViewHolder, position: Int) {
val current = educationList.toList()
holder.view.setOnClickListener {
educationList.remove(current[position])
notifyItemRemoved(position)
}
}
}
In my App, Activity.kt With attached with Adapter.kt and I'm work using RecyclerView in kotlin. In that Adapter.kt in the adapter member onBindViewHolder data parce in AnotherActivity.kt code. But, here problem is that there are no connection between two Activities (Activity.kt and AnotherActivity.kt). So, My problem is that how to the parce data between two activity without using Intent???
Title: Adapter.kt
class ChatAdapter (val chatList: ArrayList<ChatMessage>) : RecyclerView.Adapter<ChatAdapter.ViewHolder>() {
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ChatAdapter.ViewHolder {
val v = LayoutInflater.from(p0.context).inflate(R.layout.chat_sort, p0, false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return chatList.size
}
override fun onBindViewHolder(p0: ChatAdapter.ViewHolder, p1: Int) {
val chat: ChatMessage = chatList[p1]
p0.msg.text = chat.msgText /// Problem with this data is send in AnotherActivity.kt code
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val msg = itemView.findViewById(R.id.tv_msg_from_user) as TextView
}
There are not gone or start or launch AnotherActivity.kt . Only transfer data in the Adapter.kt. to AnotherActivity.kt
You could create a application class having a getInfo() function in companion object function.
class MyApp : Application() {
companion object {
var info: String? = null
fun getInfo(): String {
return info
}
fun setInfo(info1: String) {
info = info1
}
}
}
You can simply get it using MyApp.getInfo()
If I click from Activity 1--2 then I am able to see the Title bar but If I click back from 2--1 then the Title bar value is empty. I tried onBackPressed method but still its not helpful. I tried shared preference and local file storage but Its not helpful.
Model Class:
class TestProject(val name: String,val location: String)
Main Class:
private class ItemDetailAdapter(val TestProjectList:Array<TestProject>): RecyclerView.Adapter<ItemDetailViewHolder>()
{
override fun onBindViewHolder(p0: ItemDetailViewHolder, p1: Int) {
val TestProject=TestProjectList.get(p1)
p0?.customView?.TestProjectName?.text=TestProject.name
val TestProjectPicture=p0?.customView?.itemPicture
Picasso.get().load(TestProject.location).into(TestProjectPicture)
//Below code solved the Title Problem
p0?.Title=TestProject
}
override fun getItemCount(): Int {
return TestProjectList.size
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ItemDetailViewHolder {
val layoutInflater=LayoutInflater.from(p0?.context)
val customView=layoutInflater.inflate(R.layout.items_details,p0,false)
return ItemDetailViewHolder(customView)
}
}
class ItemDetailViewHolder(val customView:View,var Title: TestProject?=null):RecyclerView.ViewHolder(customView)
{
companion object {
val ITEM_TITLE_KEY="TestProject"
}
init {
customView.setOnClickListener {
val intent= Intent(customView.context,TestProjectMenuList::class.java)
intent.putExtra(ITEM_TITLE_KEY,Title?.name)
print("Printting Title :$Title?.name")
println("Hello Test $ITEM_TITLE_KEY")
customView.context.startActivity(intent)
println("Test")
}
}
TestProjectList Class:
val navBarTitle=intent.getStringExtra(MainClass.ItemDetailViewHolder.ITEM_TITLE_KEY)
supportActionBar?.title=navBarTitle
If you're sure that
val navBarTitle=intent.getStringExtra(MainClass.ItemDetailViewHolder.ITEM_TITLE_KEY)
...has a value, you can put
val navBarTitle=intent.getStringExtra(MainClass.ItemDetailViewHolder.ITEM_TITLE_KEY)
supportActionBar?.title=navBarTitle
inside the onResume function.
I am trying to retrieve the variable value in my main class so, I can load this value into my database. I am not sure how to retrieve onBindViewHolder value in MainClas. I am able to display the item in the activity.
Complete Code requested by user.
class TestProjectMenuDetail() : AppCompatActivity() {
var itemName=""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView_main.setBackgroundColor(Color.WHITE)
recyclerView_main.layoutManager= LinearLayoutManager(this)
supportActionBar?.title=navBarTitle
fetchJSON()
}
//Retrieve value from OnBindViewHolder
fun setVariable(ItemName:String)
{
itemName=ItemName
}
}
private class MenuDetailListAdapter(val TestProjectMenudetails:Array<TestProjectMenuDetails>,context: Context): RecyclerView.Adapter<TestProjectDetailMenuViewHolder>()
{
private val TestVar:TestMenuDetail= context as TestMenuDetail
override fun onBindViewHolder(p0: TestProjectDetailMenuViewHolder, p1: Int) {
val TestProjectmenudetail=TestProjectMenudetails.get(p1)
p0?.customView?.itemname.text=TestProjectmenudetail.menu
TestVar.setVariable(TestProjectmenudetail.menu)
}
override fun getItemCount(): Int {
return TestProjectMenudetails.size
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): TestProjectDetailMenuViewHolder {
val layoutInflater= LayoutInflater.from(p0?.context)
val customView=layoutInflater.inflate(R.layout.activity_TestProject_menu_detail,p0,false)
return TestProjectDetailMenuViewHolder(customView)
}
}
#Suppress("DEPRECATION")
class TestProjectDetailMenuViewHolder(val customView: View, var Menus:TestProjectMenu?=null): RecyclerView.ViewHolder(customView)
{
companion object {
val DISHES_TITLE_NAME="ITEM_NAME"
val intialcount:Int=0
}
init {
customView.setOnClickListener {
}
}
fun AddClick()
{
val intent=Intent(customView.context,TestProjectMenuList::class.java)
customView.context.startActivity(intent)
}
}
In MainClas declare a variable to hold the value you want to pass from onBindViewHolder like activityVar and then create a method:
fun setVariable(myVariable: Int) {
activityVar = myVariable
}
replace Int with the proper data type.
Change your adapter class's header like this:
private class TestDetailListAdapter(context: Context, val ItemTestdetails:Array<ItemTestDetails>)
so you need to pass to it first the context of your activity by passing this
and inside onBindViewHolder add this:
val mainclas: MainClas = context as MainClas
mainclas.setVariable(variablename)
replace variablename with the name of the variable you want to pass
I want to fetch some json data, see in the image the green arrow:
The problem is that Android Studio doesn't let me get the data I want. It stops until a step before (I think). In my adapter class check:
holder?.view?.textWeather?.text = weatherFor.weather.toString()
Also it shows me in the emulator the red arrow, what is this?
Below is my main Activity's json method with the classes i want to fetch data for, and the associated Adapter class.
Main Activity
fun fetchJson() {
val url="https://api.openweathermap.org/data/2.5/forecast?q=Prague,CZ&appid=4cf7f6610d941a1ca7583f50e7e41ba3"
val request=Request.Builder().url(url).build()
val client= OkHttpClient()
client.newCall(request).enqueue(object :Callback {
override fun onResponse(call: Call?, response: Response?) {
val body=response?.body()?.string()
println(body)
val gson=GsonBuilder().create()
val forecastfeed=gson.fromJson(body,ForecastFeed::class.java)
runOnUiThread{
recyclerView_main.adapter=MainAdapter(forecastfeed)
}
}
override fun onFailure(call: Call?, e: IOException?) {
println("Failed to execute request")
}
})
}
class ForecastFeed(val list:List<ForecastWeatherList>) { }
class ForecastWeatherList(val weather:List<WeatherData>) { }
class WeatherData(val main:String,val icon:String) { }
Adapter
class MainAdapter(val forecastfeed: ForecastFeed): RecyclerView.Adapter<CustomViewHolder>() {
val forecastWeather = listOf<String>("First","Second")
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val weatherFor = forecastfeed.list.get(position)
holder?.view?.textWeather?.text = weatherFor.weather.toString()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder{
//how do we even create a view
val layoutInflater =LayoutInflater.from(parent?.context)
val cellForRow=layoutInflater.inflate(R.layout.weather_row,parent,false)
return CustomViewHolder(cellForRow)
}
override fun getItemCount(): Int {
return forecastfeed.list.count()
}
}
class CustomViewHolder(val view: View):RecyclerView.ViewHolder(view) { }
You can format the data manually
holder?.view?.textWeather?.text = "weather ${weatherFor.weather.map{it.main}.joinToString(", ")}"
or use data classes
You need to overwrite WeatherData.toString() to have a hand on what's displayed.
class WeatherData(val main:String,val icon:String) {
override fun toString(): String {
return "$main $icon"
}
}
Further more you should use a RecyclerView with a ViewHolder to handle properties one-by-one and enable more complex layouts. If needed.