view not created for fragment of viewpager inside recyclerview - kotlin

I want to make Home screen like Instagram where video will play/pause on horizontal and vertical scrolling.
For that I am using fragment inside viewpager and viewpager inside recyclerview for achieving horizontal and vertical scrolling.
Issue is that for second item of recyclerview view of fragment is not created.
can anyone help me to achieve this functionality.
Thanks in advance.
Below is the adapter class of recyclerview.
class DashboardFeedsAdapterNew(
private val mContext: Context, var mList: ArrayList<PostListModel.PostListData>,
private val viewHolderClicks: ViewHolderClicks,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var mInflater: LayoutInflater =
mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE) as LayoutInflater
var mActivePage = 0
private var isLoadingAdded = false
val LOADING_TYPE = 0
val POST_TYPE = 1
val STORY_TYPE = 2
fun getList(): ArrayList<PostListModel.PostListData> {
return mList
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RecyclerView.ViewHolder {
when (viewType) {
POST_TYPE -> {
val v = LayoutInflater.from(parent.context)
.inflate(R.layout.raw_feed, parent, false)
return PostViewHolder(v)
}
}
val v =
mInflater.inflate(R.layout.raw_feed, parent, false)
return PostViewHolder(
v
)
}
override fun getItemViewType(position: Int): Int {
if(position == mList.size -1 && isLoadingAdded) {
return LOADING_TYPE
} else {
/*if ((position + 1) % 5 == 0) {
return STORY_TYPE
}*/
return POST_TYPE
}
}
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder,
position: Int
) {
val model = mList[holder.adapterPosition]
if (holder is PostViewHolder) {
//post type
try {
if (model.files.isNotEmpty()) {
setupViewpager(holder, model)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
private fun setupViewpager(binding: PostViewHolder, model: PostListModel.PostListData) {
binding.vpAttachment.adapter = ViewPagerAdapter((activityContext() as AppCompatActivity).supportFragmentManager,model)
binding.vpAttachment.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {
mActivePage = binding.vpAttachment.currentItem
}
override fun onPageSelected(position: Int) {
}
override fun onPageScrollStateChanged(state: Int) {}
})
}
inner class ViewPagerAdapter(fm: FragmentManager, val mData: PostListModel.PostListData) :
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT ) { //FragmentPagerAdapter
private val mFragmentList = java.util.ArrayList<Fragment>()
private val mFragmentTitleList = java.util.ArrayList<String>()
fun addFragment(fragment: Fragment, title: String) {
mFragmentList.add(fragment)
mFragmentTitleList.add(title)
}
//added this metod to update fragment after edit post
override fun getItemPosition(`object`: Any): Int {
return POSITION_NONE
}
override fun getItem(position: Int): Fragment {
mData.files[position].position = position
return PostMediaPreviewPageFragment.newInstance(position,mData.id, mData.files[position])
}
override fun getCount(): Int {
return mData.files.size
}
override fun getPageTitle(position: Int): CharSequence? {
return mFragmentTitleList[position]
}
}
private fun activityContext(): Context {
val context = mContext
return context
}
override fun getItemCount(): Int {
return mList.size
}
inner class ViewMoreViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val progressBar: ProgressBar = itemView.findViewById(R.id.progressBar)
}
inner class PostViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val imgAvatar: ImageView = itemView.findViewById(R.id.imgAvatar)
val tvUserName: TextView = itemView.findViewById(R.id.tvUserName)
val vpAttachment: ViewPager = itemView.findViewById(R.id.vpAttachment)
// val indicator: IndicatorView = itemView.findViewById(R.id.indicator)
val imgFeed: ImageView = itemView.findViewById(R.id.imgFeed)
val imgPlay: ImageView = itemView.findViewById(R.id.imgPlay)
val tvAttachmentCount: TextView = itemView.findViewById(R.id.tvAttachmentCount)
val tvFeedTitle: TextView = itemView.findViewById(R.id.tvFeedTitle)
val tvLocation: TextView = itemView.findViewById(R.id.tvLocation)
val tvViewCount: TextView = itemView.findViewById(R.id.tvViewCount)
val imgLike: ImageView = itemView.findViewById(R.id.imgLike)
val tvLikeCount: TextView = itemView.findViewById(R.id.tvLikeCount)
val lnComment: LinearLayout = itemView.findViewById(R.id.lnComment)
val tvCommentCount: TextView = itemView.findViewById(R.id.tvCommentCount)
val btnTakeAction: Button = itemView.findViewById(R.id.btnTakeAction)
}
inner class StoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val rvStory: RecyclerView = itemView.findViewById(R.id.rvStory)
val viewPager: ViewPager2 = itemView.findViewById(R.id.vpStory)
val indicator: CircleIndicator2 = itemView.findViewById(R.id.indicator)
}
interface ViewHolderClicks {
fun onUserClick(model: PostListModel.PostListData, position: Int)
fun onImageClick(model: PostListModel.PostListData, position: Int)
fun onLikeClick(model: PostListModel.PostListData, position: Int)
fun onLikeCountClick(model: PostListModel.PostListData, position: Int)
fun onCommentClick(model: PostListModel.PostListData, position: Int)
fun onTakeActionClick(model: PostListModel.PostListData, position: Int)
}
}

