I'm trying to show BreakingNewsFragment through news activity using navigation
but the error is show
I am getting this error when trying to run this app. I have followed numerous guides to no avail. I am just trying to do the simplist exercise with navigation
Caused by: android.view.InflateException: Binary XML file line #20 in com.example.newsapp:layout/activity_news: Binary XML file line #20 in com.example.newsapp:layout/activity_news: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #20 in com.example.newsapp:layout/activity_news: Error inflating class fragment
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property newsViewModel has not been initialized
at com.example.newsapp.ui.activity.NewsActivity.getNewsViewModel(NewsActivity.kt:17)
at com.example.newsapp.ui.fragments.BreakingNewsFragment.onViewCreated(BreakingNewsFragment.kt:29)
newsActivity:
class NewsActivity : AppCompatActivity() {
lateinit var newsViewModel: NewsViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_news)
var newsRepository = NewsRepository(ArticleDataBase(this))
var newsViewModelFactoryProvider = NewsViewModelFactory(newsRepository)
newsViewModel = ViewModelProvider(this,newsViewModelFactoryProvider).get(NewsViewModel::class.java)
bottomNavigationView.setupWithNavController(navHostFragmentNews.findNavController())
}}
when to get newsViewModel from activity the error is show
in fragment:
class BreakingNewsFragment : Fragment(R.layout.fragment_breaking_news) {
lateinit var newsViewModel : NewsViewModel
lateinit var articleRecyclerAdapter: ArticleRecyclerAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
newsViewModel = (activity as NewsActivity).newsViewModel
setupRecyclerView()
}
fun setupRecyclerView(){
articleRecyclerAdapter= ArticleRecyclerAdapter()
rvBreakingNews.adapter= articleRecyclerAdapter
}}
xml code:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activity.NewsActivity">
<FrameLayout
android:id="#+id/flFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<fragment
android:name="androidx.navigation.fragment.NavHostFragment"
android:id="#+id/navHostFragmentNews"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph_news"/>
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="56dp"
app:menu="#menu/menu_bottom_navigation_news"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
i use many fragment other it ,with them no any problem
why the error come in this fragment
you are initializing the newsViewModel after doing setContentView. So the fragment gets created before that. Try moving setContentView down, like this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var newsRepository = NewsRepository(ArticleDataBase(this))
var newsViewModelFactoryProvider = NewsViewModelFactory(newsRepository)
newsViewModel = ViewModelProvider(this,newsViewModelFactoryProvider).get(NewsViewModel::class.java)
setContentView(R.layout.activity_news)
bottomNavigationView.setupWithNavController(navHostFragmentNews.findNavController())
}}
Related
everyone. I suddenly get an Unresolved reference error displayed in my layouts in RecyclerView. I've already restarted Android Studio, rebuilt and cleaned the project. All without success.
AddNewHomeFragment.kt:
class AddNewHomeFragment : Fragment() {
listImg = ArrayList()
var rv_img:RecyclerView = view.findViewById(R.id.recyclerViewImgs)
rv_img.layoutManager = GridLayoutManager(requireContext(),3)
adapter = CustomerAdapter(requireContext(),listImg){
var intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent,IMAGE_REQUEST)
}
rv_img.adapter = adapter
...
}
My CustomAdapter for RecyclerView:
class CustomerAdapter(val context: Context,
private val listImg:ArrayList<Int>, private val onClickFunction: ((Any?) -> Unit)? = null):RecyclerView.Adapter<CustomerAdapter.MyCustomViewHolder>() {
class MyCustomViewHolder(view: View):RecyclerView.ViewHolder(view) {
//Unresolved reference: customImg
val customImg:ImageView = view.findViewById(R.id.customImg)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyCustomViewHolder {
//Unresolved reference: single_img
val inflate = LayoutInflater.from(context).inflate(R.layout.single_img,parent,false)
return MyCustomViewHolder(inflate)
}
override fun onBindViewHolder(holder: MyCustomViewHolder, position: Int) {
holder.customImg.setImageResource(listImg[position])
holder.customImg.setOnClickListener {
this#CustomerAdapter.onClickFunction?.invoke(listImg[position])
}
}
override fun getItemCount(): Int {
return listImg.size
}
}
fragment_add_new_home.xml:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewImgs"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
single_img.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_marginEnd="5dp"
android:layout_marginBottom="8dp"
android:background="#drawable/layout_for_imgs"
android:id="#+id/customImg"
app:layout_constraintDimensionRatio="1"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="#drawable/ic_baseline_add_home_24">
</ImageView>
</androidx.constraintlayout.widget.ConstraintLayout>
How to make my recicle view visible on search field click in fragment and how to set search in this View?
Logcat shows, that "No adapter attached; skipping layout"
Code of home_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="8dp">
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="330dp"
android:layout_height="30dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="62dp"
android:layout_height="match_parent"
android:src="#drawable/ic_baseline_search_24" />
<EditText
android:id="#+id/searchField"
android:layout_width="270dp"
android:layout_height="60dp"
android:ems="10"
android:hint="Поиск"
android:inputType="textPersonName"
tools:ignore="SpeakableTextPresentCheck" />
<ListView
android:id="#+id/listSearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="#layout/list_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
Code of HomeFragment
package com.example.booksh
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.booksh.databinding.FragmentHomeBinding
class HomeFragment: Fragment(R.layout.fragment_home) {
private lateinit var binding: FragmentHomeBinding
private lateinit var newRecyclerView: RecyclerView
private lateinit var newArrayList: ArrayList<Books>
lateinit var imageId: Array<Int>
lateinit var heading: Array<String>
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding = FragmentHomeBinding.inflate(layoutInflater)
super.onViewCreated(binding.root, savedInstanceState)
// Поисковой список
imageId = arrayOf(
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e,
R.drawable.f,
R.drawable.h,
R.drawable.i,
R.drawable.j
)
heading = arrayOf(
"Война и мир",
"Капитанская дочка",
"Раковый корпус",
"Мастер и маргарита",
"Муму",
"О дивный новый мир",
"Скотный двор",
"Портрет Дориана Грея",
"Отель с привидениями"
)
//Переменные для выпадающего списка на главной странице - поиск книг
newRecyclerView = binding.recyclerView
newRecyclerView.layoutManager = LinearLayoutManager(this.context)
newRecyclerView.setHasFixedSize(true)
newArrayList = arrayListOf()
getUserData()
}
//Заносим в список данные о книгах
private fun getUserData() {
for (i in imageId.indices){
val book = Books(imageId[i], heading[i])
newArrayList.add(book)
}
newRecyclerView.adapter = MyAdapter(newArrayList)
}
}
Code of adapter
package com.example.booksh
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.imageview.ShapeableImageView
class MyAdapter(private var booksList: ArrayList<Books>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item,
parent, false)
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = booksList[position]
holder.titleImage.setImageResource(currentItem.titleImage)
holder.tvHeading.text = currentItem.heading
}
override fun getItemCount(): Int {
return booksList.size
}
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
val titleImage : ShapeableImageView = itemView.findViewById(R.id.list_item_icon)
val tvHeading: TextView = itemView.findViewById(R.id.list_item_text)
}
}
I made a ricycle view for main activity without visibility change, but it was shown in every fragment of my app. Then I copied all code connected with recyclerView to fragment home (xml, kt), but it became invisible whether I click on the search field or not.
This question already has answers here:
Why do I get "unresolved reference" error for my view's name/ID when I type it in Kotlin?
(2 answers)
Closed 1 year ago.
when I try to use a TextView in my activity_main.xml, I get a “Unresolved reference” in my MainActivity.kt (even before try building)? I just can’t see what I’m doing wrong!
I've highlighted the error at the end of the MainActivity.
Any help appreciated.
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val carouselRecyclerview = findViewById<CarouselRecyclerview>(R.id.recycler)
val list = ArrayList<DataModel>()
list.add(DataModel(R.drawable.ad_astra, "Adastra"))
list.add(DataModel(R.drawable.beach_bum, "Beach Bum"))
list.add(DataModel(R.drawable.dark_phoenix, "Dark Phoenix"))
list.add(DataModel(R.drawable.glass, "Glass"))
val adapter = DataAdapter(list)
carouselRecyclerview.adapter = adapter
carouselRecyclerview.set3DItem(true)
carouselRecyclerview.setAlpha(true)
val carouselLayoutManager = carouselRecyclerview.getCarouselLayoutManager()
val currentlyCenterPosition = carouselRecyclerview.getSelectedPosition()
carouselRecyclerview.setItemSelectListener(object : CarouselLayoutManager.OnSelected {
override fun onItemSelected(position: Int) {
//Cente item
Toast.makeText(this#MainActivity, list[position].text, Toast.LENGTH_LONG).show()
ShowMeIt.text = "Why does cause a Unresolved reference?"
ShowMeIt.text = list[position].text
}})
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.jackandphantom.carouselrecyclerview.CarouselRecyclerview
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler"/>
<TextView
android:id="#+id/ShowMeIt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="186dp"
android:layout_marginRight="186dp"
android:layout_marginBottom="106dp"
android:text="Hello" />
</RelativeLayout>
I think you need to define on MainActivity.kt like this
val ShowMeIt= findViewById<TextView>(R.id.ShowMeIt)
I am using a horizontal RecyclerView and showing images using the CircleImageView widget (See image below).
I am really struggling on how to make the list of items loop around, so that if you are in the last item, you will move to the first item in the list?
I have tried quite a few similar examples but I can’t make them work as they are in Java, or are quite complex. following is my code
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var adapter: ConcatAdapter
lateinit var userVerticalAdapter: UsersAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupDataInRecyclerView()
}
private fun setupDataInRecyclerView() {
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
userVerticalAdapter = UsersAdapter(DataSource.getUser())
val listOfAdapters = listOf(userVerticalAdapter)
adapter = ConcatAdapter(listOfAdapters)
recyclerView.adapter = adapter
}
}
Adapter.kt
class UsersAdapter(
private val users: ArrayList<User>
) : RecyclerView.Adapter<UsersAdapter.DataViewHolder>() {
class DataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(user: User) {
itemView.textViewUserName.text = user.name
Glide.with(itemView.imageViewAvatar.context)
.load(user.avatar)
.into(itemView.imageViewAvatar)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
DataViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.item_layout, parent,false))
override fun getItemCount(): Int = users.size
override fun onBindViewHolder(holder: DataViewHolder, position: Int) =
holder.bind(users[position])
}
}
DataSource.kt
object DataSource {
fun getUser() = ArrayList<User>().apply {
add(User(1, "Chillis", R.drawable.chilli))
add(User(2, "Tomato", R.drawable.tomatoe))
add(User(3, "Sweetcorn", R.drawable.sweeetcorn))
add(User(4, "Potatoe", R.drawable.potatoe))
add(User(5, "Aubergine", R.drawable.aubmain))
add(User(12, "Onion", R.drawable.onion))
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="#layout/item_layout_banner"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="1dp">
<androidx.cardview.widget.CardView
android:layout_width="120dp"
android:layout_height="120dp"
app:cardCornerRadius="4dp"
app:cardMaxElevation="2dp"
app:cardElevation="1dp"
android:layout_centerInParent="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="90dp"
android:layout_height="90dp"
android:scaleType="centerCrop"
android:layout_centerHorizontal="true"
app:civ_border_width= "3dp"
app:civ_border_color= "#color/colorPrimary"
android:id="#+id/imageViewAvatar"
android:src="#drawable/ic_launcher_background"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text="Veg"
android:layout_below="#+id/imageViewAvatar"
android:id="#+id/textViewUserName"
android:gravity="center"
android:layout_marginTop="5dp"
android:layout_centerHorizontal="true"
android:textColor="#000"
android:layout_marginBottom="5dp"
android:autoSizeTextType="uniform"
android:autoSizeMinTextSize="8sp"
android:autoSizeMaxTextSize="15sp"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
To achieve this first you have to override the getItemCount function of UsersAdapter to return a very large value such as Int.MAX_VALUE
// This enables your adapter to scroll past the actual list size
override fun getItemCount(): Int = Int.MAX_VALUE
Now change your onBindViewHolder to calculate actual position
// Lets say your list had 100 items
override fun onBindViewHolder(holder: DataViewHolder, position: Int) {
// position can be larger than 100 (ex 101), because our getItemCount doesn't return actual list size
// so if we receive position as 101, which item should we display?
// that should be item 1. (for 102 -> 2, 201 -> 1) and so on
// this suggests use of modules
val pos = position % users.size
holder.bind(users[pos]) // bind the actual item
}
Now in your MainActivity after recyclerView.adapter = adapter line, add following line
// When RV is loaded scroll it to middle, so that user doesn't hit limit on both ends(easily)
rv.scrollToPosition(Int.MAX_VALUE/2)
I am working on an app where click on an item in a recycler View opens another activity (Customer-Detail) where there are three Fragments in Tab layout .recycler view contains list of employees, I want to show the details of employee selected from list. I have stored All employee's data in SQLITE in "Employee" Table ( which contains Customer-Id ,Name ,Address ETC) , Now I have Customer-ID (ID of selected Customer) in "Customer-Detail" Activity. I just want to send that "Customer-ID" value to three Fragments of this Customer-Detail Activity. It seems simple but I could not find any solution . Here is my CustomerDetail.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CustomerDetail">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/custID"
/>
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabInlineLabel="true"
app:tabBackground="#color/lightRed"
app:tabIndicatorColor="#color/white"
app:tabTextColor="#color/white"
app:tabMode="fixed"
android:id="#+id/tablayout"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/appbar"
android:id="#+id/viewPager"
/>
</RelativeLayout>
Here is CustomerDetails.kt :
class CustomerDetail : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_customer_detail)
val extras: Bundle? = intent.extras
val EmployeeID: Int = extras!!.getInt("id")
sendToFragmentOrder(EmployeeID)
val appbar = findViewById<AppBarLayout>(R.id.appbar)
val tabLayout = findViewById<TabLayout>(R.id.tablayout)
val viewPager = findViewById<ViewPager>(R.id.viewPager)
setUpTabs()
}
private fun sendToFragmentOrder(id : Int) {
// this method is not working...
val bundle = Bundle()
bundle.putInt("id",id)
val fragmentOrder = OrderFragment()
fragmentOrder.arguments = bundle
}
private fun setUpTabs() {
val adapter = mPagerAdapter(supportFragmentManager)
adapter.addFragment(OrderFragment(), "Orders")
adapter.addFragment(ReceiptsFragment(), "Receipts")
adapter.addFragment(ReportsFragment(), "Reports")
val viewpager = findViewById<ViewPager>(R.id.viewPager)
viewpager.adapter = adapter
val tab = findViewById<TabLayout>(R.id.tablayout)
tab.setupWithViewPager(viewpager)
}
}
OrderFragment() Class :
class OrderFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val id = arguments?.getInt("id")
val view=inflater.inflate(R.layout.fragment_order, container, false)
val tv = view.findViewById<TextView>(R.id.idtv)
tv.text = id.toString()
return view }
}
i hope i explained my question well ... i am new here so ... any help will be appreciated
use the same viewmodel:
in Activity:
val viewModel: MyViewModel by viewModels()
in Fragment:
val viewModel: MyViewModel by activityViewModels()
needs ktx artifcats, see https://developer.android.com/topic/libraries/architecture/viewmodel