I'm trying to make a spinner with list of locale months (or string in general). I already checked a few tutorials on this topic and had this running using string-array and ArrayAdapter.createFromResource() but i need to also show dynamic things like filtered list of years etc.
My activity:
class ChartActivity : AppCompatActivity() {
private val view by lazy { ActivityChartBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setSpinners()
setContentView(R.layout.activity_chart)
}
private fun setSpinners() {
setMonthSpinner()
}
private fun setMonthSpinner() {
var months = DateFormatSymbols.getInstance().shortMonths
var monthsAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, months)
monthsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
view.spinnerMonth.adapter = monthsAdapter
}
}
activity xml:
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Spinner
android:id="#+id/spinnerMonth"
android:spinnerMode="dropdown"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_weight="1"
android:gravity="center" />
<View
android:id="#+id/divider"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="?android:attr/listDivider" />
<Spinner
android:id="#+id/spinnerYear"
android:spinnerMode="dropdown"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_weight="1"
android:gravity="center" />
</LinearLayout>
Spinners (without values) are visible in emulator, click on them triggers visual effects, but doesn't show value list
Because you're not using your inflated binding in setContentView you're setting the layout again setContentView(R.layout.activity_chart) but you're updating view using view.spinnerMonth. This won't have effect.
So the correct way would be set setContentView(view.root).
So your activity would look like this:
class MainActivity : AppCompatActivity() {
private val view by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(view.root)
setSpinners()
}
private fun setSpinners() {
setMonthSpinner()
}
private fun setMonthSpinner() {
var months = DateFormatSymbols.getInstance().shortMonths
var monthsAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, months)
monthsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
view.spinnerMonth.adapter = monthsAdapter
}
}
Related
I wanna align vertically all of items in RecyclerView like ListView but I'm confused to set them.
In other words, They are seen horizontally : https://i.stack.imgur.com/ossLb.jpg
item's image is here : https://i.stack.imgur.com/sjDws.png
Main Activity(CalendarActivity.kt) gets Fragment(HomeFragment) which gets item's information.
CalendarActivity (Main Activity)
L HomeFragment (items are shown in here)
L item (note_layout.xml)
Many solutions I've seen are Add this RecyclerView.layoutManager = LinearLayoutManager(this) in MainActivity.
Even if I added in CalendarActivity, It returns error : kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized
And In HomeFragment, I added binding.recyclerViewNotes.layoutManager = LinearLayoutManager(activity) in onCreateView, but It returns same error.
It is related to ViewBinding of course. But what I wanna say is I didn't search way with reference.
What shoud I do in this situation? I'm stuck here.
Someone help please? 🤕
CalendarActivity.kt
class CalendarActivity : AppCompatActivity() {
val TAG: String = "CalenderActivity"
//private lateinit var binding: FragmentHomeBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_calendar)
Log.d(TAG, "CalendarActivity - onCreate() called")
//binding = FragmentHomeBinding.inflate(layoutInflater)
//binding.recyclerViewNotes.layoutManager = LinearLayoutManager(this)
//setContentView(binding.root)
val navController = Navigation.findNavController(this, R.id.fragment)
NavigationUI.setupActionBarWithNavController(this, navController)
}
override fun onSupportNavigateUp(): Boolean {
Log.d(TAG, "CalendarActivity - onSupportNavigateUp() called")
return NavigationUI.navigateUp(
Navigation.findNavController(this, R.id.fragment),
null
)
}
}
HomeFragment.kt
class HomeFragment : BaseFragment() {
private lateinit var binding: FragmentHomeBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
//binding.recyclerViewNotes.layoutManager = LinearLayoutManager(activity)
binding = FragmentHomeBinding.inflate(inflater)
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
binding.recyclerViewNotes.setHasFixedSize(true)
binding.recyclerViewNotes.layoutManager = StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)
launch {
context?.let {
val notes = NoteDatabase(it).getNoteDao().getAllNotes()
binding.recyclerViewNotes.adapter = NotesAdapter(notes)
}
}
binding.buttonAdd.setOnClickListener {
val action = HomeFragmentDirections.actionAddNote()
Navigation.findNavController(it).navigate(action)
}
}
}
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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.HomeFragment"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_notes"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/button_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
android:layout_marginBottom="40dp"
android:clickable="true"
android:src="#drawable/ic_add" />
</LinearLayout>
note_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:id="#+id/text_date"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_weight="2"
android:text="2021/01/01"
android:textColor="#111111"
android:textSize="12sp" />
<TextView
android:id="#+id/text_view_title"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="4"
android:layout_marginTop="5dp"
android:text="Title"
android:textStyle="bold"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Headline" />
</LinearLayout>
If you need more detailed information, please comment! thank you!
You have already assigned a LinearLayoutManager in your XML, and that's the type that looks like ListView.
So just delete this line where you are changing it to a staggered grid, which is not what you want:
binding.recyclerViewNotes.layoutManager = StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)
Change your code to this
binding.recyclerViewNotes.layoutManager = StaggeredGridLayoutManager(1,
StaggeredGridLayoutManager.VERTICAL)
or You can also use LinearLayoutManager instead of StaggeredGridLayoutManager
binding.recyclerViewNotes.layoutManager = new LinearLayoutManager(this);
I created a small practice app which changes the image on-screen when the buttonNext is clicked. However, neither the image nor button does anything. Everything in my MainActivity looks normal for an onClickListener setup and I followed various guides to create a layout which works. But, I'm not sure why it looks so weird and does not work in the emulator.
Here is the MainActivity code I wrote so far:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setListener()
}
private fun changeImage(view: View) {
when (view.id) {
R.id.goodMorning -> view.setBackgroundResource(R.drawable.gm1)
R.id.goodMorning -> view.setBackgroundResource(R.drawable.gm2)
else -> view.setBackgroundColor(Color.LTGRAY)
}
}
private fun setListener() {
val goodMorning = findViewById<ImageView>(R.id.goodMorning)
val buttonNext = findViewById<TextView>(R.id.buttonNext)
fun setListener(){
val clickableViews: List<View> =
listOf(goodMorning, buttonNext)
for (item in clickableViews){
item.setOnClickListener() { changeImage(it) }
}
}
}
}
This is the layout xml:
<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">
<ImageView
android:id="#+id/goodMorning"
android:layout_width="404dp"
android:layout_height="562dp"
android:contentDescription="#android:string/no"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.428"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.365"
tools:srcCompat="#drawable/gm1" />
<Button
android:id="#+id/buttonNext"
style="#style/twoButtons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="#string/buttonNext"
android:textSize="#dimen/box_text_size"
app:layout_constraintBaseline_toBaselineOf="#+id/buttonBack"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/buttonBack" />
<Button
android:id="#+id/buttonDownload"
style="#style/twoButtons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="#string/buttonDownload"
android:textSize="#dimen/box_text_size"
app:layout_constraintBaseline_toBaselineOf="#+id/buttonBack"
app:layout_constraintEnd_toStartOf="#+id/buttonBack"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/buttonBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:text="#string/buttonBack"
android:textColor="#android:color/black"
android:textSize="#dimen/box_text_size"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/goodMorning"
app:layout_constraintVertical_bias="0.718" />
This is what the app looks like in Pixel 2:
Any help is greatly appreciated!
change the code like this
private fun changeImage(view: View) {
val goodMorning = findViewById<ImageView>(R.id.goodMorning)
when (view.id) {
R.id.buttonBack -> view.setBackgroundResource(R.drawable.gm1)
R.id.buttonNext -> view.setBackgroundResource(R.drawable.gm2)
else -> goodMorning.setBackgroundColor(Color.LTGRAY)
}
}
private fun setListener() {
val buttonNext = findViewById<TextView>(R.id.buttonNext)
val buttonBack = findViewById<TextView>(R.id.buttonBack)
val clickableViews: List<View> =
listOf(buttonBack, buttonNext)
for (item in clickableViews){
item.setOnClickListener() { changeImage(it) }
}
}
I found out how to fix the issue:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val nextButton: Button = findViewById(R.id.buttonNext)
nextButton.setOnClickListener() { changeImage() }
}
private fun changeImage() {
// Shift through all available images
val imageOptions: ImageView = findViewById(R.id.morningImages)
val drawableResources = when (imageOptions) {
buttonNext -> R.drawable.gm1
else -> R.drawable.gm2
}
imageOptions.setImageResource(drawableResources)
// Repeat function needed
}
}
You are better off creating the clickListener at the beginning with onCreate because you will not have to create another private function which can make this issue more confusing than it really is.
Create a new variable within the changeImage function to find the ImageView. After that, make another variable called to create a when block to shift through the images available and end it with an else statement to avoid creating an error.
Set the imageResource to drawableResources so the images appear on-screen when requested.
Note: a repeat function is needed to shift through the images again once the user goes through all of them.
So I am following for my project this clean architecure in kotlin (https://github.com/android10/Android-CleanArchitecture-Kotlin) and I want to add a progress bar before recycler view loads the data and make it dissapear after the data loads. In this example the progress bar is in a separate toolbar but in my case i want to be in center of the recycler view.
This is my layout:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/list_wrapper_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="8dp"
android:background="#drawable/layout_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/movieList_recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
app:layout_constraintBottom_toTopOf="#+id/bottom_navigation_bar"
app:layout_constraintEnd_toEndOf="#+id/list_horizontal_guideline_end"
app:layout_constraintStart_toStartOf="#+id/list_horizontal_guideline_start"
app:layout_constraintTop_toBottomOf="#+id/searchView" />
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="#color/black"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
And in my class:
class MoviesFragment : BaseFragment() {
#Inject lateinit var navigator: Navigator
#Inject lateinit var moviesAdapter: MoviesAdapter
private lateinit var moviesViewModel: MoviesViewModel
override fun layoutId() = R.layout.fragment_movies
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
appComponent.inject(this)
moviesViewModel = viewModel(viewModelFactory) {
observe(movies, ::renderMoviesList)
failure(failure, ::handleFailure)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initializeView()
loadMoviesList()
}
private fun initializeView() {
movieList_recyclerView.layoutManager = StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)
movieList_recyclerView.adapter = moviesAdapter
}
private fun loadMoviesList() {
progressBar.visible()
movieList_recyclerView.invisibile()
moviesViewModel.loadMovies()
}
private fun renderMoviesList(movies: List<MovieView>?) {
moviesAdapter.collection = movies.orEmpty()
progressBar.invisible()
movieList_recyclerView.visible()
}
private fun handleFailure(failure: Failure?) {
when (failure) {
is NetworkConnection -> renderFailure(R.string.failure_network_connection)
is ServerError -> renderFailure(R.string.failure_server_error)
is ListNotAvailable -> renderFailure(R.string.failure_movies_list_unavailable)
}
}
private fun renderFailure(#StringRes message: Int) {
movieList.invisible()
emptyView.visible()
hideProgress()
notifyWithAction(message, R.string.action_refresh, ::loadMoviesList)
}
}
But the progress bar doesn't show up at all. What am I doing wrong?
I am trying to populate two or more recycler views on one activity, the process works fine with one view, but the moment I add another one then it crashes.
Can someone see if I'm doing something wrong? I know how I'm doing it at the moment isn't the best practice or efficient.
My code from the activity
private var shouldInitRecyclerView = true
private lateinit var testSection: Section
private lateinit var assSection: Section
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_edit_mod)
FirestoreUtil.addModInfoListener("test","xbIpNiDXGsIPmb5sTwbH", this, this::updateRecyclerViewTest)
FirestoreUtil.addModInfoListener("assignment","xbIpNiDXGsIPmb5sTwbH", this, this::updateRecyclerViewAss)
}
private fun updateRecyclerViewTest(items: List<Item>) {
fun init() {
recycler_view_test.apply {
layoutManager = LinearLayoutManager(this#EditModActivity)
adapter = GroupAdapter<ViewHolder>().apply {
testSection = Section(items)
add(testSection)
setOnItemClickListener(onItemClick)
}
}
shouldInitRecyclerView = false
}
fun updateItems() = testSection.update(items)
if (shouldInitRecyclerView)
init()
else
updateItems()
}
private fun updateRecyclerViewAss(items: List<Item>) {
fun init() {
recycler_view_ass.apply {
layoutManager = LinearLayoutManager(this#EditModActivity)
adapter = GroupAdapter<ViewHolder>().apply {
assSection = Section(items)
add(assSection)
setOnItemClickListener(onItemClick)
}
}
shouldInitRecyclerView = false
}
fun updateItems() = assSection.update(items)
if (shouldInitRecyclerView)
init()
else
updateItems()
}
and the layout:
<android.support.constraint.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=".EditModActivity">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Groups"
android:layout_marginLeft="8dp"
android:textStyle="bold"
android:textSize="20sp"/>
<android.support.v7.widget.RecyclerView
android:layout_marginTop="8dp"
android:layout_below="#id/textView"
android:id="#+id/recycler_view_test"
android:layout_marginLeft="8dp"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.v7.widget.RecyclerView
android:layout_marginTop="8dp"
android:layout_below="#id/recycler_view_test"
android:id="#+id/recycler_view_ass"
android:layout_marginLeft="8dp"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
I know there are few questions about this problem. But none of them didn't solve my problem especially my code is in Kotlin and new working with Fragments. Don't rush to say my question is duplicated.
My problem is exactly what title said, my RecyclerView is populated just with one item(child) from Firebase in my Fragment.
Adapter:
class NewsList(private val userList: List<News>) : RecyclerView.Adapter<NewsList.ViewHolder>() {
private val Context = this
override fun onBindViewHolder(p0: ViewHolder?, p1: Int) {
val news: News = userList[p1]
p0?.mesajTextView?.text = news.text
val time = news.time
val getTimeAgo = GetTimeAgo()
val lastMsg = getTimeAgo.getTimeAgo(time, Context)
p0?.timeNewsTextView!!.text = lastMsg
}
override fun onCreateViewHolder(p0: ViewGroup?, p1: Int): ViewHolder {
val v = LayoutInflater.from(p0?.context).inflate(R.layout.news_layout, p0, false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return userList.size
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val mesajTextView = itemView.findViewById(R.id.mesajTextView) as TextView
val timeNewsTextView = itemView.findViewById(R.id.timeNewsTextView) as TextView
}
}
My fragment where ReyclerView is populated:
override fun onActivityCreated(savedInstanceState: Bundle?) {
newsRecyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
}
private fun populalteQuestionsList() {
val mChatDatabaseReference = FirebaseDatabase.getInstance().reference.child(Constants.NEWS)
mListenerPopulateList = mChatDatabaseReference.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (convSnapshot in dataSnapshot.children) {
val news = ArrayList<News>()
val conv = convSnapshot.getValue(News::class.java)
news.add(conv!!)
val adapter = NewsList(news)
newsRecyclerView!!.adapter = adapter
adapter.notifyDataSetChanged()
}
}
override fun onCancelled(databaseError: DatabaseError) {
}
})
mChatDatabaseReference.addListenerForSingleValueEvent(mListenerPopulateList)
}
Layout for items:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
card_view:cardCornerRadius="2dp"
card_view:contentPadding="10dp"
card_view:cardElevation="10dp">
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp">
<TextView
android:id="#+id/mesajTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="64dp"
android:textAppearance="?android:attr/textAppearanceLarge"
tools:text="Mesaj" />
<TextView
android:id="#+id/timeNewsTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginEnd="16dp"
android:layout_marginTop="4dp"
android:maxLength="15"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="14:20" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Hope you understand, please help me I really need to finish this app.
You are creating new list with having single element in loop and passing it to adapter so it has only one element to show so
Move this outside loop
val adapter = NewsList(news)
newsRecyclerView!!.adapter = adapter
adapter.notifyDataSetChanged()
and initialise list outside for loop
val news = ArrayList<News>()
for (convSnapshot in dataSnapshot.children) {
val conv = convSnapshot.getValue(News::class.java)
news.add(conv!!)
}
val adapter = NewsList(news)
newsRecyclerView!!.adapter = adapter
adapter.notifyDataSetChanged()
Note : fill_parent has been deprecated so us match_parent
You're recreating the dataset at every iteration, so it will always have the last added item, move the instantiation of the datasource to outside the loop. Also, try not adding the values for the adapter at every iteration. When you're done adding items to the datasource, then you should add them to the adapter and set the adapter in the recyclerview. :
val news = ArrayList<News>()
for (convSnapshot in dataSnapshot.children) {
val conv = convSnapshot.getValue(News::class.java)
news.add(conv!!)
}
val adapter = NewsList(news)
newsRecyclerView!!.adapter = adapter
adapter.notifyDataSetChanged()