Related

how do i update items that change in recyclerview use diffutil?

DiffUtil do not update items recyclerview with the same id and not same the content,
The model has [id : Int and title : String]. I want to the diffUtilCallBack check items with the same id and not same title and update to recyclerview
Please help me fix it
my DiffUtil CallBAck
class DiffCB(
val oldl : ArrayList<Test>,
val newl : ArrayList<Test>
) : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return oldl.size
}
override fun getNewListSize(): Int {
return newl.size
}
override fun areItemsTheSame(oldItemPos: Int, newItemPos: Int): Boolean {
return oldl[oldItemPos].id == newl[newItemPos].id
}
override fun areContentsTheSame(oldItemPos: Int, newItemPos: Int): Boolean {
return oldl[oldItemPos].title.equals(newl[newItemPos].title)
}
}
my Adapter.kt
class TestAdapter(val click: TestClick) :
RecyclerView.Adapter<TestAdapter.TestVH>() {
var list: ArrayList<Test> = ArrayList()
inner class TestVH(val bin: ItemTestBinding) : RecyclerView.ViewHolder(bin.root) {
fun bind(test: Test) {
bin.tvTestId.text = "[id: ${test.id}]"
bin.tvTestTitle.text = test.title
bin.cbTest.isChecked = test.select
bin.cbTest.setOnClickListener {
click.click(test)
}
}
}
fun sumbitData(newl: ArrayList<Test>) {
val diff = DiffCB(this.list, newl)
val diffResult = DiffUtil.calculateDiff(diff)
list.clear()
this.list.addAll(newl)
diffResult.dispatchUpdatesTo(this)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: TestVH, position: Int) {
holder.bind(list[position])
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestVH {
return TestVH(ItemTestBinding.inflate(LayoutInflater.from(parent.context),
parent, false))
}
}
my Activity.kt
class TestActivity : AppCompatActivity(), TestClick {
private var list : ArrayList<Test> = ArrayList()
private lateinit var bin : ActivityTestBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bin = ActivityTestBinding.inflate(layoutInflater)
setContentView(bin.root)
val viewModel = ViewModelProviders.of(this).get(TestViewModel::class.java)
val manager = LinearLayoutManager(this)
bin.rvTest.layoutManager = manager
val adapter = TestAdapter(this)
bin.rvTest.adapter = adapter
//init first data
viewModel.setTests(initData())
viewModel.getTests().observe(this, Observer {
adapter.sumbitData(it as ArrayList<Test>)
})
bin.btnTest.setOnClickListener{
viewModel.setTests(updateData())
}
}
fun updateData() : ArrayList<Test> {
for (i in 2..6) {
var test = Test()
test.id = i
test.title = "title test $i update"
list.add(test)
}
return list
}
fun initData() : ArrayList<Test> {
for (i in 1..3) {
var test = Test()
test.id = i
test.title = "title test $i"
list.add(test)
}
return list
}
override fun click(test: Test) {
Toast.makeText(this, "${test.id} ${test.title}", Toast.LENGTH_SHORT).show()
}
}
it is first data
after update data, items with the same id have not been updated (id 2, 3)

