Reputation: 15722
I can't get my Recycleview inside my fragment to work. I've tried moving the recyclerview adapter
and layout
code to onViewCreated
but that didn't work either.
Does anybody have an idea to what the problem could be?
Main Activity
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
loadFragment(NewsFragment()) // Show the news fragment by default
initBottomNavigation()
}
...
private fun loadFragment(fragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container, fragment)
transaction.addToBackStack(null)
transaction.commit()
}
...
NewsAdapter
class NewsAdapter(private val newsItems: List<NewsItem>) :
RecyclerView.Adapter<NewsAdapter.ViewHolder>() {
private lateinit var context: Context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
context = parent.context
return ViewHolder(
LayoutInflater.from(context).inflate(R.layout.news_list_item, parent, false)
)
}
override fun getItemCount(): Int = newsItems.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) =
holder.bind(newsItems[position])
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(newsItem: NewsItem) {
}
}
}
fragment_news.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".NewsFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvNewsItems"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<include
layout="@layout/news_list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.recyclerview.widget.RecyclerView>
</FrameLayout>
NewsFragment
class NewsFragment : Fragment() {
private val newsItems = arrayListOf<NewsItem>()
private val newsAdapter = NewsAdapter(newsItems)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
if (container != null) {
container.rootView.rvNewsItems.layoutManager =
LinearLayoutManager(context, RecyclerView.VERTICAL, false)
container.rootView.rvNewsItems.adapter = newsAdapter
}
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_news, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
btnLike.setOnClickListener {
val color = ResourcesCompat.getColor(resources, R.color.colorPrimary, null);
btnLike.setColorFilter(color)
}
}
}
build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.johanvanderlindenapp"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//Navigation
implementation "androidx.navigation:navigation-fragment-ktx:2.1.0"
implementation "androidx.navigation:navigation-ui-ktx:2.1.0"
// Material widgets
implementation "com.google.android.material:material:1.0.0"
// ViewModel and LiveData
def lifecycle_version = "2.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation 'androidx.recyclerview:recyclerview:1.1.0'
}
EDIT I have removed the include inside the recycleview shown above, still receive the error.
Upvotes: 0
Views: 541
Reputation: 15722
Using vindViewById
instead of synthetic
turned out to solve the problem.
My news fragment now looks like this:
class NewsFragment : Fragment() {
private val newsItems = arrayListOf<NewsItem>()
private val newsAdapter = NewsAdapter(newsItems)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_news, container, false)
val rvNewsItems = view.findViewById(R.id.rvNewsItems) as RecyclerView
rvNewsItems.layoutManager = LinearLayoutManager(context)
rvNewsItems.adapter = newsAdapter
return view
}
}
Upvotes: 1
Reputation: 2283
You cannot use the <include />
tag to show your list items. Your ViewHolder
class takes care of instantiating your list items for you. Simply remove the include
tag in your fragment_news.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".NewsFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvNewsItems"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</androidx.recyclerview.widget.RecyclerView>
</FrameLayout>
Also, make sure your newsItems
is not empty. Otherwise, it will show you an empty view. If you wish to add items to your newsItems
, don't forget to call notifyDataSetChanged()
in your adapter to reflect the changes.
Upvotes: 0
Reputation: 146
Try this
<FrameLayout 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"
tools:context=".NewsFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvNewsItems"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_height="match_parent" >
</androidx.recyclerview.widget.RecyclerView>
class NewsFragment : Fragment() {
private val newsItems = arrayListOf<NewsItem>()
private val newsAdapter : NewsAdapter? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
container.rootView.rvNewsItems.adapter = newsAdapter
container.rootView.rvNewsItems.adapter as NewsAdapter).submitList(newsItems)
}
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_news, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
btnLike.setOnClickListener {
val color = ResourcesCompat.getColor(resources, R.color.colorPrimary, null);
btnLike.setColorFilter(color)
}
}
Upvotes: 0