Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
305 views
in Technique[技术] by (71.8m points)

kotlin - UI blink after loading

I made an app which loading data from "https://api.spacexdata.com/v3/launches" - saved data at DataBase (cache) and showing it in UI from another data class (repository). At UI i using Recyclerview. My problems is:

  1. When app is launched - after few seconds UI (OverviewFragment) is blink. For example: i launch app - then scroll down - UI blinked - and im again see top of list. Its happen only after app launch. If i go to second Fragment (DetailFragment) and then moving back to OverviewFragment - IU isnt blink - all is good. I checked with log all lifecycle statements - its working correctly - when i laucn app - UI (OverviewFragment) created only once. I think it mb recycler error or repository, but cannot find it - im new in kotlin. Help please.

  2. My second problem is that Glide isnt showing "ic_broken_image" when i have a null at image url property, i talking about ".fallback(R.drawable.ic_broken_image)"

Details: You can see/download app here https://github.com/bboykot/myRepo Bellow i write a some description for this app.

I loading data to "data class SpaceXProperty", after i mapping networkData with Database "data class SpaceEntity" using "fun List.asDatabaseModel()", then i mapping database data with "data class Models" (i using it at UI) with fun List.asDdomainModel(). After i showing with RecycleView data from "Models".

My mainFragment:

class OverviewFragment : Fragment() {

    private lateinit var viewModel: OverviewViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?): View? {


        val binding = FragmentOverviewBinding.inflate(inflater)

        binding.lifecycleOwner=this

        //block of creating viewModel and transfering parameters to him
        val application = requireNotNull(this.activity).application
        val dataSource = SpaceDatabase.getInstance(application).spaceDao
        val viewModelFactory = OverviewViewModelFactory(dataSource, application)
        viewModel = ViewModelProvider(this, viewModelFactory).get(OverviewViewModel::class.java)

        binding.viewModel = viewModel

        //recycler + moving to OverviewFrafment
        binding.photosGrid.adapter= SpaceXGridAdapter(SpaceXGridAdapter.OnClickListener { Models ->
           this.findNavController().navigate(OverviewFragmentDirections.actionOverviewFragmentToDetailFragment(Models))
        })


        //display network error
        viewModel.networkResponse.observe(viewLifecycleOwner, Observer {response->
            if (viewModel.networkResponse.value != "ok") {
                Toast.makeText(activity, "Network error", Toast.LENGTH_LONG).show()
            }
        })
        return binding.root
    }

}

Recycler adapter:

class SpaceXGridAdapter (private val onClickListener: OnClickListener): ListAdapter<Models, SpaceXGridAdapter.SpaceXPropertyViewHolder>(DiffCallback) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SpaceXPropertyViewHolder{

        return SpaceXPropertyViewHolder(GridViewItemBinding.inflate(
            LayoutInflater.from(parent.context)))
    }

    override fun onBindViewHolder(holder: SpaceXPropertyViewHolder, position: Int){
        val spaceXProperty = getItem(position)

        holder.itemView.setOnClickListener {
            onClickListener.onClick(spaceXProperty)
        }

        holder.bind(spaceXProperty)
    }

    companion object DiffCallback : DiffUtil.ItemCallback<Models>() {
        override fun areItemsTheSame(oldItem: Models, newItem: Models): Boolean {
            return oldItem === newItem
        }

        override fun areContentsTheSame(oldItem: Models, newItem: Models): Boolean {
            return oldItem.flightNumber == newItem.flightNumber
        }
    }


    class SpaceXPropertyViewHolder (private val binding: GridViewItemBinding): RecyclerView.ViewHolder(binding.root){
        fun bind(spaceXProperty: Models){
            binding.model=spaceXProperty
            binding.executePendingBindings()
        }
    }

    class OnClickListener(val clickListener:(models:Models)-> Unit ){
        fun onClick(models: Models) = clickListener(models)
    }
}

Glide and listadapter

@BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView, data: List<Models>?) {

    val adapter = recyclerView.adapter as SpaceXGridAdapter
    adapter.submitList(data)
}


@BindingAdapter("imageUrl")
fun bidImage(imgView: ImageView, imgUrl: String?){
    imgUrl?.let{
        val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()
        Glide.with(imgView.context)
            .load(imgUri)
            .apply(
                RequestOptions()
                .placeholder(R.drawable.loading_animation)
                .error(R.drawable.ic_broken_image))
                .fallback(R.drawable.ic_broken_image)
            .into(imgView)

    }
} 
question from:https://stackoverflow.com/questions/65874960/ui-blink-after-loading

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...