Recyclerview item background color change

How can I change the background color of the selected item in RecyclerView Kotlin
Thank you from now
How to change the background color of only selected view in my recycle view example?only the background color of clicked itemview needs to be changed
OutTimeActiviyt
val linearLayoutManager = LinearLayoutManager(this)
layoutBnd.outRecylerView.layoutManager = linearLayoutManager
layoutBnd.outRecylerView.setHasFixedSize(false)
//IN RECYCLERVIEW
out_TimeList.clear()
val out_DataBase = this.openOrCreateDatabase("Park", Context.MODE_PRIVATE, null)
val recyclerCursor = out_DataBase.rawQuery("SELECT * FROM Money", null)
val listTimeIndex = recyclerCursor.getColumnIndex("MoneyListName")
while (recyclerCursor.moveToNext()) {
out_TimeList.add(recyclerCursor.getString(listTimeIndex))
}
recyclerCursor.close()
val recyclerMoneyListName = Out_Recyler_Adapter(out_TimeList)
layoutBnd.outRecylerView.adapter = recyclerMoneyListName
recyclerMoneyListName.setOnItemClickListener(object : Out_Recyler_Adapter.onItemClickListener{
override fun onItemClick(position: Int) {
Toast.makeText(this#OutTimeActivity, "Selected item:${position}", Toast.LENGTH_SHORT).show()
}
})
Out_TimeAdapter
class Out_Recyler_Adapter(private val out_TimeList: ArrayList<String>) :
RecyclerView.Adapter<Out_Recyler_Adapter.ViewHolder>() {
private lateinit var out_ClickListener: onItemClickListener
interface onItemClickListener {
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener) {
out_ClickListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.recyler_style, parent, false)
return ViewHolder(view, out_ClickListener)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val ItemsViewModel = out_TimeList[position]
holder.textView.text = ItemsViewModel
}
override fun getItemCount(): Int {
return out_TimeList.size
}
class ViewHolder(ItemView: View, listener: onItemClickListener) : RecyclerView.ViewHolder(ItemView) {
val textView: TextView = itemView.findViewById(R.id.style_txtParkingInfo)
init {
itemView.setOnClickListener {
listener.onItemClick(adapterPosition)
}
}
}
}

Show item info on selected item in RecyclerView using Kotlin

