Пользовательский интерфейс мигает после нажатия обновления

#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. Спасибо, приятель, я действительно вывел фрагмент кода адаптера из цикла, и он работает, помощь оценена