I have a Recyclerview which shows one detail card on full screen. Initially basic data loading is done when data is set in Adapter from one Main Api Call. when card is set on screen using PagerSnapHelper in centre, to show some specific details on detail card I want to make separate Api call to different Api endpoints and update the same POJO object for that particular Card. The trigger point for making the separate extra Api call fro details is when card is in Idle position hit and get data. This is working fine. The code is
binding.rvUserData.addOnScrollListener(
SnapOnScrollListener(
snapHelper,
SnapOnScrollListener.Behavior.NOTIFY_ON_SCROLL_STATE_IDLE,
object : OnSnapPositionChangeListener {
override fun onSnapPositionChange(position: Int) {
val getData = viewModel.getExtraUserDetails()
val currentUserData: UserData? = adapter?.getCurrentData()?.get(position)
currentUserData.userPreferences = getData.preferences
currentUserData.userSkills = getData.skills
adapter?.updateData(position,currentUserData)
}
})
)
This is working fine. But suppose the Card has already done the extra details Api Call and set the data in onBindViewHolder it again call the same when we scroll to same position. How to skip the extra unnecessary Api call when data is already set on Recyclerview card and only make a call for extra data when Card is recycled etc or does not have extra data to show full details.
Use Case:
Card-1 displayed (extra Api calls made and data is set)
Scroll to next Card-2 (extra Api calls made and data is set)
Scroll again to Card-1 (again extra Api calls made and data is set)
How to make sure it should make Api calls when necessary ? How to resolve this ? It would be of great help, thanks
I'm new to all of this and was making good progress but I have hit a brick wall with working out how to do the next thing. I am using Kotlin and have a Fragment with an associated Recyclerview Adapter. I would like to set OnClick (On or Off) against items in a row depending upon a value in the Fragment which could change at any time.
My adapter works fine to show and update the array of data and also to implement OnClick.
I have tried sending a data element via a constructor which changed in the fragment but always showed as the initial setting in the adapter. The same with trying to call a method.
Many other questions touch on the issue but only show snippets of code, and it seems that I'm not advanced enough to get them working successfully in my code.
Could anyone please provide a pointer to a working set of Kotlin code that includes parsing a variable from fragment to adapter - perhaps in Git or a tutorial. I'm sure that if I can study a working program I can move forward. Thank you.
It would have been better if you had included your Adapter and Fragment code in the question, that would have helped us in understanding how you have setup everything and what data model are you passing to adapter.
But looking at your question, one solution that comes to my mind is to add an enabled boolean in your data model that is displayed in the ViewHolder. Using this you can set view.clickable = model.enabled. Now whenever your "value in the Fragment" changes you can update this list and let the adapter rebind items.
Note that the above solution is when you want to selectively enable/disable clicks on individual items. If you want to do this for all items at once, it's better to create a variable in adapter that you can change from the Fragment, and inside the clickListener you can check the value of that adapter variable. If it's false, just return out of the click listener. Something like,
view.setOnClickListener {
if(adapterValue) {
// handle Click
}
}
If this approach doesn't help, I would ask you to add more context in your question and show what you have done so far.
According Firebase Android SDK Release Notes with 9.8 update we have screen tracking support with android screens and activities... The documentation says that this event works like that:
mFirebaseAnalytics.setCurrentScreen(activity,class_name,class_override_name);
In my case, I don't need overrides class name and I send null value... But i'm waiting 48h and my firebase analytics console doesn't show info about this event, any ideas?
Thanks in advance!
Another very important thing that I've noticed only after two days of intensive struggling: the setCurrentScreen method MUST be called on the UI thread.
I was only able to see that after looking for a light in the Firebase decompiled code:
#MainThread
#Keep
public final void setCurrentScreen(#NonNull Activity var1, #Size(min = 1L,max = 36L) #Nullable String var2, #Size(min = 1L,max = 36L) #Nullable String var3) {
//...
}
Whenever this method is called a event of type screen_view is logged.
And keep in mind the Firebase size restrictions. The maximum size of a screen name is 36 characters long.
First I had the same question: where is my event with current screen name on the Firebase dashboard?
I've called method mFirebaseAnalytics.setCurrentScreen(this, "MainActivity", null); with no result.
Thanks to the comment by Benoit I realized that this method indicates the value of implicit parameter that is automatically attached to any event you send.
That means it's not independent event, it's a parameter that will stick to all your events since you set it.
This will be useful if you have changing screens within single Activity. For example when you have multiple fragments with one hosting Activity. And you call this method in each fragment in onResume().
If you want to have distinct metric with the name of your screen - fire explicitly a new event for that.
Bundle params = new Bundle();
params.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, "screen");
params.putString(FirebaseAnalytics.Param.ITEM_NAME, "MainActivity");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.VIEW_ITEM, params);
val bundle = Bundle()
bundle.putString(FirebaseAnalytics.Param.SCREEN_NAME, "YOUR SCREEN NAME")
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle)
Also Firebase Analytic's screen tracking is automatic. No need for explicit separate event tracking.
Sets the current screen name, which specifies the current visual context in your app. This helps identify the areas in your app where users spend their time and how they interact with your app.
Note that screen reporting is enabled automatically and records the class name of the current Activity for you without requiring you to call this function. The class name can optionally be overridden by calling this function in the onResume callback of your Activity and specifying the screenClassOverride parameter.
If your app does not use a distinct Activity for each screen, you should call this function and specify a distinct screenName each time a new screen is presented to the user.
The name and classOverride remain in effect until the current Activity changes or a new call to setCurrentScreen is made. I will try to add this method to onResume Method. I do not know the result but i will share my experience.
firebaseAnalytics.setCurrentScreen(activity,screeenName,activity.getClass().getSimpleName());
firebaseAnalytics.setMinimumSessionDuration(100L);
params = new Bundle();
params.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, "screen");
params.putString(FirebaseAnalytics.Param.ITEM_NAME, screeenName);
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.VIEW_ITEM, params);
Try using setCurrentScreen as well as manual event fire as firebase doesn't send data immediately to the console...but if event is fired up..all the remaining data is sent to firebase..
Just call that method in onResume(), and check the tracking through DebugView. it worked for me.
Check out the documentation.
My current Android application uses Firebase to store user data.
My data has the following "structure" (and/or levels)
my-android-app.firebaseio.com/level0/level1/UUID1/UUID2
data objects are stored at UUID2 that resemble this
{
"Students":[
{
"Name":"Amit Goenka",
"Major":"Physics"
},
{
"Name":"Smita Pallod",
"Major":"Chemistry"
},
{
"Name":"Rajeev Sen",
"Major":"Mathematics"
}
]
}
I need to be able to detect when child data is added, removed or changed etc
below (at) UUID2, however I only want to set up my ChildEventListener using this path
android-app.firebaseio.com/level0/level1
is this possible?
During my test so far I have had to specify the full path of:-
my-android-app.firebaseio.com/level0/level1/UUID1/UUID2
Firebase will fire a child_* event for any change under the level where you register the correct listener. But it will only fire child_added/child_removed for nodes added/removed directly under the level where you registered. For other changes, it will fire child_changed and possibly child_moved.
Your options:
flatten the tree
listen to value events
listen to all child_ events and figure out the changes
I have implmented pagination and it display 5 records per page. Now suppose I am on page 3 and click 3'rd element then 3'rd element of page-1 is selected.
I am not able to figure out problem as I always create new list object while setting data.
I used below code
temp = new ArrayList();
this.someListAdapter = new SomeListAdapter(this, R.layout.row_facet,temp);
setListAdapter(this.someListAdapter );
Below is signature of SomeListAdapter class.
public class SomeListAdapter extends ArrayAdapter<VoNeighborhood> {
}
Please help....
There really aren't enough details here about how you do pagination with your ListView.
So I might guess you're overriding onListItemClick and using the position variable it sends you, but you then don't take into account the page you're on?
Alternatively, just don't use pagination as you have an infinite canvas to scroll your list within — I don't think I've recall seeing an Android app so far that uses pagination!