#android #xml #kotlin
#Android #xml #kotlin
Вопрос:
У меня есть фрагмент, в котором я обрабатываю данные из источника xml, и все работает нормально, но дело в том, что когда я обновляю свой макет, отсоединяя и затем прикрепляя свой фрагмент, пользовательский интерфейс продолжает мигать, пока все данные не будут обработаны, я много раз проверял свой код, но я чувствую себя потерянным, и я не могнайти что-нибудь
- Вот как я обрабатываю свои исходные данные xml
fun getData(){
val url = URL("www.xmldatasource.com")
val factory = XmlPullParserFactory.newInstance()
factory.isNamespaceAware = false
val xpp = factory.newPullParser()
xpp.setInput(GetInputStream(url), "utf-8")
var insideItem = false
var eventType = xpp.eventType
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if (xpp.name.equals("item", ignoreCase = true)) {
insideItem = true
} else if (xpp.name.equals("title", ignoreCase = true)) {
if (insideItem) {
title = xpp.nextText()
}
} else if (xpp.name.equals("pubDate", ignoreCase = true)) {
if (insideItem) {
val subbedDate = xpp.nextText()
publishDate = subbedDate.substring(0, 25)
}
} else if (xpp.name.equals("guid", ignoreCase = true)) {
if (insideItem) {
link = xpp.nextText()
}
} else if (xpp.name.equals("description", ignoreCase = true)) {
if (insideItem) {
val newsDescription = xpp.nextText()
if (newsDescription.contains("src") amp;amp; newsDescription.contains("jpg")) {
imageUrl = newsDescription.substring(
newsDescription.indexOf("src=") 5,
newsDescription.indexOf("jpg") 3
)
}
if (newsDescription.contains("<BR>") amp;amp; newsDescription.contains("</p>")) {
description =
newsDescription.substring(
newsDescription.indexOf("<BR>") 4,
newsDescription.indexOf("</p>")
)
}
}
}
} else if (eventType == XmlPullParser.END_TAG amp;amp; xpp.name.equals("item", ignoreCase =
true)) {
insideItem = false
imageUrl?.let {
//TODO : Getting Image Url And Convert it to Bitmap
val urlImg = URL(it)
val httpURLConnection = urlImg.openConnection() as HttpURLConnection
httpURLConnection.connect()
val inputStream = httpURLConnection.inputStream
val bitmap = BitmapFactory.decodeStream(inputStream)
CoroutineScope(Dispatchers.Main).launch{
xmlList?.clear()
val model = NewsModel(bitmap, title, description, publishDate!!, link!!)
xmlList?.add(model)
leagueViewModel.insertNews(model)
binding.newsrcycler.adapter = LeagueNewsAdapter(requireContext(), xmlList!!)
customType(requireActivity(), "left-to-right")
}
})
}
}
}
eventType = xpp.next()
}
}
- Вот как я обновляю свой фрагмент
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.refresh -> {
if(Constants.checkConnectivity(requireContext())){
requireActivity().supportFragmentManager.beginTransaction().detach(this).attach(this).commit()
} else {
requireContext().ShowToast(requireContext(),"Please Check Your Internet..")
}
}
}
return true
}
- Это макет, содержащий все представления моего адаптера
<layout 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">
<data>
<variable
name="listener"
type="taki.eddine.premier.league.pro.uilisteners.RssListener" />
<variable
name="newsModel"
type="taki.eddine.premier.league.pro.models.NewsModel" />
</data>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="16dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="?attr/selectableItemBackground"
android:onClick="@{() -> listener.RssArticle(newsModel)}">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="match_parent"
android:layout_height="140dp"
android:layout_margin="8dp"
android:layout_marginTop="5dp"
app:layout_constraintBottom_toTopOf="@ id/guideline7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:rssimg="@{newsModel.newsBanner}"/>
<TextView
android:id="@ id/newstitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:fontFamily="@font/andada"
android:maxLines="2"
android:text="@{newsModel.newsTitle}"
android:textColor="@android:color/black"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@ id/guideline14"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@ id/guideline7"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="@ id/newsdescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:fontFamily="@font/adamina"
android:maxLines="3"
android:text="@{newsModel.newsDescription}"
android:textColor="@android:color/black"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@ id/guideline15"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@ id/guideline14"
app:layout_constraintVertical_bias="0.0" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginTop="11dp"
android:layout_marginStart="8dp"
android:src="@drawable/ic_baseline_date_range_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@ id/guideline22"
app:layout_constraintHorizontal_bias="0.842"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@ id/guideline15" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginEnd="16dp"
android:fontFamily="@font/andada"
android:textStyle="bold"
android:textSize="11sp"
android:textColor="@android:color/holo_blue_dark"
android:layout_marginTop="15dp"
android:text="@{newsModel.newsDate}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@ id/guideline22"
app:layout_constraintTop_toTopOf="@ id/guideline15" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</layout>
- Это мой макет фрагмента
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@ id/newsprogress"
android:visibility="visible"
android:layout_gravity="center"/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@ id/newsrcycler"
android:scrollbars="vertical"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Ответ №1:
Кажется, вы устанавливаете RecyclerView
адаптер несколько раз в цикле while. Это будет продолжать обновлять RecyclerView
.
Вы не должны заменять весь адаптер, так как данные меняются. Данные должны храниться внутри адаптера, и они должны обновляться внутри адаптера.
Как я пришел к такому выводу:
getData()
содержитwhile()
цикл.- В этом цикле while в последней вызываемой ветке
CoroutineScope(Dispatchers.Main).launch {}
- При этом
launch {}
вы вызываетеbinding.newsrcycler.adapter = LeagueNewsAdapter()
.
Комментарии:
1. Спасибо за ваш ответ, так вы думаете, я должен вынуть свой адаптер из блока цикла while и установить его после цикла while?
2. Да! Затем адаптер может иметь изменяемый массив, данные которого вы можете изменять. После того, как вы закончите изменять все данные, затем вызовите
adapter.notifyDataSetChanged()
адаптер. Это приведет к обновлению представления.3. Спасибо, приятель, я действительно вывел фрагмент кода адаптера из цикла, и он работает, помощь оценена