I am using kotlin language with android studio. I want to get the properties of the element I clicked in the RecyclerView.
Ben bu kod ile saderc id alabiliyorum
Ex: date
ListAdapter.kt
class ListAdapter(
private val context: Context
) : RecyclerView.Adapter<ListAdapter.ListViewHolder>() {
private var dataList = mutableListOf<Any>()
private lateinit var mListener: onItemClickListener
interface onItemClickListener {
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener) {
mListener = listener
}
fun setListData(data: MutableList<Any>) {
dataList = data
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.item_row, parent, false)
return ListViewHolder(view)
}
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
val question: Questionio = dataList[position] as Questionio
holder.bindView(question)
}
override fun getItemCount(): Int {
return if (dataList.size > 0) {
dataList.size
} else {
return 0
}
}
inner class ListViewHolder(itemView: View, listener: onItemClickListener) :
RecyclerView.ViewHolder(itemView) {
fun bindView(questionio: Questionio) {
itemView.findViewById<TextView>(R.id.txt_policlinic).text = questionio.policlinic
itemView.findViewById<TextView>(R.id.txt_title).text = questionio.title
itemView.findViewById<TextView>(R.id.txt_description).text = questionio.description
itemView.findViewById<TextView>(R.id.txt_date).text = questionio.date
itemView.findViewById<TextView>(R.id.txt_time).text = questionio.time
}
init {
itemView.setOnClickListener {
listener.onItemClick(adapterPosition)
}
}
}
}
My code in onCreateView inside list fragment.Edit
ListFragment
recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerView.adapter = adapter
observeData()
adapter.setOnItemClickListener(object : ListAdapter.onItemClickListener {
override fun onItemClick(position: Int) {
showShortToast(position.toString())
}
})
this function is also my observationData(),
I made new edits
private fun observeData() {
binding.shimmerViewContainer.startShimmer()
listViewModel.fetchQuestinData("questions",
requireContext())
.observe(viewLifecycleOwner, {
binding.shimmerViewContainer.startShimmer()
binding.shimmerViewContainer.hideShimmer()
binding.shimmerViewContainer.hide()
adapter.setListData(it)
adapter.notifyDataSetChanged()
})
}
You can pass highOrderFuction into the adapter then setonclickListener for any view you want. Like this:
class ListAdapter(
private val context: Context,
private val onItemClick:(questionio: Questionio)->Unit
) : RecyclerView.Adapter<ListAdapter.ListViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.item_row, parent, false)
return ListViewHolder(view,onItemClick)
}
...
inner class ListViewHolder(itemView: View,private val onItemClick:(questionio: Questionio)->Unit) : RecyclerView.ViewHolder(itemView) {
fun bindView(questionio: Questionio) {
//set on any view you want
itemView.findViewById<TextView>(R.id.root_view_id).
setOnClickListener{onItemClick(questionio)}
itemView.findViewById<TextView>(R.id.txt_policlinic).text =
questionio.policlinic
itemView.findViewById<TextView>(R.id.txt_title).text = questionio.title
itemView.findViewById<TextView>(R.id.txt_description).text =
questionio.description
itemView.findViewById<TextView>(R.id.txt_date).text = questionio.date
itemView.findViewById<TextView>(R.id.txt_time).text = questionio.time
}
}
}

Recyclerview does not display on the screen in kotlin

