How to refresh screen smoothly onResume in Kotlin? - android

I get data from fireStorage and draw RecyclerView with those data.
That is function getData().
I also have tabLayout on top of screen, so I click tabItem, I need to run this getData() in order to get new data, since it can have some change in DB.
So I clear recyclerview item array and run getData in onResume.
override fun onResume() {
super.onResume()
diaryItems.clear()
getData()
}
But whenever I click tabItem, screen flickers.
Is there any way to refresh screen more smoothly?

Related

How to change item position of a recycle view from within its adapter?

Is it possible to change the item from within the adapter itself?
What am I trying to a achieve?
I have created a simple recycler view and it has a simple list item, but when the user clicks on the item a bottom sheet dialog gets displayed (that bottom sheet is being created in the adapter itself so it's different for every item) that bottom sheet dialog have a back and next button which can allow the user to move back and forth through the item view
When the user clicks on item -> bottom sheet dialog gets displayed -> if he presses next I have to show next following item with its bottom sheet opened.
How can I move from I item to another within the adapter?
you can pass position and list item as ArrayList to bottom sheet and update UI on next and previous buttons.
for example, you can create a method in your bottom sheet to update bottom sheet UI:
var listItem = ArrayList<Objects>()
var position = 0
private fun updateUi() {
val item = listItem[position]
///update ui with item
}
on next button click:
position += 1
if (position == listItem.size)
{
// end of list
} else
{
updateUi()
}
and on pervious button click:
position -= 1
if (position == -1)
{
// end of list
} else
{
updateUi()
}
RecyclerView has a couple of convenience methods, scrollToPosition and smoothScrollToPosition (the latter needs a little setup, check the link). You can use these to change the current item being displayed.
That requires having a reference to the RecyclerView though, which your Adapter doesn't have (or at least, it doesn't expose it). There's a callback when on starts observing the adapter though. So you could store that reference when you get it (but don't hold onto it when the equivalent onDetached callback happens)
Personally I'd want to separate all these things out, have them coordinated by the containing fragment, or some other component. So instead of one component (the adapter) managing what other components are doing and showing, it just calls a function saying "hey this item got clicked" and what happens as a result is none of its concern.
There's lots of ways to coordinate that, but it keeps things neater if you can separate that functionality. When one thing that has a specific job (displaying items and handling clicks) starts doing other stuff (messing with other UI components, handling stuff they do) it can start getting complex. Up to you but it's worth thinking about!
Thanks to everyone who shared their ideas.
Here is what I finally did
created an interface within the adapter
implemented that interface in the fragment which was starting the adapter
when the user press the next or previous button, I dismiss the current bottom sheet and then I call the function in the interface and also pass it the position of either next to or previous item
When the implemented function gets called in the fragment, first I move the list to that position second i get the item on that positon and third call perform on click on that item and it displayed the bottom sheet of that item
here is the fun which get called in fragment
override fun onAddIconClick(position: Int) {
surveyBinding.surveyRecV.scrollToPosition(position)
val v: View? = surveyBinding.surveyRecV.layoutManager?.findViewByPosition(position)
if(v != null) {
v.findViewById<ImageView>(R.id.viewAddIcon).performClick()
val temp = v.findViewById<TextView>(R.id.viewMainTitle)
Log.i("here22" , temp.text.toString())
}
}

RecyclerView scrolls to the top when I open another activity

I have a RecyclerView in my Fragment. When I open another activity, then hit back and go to the initial activity/fragment, the RecyclerView is now scrolled to the top of the list.
I'm initiating my RecyclerView inside of onCreate method, and when I navigate to another activity and come back, only onStop (and the once after obviously) get called.
I even tried saving the state of the LinearLayout manager
override fun onStop() {
super.onStop()
rcerecylerViewState = myRecyclerView.layoutManager?.onSaveInstanceState()
}
override fun onStart() {
super.onStart()
if(rcerecylerViewState != null){
myRecyclerView.layoutManager?.onRestoreInstanceState(newsFeedViewModel.rcerecylerViewState)
}
}
I dont want to clutter this post by including my whole layout and fragment file. Please let me know which part of the code I should include to further clarify.
No need to do anything in onStart.
Move your onStart code into your onCreate.
Pseudocode looks like this.
if (recyclerview != null)
// restoredata
else
// initial set up.