So I tried to create multi views recyclerview in kotlin, but sadly it did not work.The recyclerview does not display on the screen. It worth to mention that I tried to set the orientation as vertical in my layout files, also added all the dependencies and things needed. Can anyone please help me with that?
My MainActivity.class
#AndroidEntryPoint
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
lateinit var adapter: NumbersAdapter
lateinit var recyclerView: RecyclerView
var list: List<Nums> = listOf(Nums(1,false))
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
updateAll()
}
fun updateAll(){
binding.recyclerview.apply {
val layoutManager = LinearLayoutManager(this#MainActivity)
adapter = NumbersAdapter(list)
adapter = adapter
}}}
My Adapter
class NumbersAdapter(
var list: List<Nums>,
): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class RedViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val name = itemView.findViewById<TextView>(R.id.red_number)
fun bindRed(number: Nums) {
name.text = number.nums.toString()
}
}
class OrangeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val name = itemView.findViewById<TextView>(R.id.orange_number)
fun bindOrange(number: Nums) {
name.text = number.nums.toString()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == 0) {
val redvView =
LayoutInflater.from(parent.context).inflate(R.layout.red_item, parent, false)
return RedViewHolder(redvView)
}
else {
val orangeView =
LayoutInflater.from(parent.context).inflate(R.layout.orange_item, parent, false)
return OrangeViewHolder(orangeView)
}
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if(getItemViewType(position)==0){
(holder as RedViewHolder).bindRed(list[position])
}
else{
(holder as OrangeViewHolder).bindOrange(list[position])
}
}
override fun getItemViewType(position: Int): Int {
checkItem()
if(list[position].flag)
return 0
return 1
}
fun checkItem(){
for (i in list.indices) {
for (k in i + 1 until list.size) {
if (list[i].nums + list[k].nums == 0) {
list[i].flag = true
list[k].flag = true
}}}}}
in MainActivity.class change code in updateAll() function
fun updateAll(){
binding.recyclerView.apply {
adapter = NumbersAdapter(list)
layoutManager = LinearLayoutManager(this#MainActivity)
}
}

display list view in fragment kotlin

l want display my list view in fragment , l used separated listview adpater .
l got error in class adapter under line val view : View = LayoutInflater.from(context,this).inflate(R.layout.arr_list,parent,false)
class fragment
class fragment_Arr :Fragment(), View.OnClickListener {
override fun onClick(v: View?) {
// val intent = Intent(context, FlightsArrbefor::class.java)
// context!!.startActivity(intent)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_arrivel,container,false)
val url = "xxxxxxxx/airport.json?code=BGW"
Arr().execute(url)
return view
}
inner class Arr : AsyncTask<String, String, String>(){
override fun onPreExecute() {
super.onPreExecute()
}
// for build connection
override fun doInBackground(vararg url: String?): String{
var text : String
val connection = URL(url[0]).openConnection() as HttpURLConnection
try {
connection.connect()
text = connection.inputStream.use { it.reader().use{reader -> reader.readText()} }
} finally{
connection.disconnect()
}
return text
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson(result)
}
override fun onProgressUpdate(vararg text: String?) {
}
#SuppressLint("WrongViewCast")
private fun handleJson (jsonString: String?) {
val jsonObj = JSONObject(jsonString)
val result = jsonObj.getJSONObject("result")
val response = result.getJSONObject("respe")
val airport = response.getJSONObject("airport")
val pluginData = airport.getJSONObject("Data")
val schedule = pluginData.getJSONObject("schedule")
val arrivals = schedule.getJSONObject("arrivals")
// val data = arrivals.getJSONObject("data")
val jsonArray = JSONArray(arrivals.get("data").toString())
val list = ArrayList<FlightShdu>()
var x = 0
while (x < jsonArray.length()) {
val jsonObject = jsonArray.getJSONObject(x)
list.add(
FlightShdu(
jsonObject.getJSONObject("flight").getJSONObject("identification").getJSONObject("number").getString("default"),
jsonObject.getJSONObject("flight").getJSONObject("airline").getString("short"),
jsonObject.getJSONObject("flight").getJSONObject("status").getJSONObject("generic").getJSONObject("status" )
)
)
x++
}
list.forEach(::println)
var adapter = ListAdapteArr(this#MainActivity, list)
flight_arrivel_list.adapter = adapter
}
}
List Aadpter Class
class ListAdapteArr (val context: fragment_Arr, var list: ArrayList<FlightShdu>): BaseAdapter() {
#SuppressLint("ViewHolder", "NewApi")
override fun getView(p0: Int, convertView: View?, parent: ViewGroup?): View {
val view : View = LayoutInflater.from(context,this).inflate(R.layout.arr_list,parent,false)
val list = list[p0]
val code = view.findViewById(R.id.code_id) as AppCompatTextView
view.callsign_id.text=list.Callsign
view.airline_id.text=list.Airline
code.text = list.code
view.setOnClickListener {
val intent = Intent(context, FlightDeatilasArr::class.java)
intent.putExtra("Stauts",list.Stauts!!)
intent.putExtra("Callsign",list.Callsign!!)
intent.putExtra("Airline",list.Airline!!)
context!!.startActivity(intent)
}
}
private fun getDateTime(s: String): String? {
try {
val sdf = SimpleDateFormat("EE, MMM d KK:mm a")
val netDate = Date(s.toLong() * 1000)
return sdf.format(netDate)
} catch (e: Exception) {
return e.toString()
}
}
override fun getItem(p0: Int): Any {
return list [p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getCount(): Int {
return list.size
}
}
According to documentation, there is method with single parameter LayoutInflater.html#from(android.content.Context), but you invoke it with 2 parameters
LayoutInflater.from(context,this).inflate(R.layout.arr_list,parent,false)
And by the way, context that you pass is not actually Context, but a fragment
class ListAdapteArr (val context: fragment_Arr, ...)
To fix your problem use next approach
override fun getView(p0: Int, convertView: View?, parent: ViewGroup?): View? {
val view: View = LayoutInflater.from(parent!!.context).inflate(R.layout.arr_list,parent,false)
...
return view
}
According to documentation, parent should never be null.
The parent that this view will eventually be attached to