fragment does not reflect changes

I am trying to create an application in which my Fragment contains one listview which is populated from a database, and when one of the item is clicked, a new activity starts.
In this new activity, I update the database, and then come back to the first Fragment (by pressing back button).
What happens next is that the ListView in the first Fragment does not take the changes I made in the second Activity into account.
And strange thing is that when I start the application again, the Fragment shows the updated list.
How can I automatically update the ListView when making changes to the database?
Try to use the onResume( ) method in your Fragment, so you can told the Adapter that the Dataset has changed.
#Override
protected void onResume() {
super.onResume();
// Dataset has changed, notify adapter !
mAdapter.notifyDataSetChanged();
}

Changing reenter animation to another item of a list

I have a RecyclerView with images and when I press an image the app opens another activity that contains a ViewPager with the same images but in the position of the one I selected.
I've done the transition in Lollipop to share this image between activities using supportPostponeEnterTransition and supportStartPostponedEnterTransition in the called activity to wait until the viewPager is loaded with images to start the transition.
When I enter in the called activity and when I press back the transitions are ok.
The problem I'm facing is if I move to another image in the ViewPager of the called activity, when I press back it animates the image that it was selected at the beginning, not the currently selected one.
I've been able to change the animated image to the one selected in the called activity with this:
#Override
public void onBackPressed() {
View view = ((ImageDetailFragment) adapter.getFragment(viewPager,
viewPager.getCurrentItem())).getTransitionView();
ViewCompat.setTransitionName(view, Constants.TRANSITION_IMAGE);
super.onBackPressed();
}
But it is returning to the same position of the original image in the list of the calling activity.
How can I do it to make the image return to its position in the list of the calling activity?
The first thing to do is to make sure that the views work properly without any Activity transition. That is, when your return from Activity with the ViewPager, the RecyclerView Activity should be showing the View that the ViewPage was showing. When you call the ViewPager activity, use startActivityForResult and use the result to scroll the RecyclerView to the correct position.
Once that is working, the Activity Transition can be made to work. I know that you've given each View in your RecyclerView a different transitionName, right? When you bind the View, call setTransitionName and give it a repeatable name. Typically this is the image URL or cursor row ID or at worst some munged index like "image_" + index.
The next thing you need to do is set the SharedElementCallback for both the calling Activity (exit) and called activity (enter). In each, you're going to need to override the onMapSharedElements callback to remap the shared element.
#Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
// assuming just one shared element, excuse the ugly code
sharedElements.put(names.get(0), mSharedElement);
}
Here, mSharedElement has been set in the onActivityReenter in the calling (RecyclerView) activity and in onCreate and prior to finishAfterTransition (onBackPressed?) in the called (ViewPager) activity.
The onActivityReenter gives new functionality specifically for this case. You can look at the results there before the called Activity completes.

How to update a Fragment View in Android without changing the current state of the view?

Whenever I click on a refresh button on my fragment and get new set of data, I call this function:
public void updateView(User user){
LinkAdapter linkList = new LinkAdapter(getActivity(),R.layout.link_list,user.links, getActivity());
linkCardView.setAdapter(linkList);
}
This updates the view with new set of links at the top of it, and also drags the view up to the top to show the new links that have been added.
My only problem is I don't want the dragging up to happen. Say the user has scrolled to position B in a listView and then refreshes which results in new data added to the top of the listView, the current View state shouldn't be altered automatically. How do I stop this from happening?
Instead of creating a new adapter and setting it, when you update the content, I'm guessing user.links, make sure you update whatever array you sent into the adapter, then call notifyDataSetChanged() on the adapter.

Categories

Resources