I'm trying to achieve an Instagram style comment section. I have a collection group query /comments and can display comments just fine with RecyclerView.
Inside of the parent FirestoreRecyclerAdapter onBindViewHolder I have this.
DocumentSnapshot snapshot = getSnapshots().getSnapshot(holder.getAdapterPosition());
String commentId = snapshot.getId();
System.out.println("[CommentID: ]" + commentId);
Query rQuery = mFirestore.collectionGroup("comments")
.whereEqualTo("postId", commentId)
.orderBy("timestamp", Query.Direction.DESCENDING)
.limit(50);
FirestoreRecyclerOptions<SubCommentModel> options = new FirestoreRecyclerOptions.Builder<SubCommentModel>()
.setQuery(rQuery, SubCommentModel.class).build();
RecyclerView replyRecycler = holder.reply_recycler;
rAdapter = new FirestoreRecyclerAdapter<SubCommentModel, ReplyTypeViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull ReplyTypeViewHolder holder, int position, #NonNull SubCommentModel model) {
final SimpleDateFormat FORMAT = new SimpleDateFormat(
"MM/dd/yyyy", Locale.US);
((ReplyTypeViewHolder) holder).author_name.setText(model.getAuthor());
((ReplyTypeViewHolder) holder).comment_text.setText(model.getComment());
((ReplyTypeViewHolder) holder).time_stamp.setText(FORMAT.format(model.getTimestamp()));
}
#NonNull
#Override
public ReplyTypeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment_item, parent, false);
return new ReplyTypeViewHolder(view);
}
Outside of this block, I set replyRecycler to the nested adapter; I set up Linear Layout Manager and start listening.
However this does nothing. In fact doing addSnapShotLinstener to cQuery returns nothing. No error and no data.
Related
so I have an application that is as follows:
login page where the user enters his credentials and can access the main app if his credentials are correct. and if he checks the remember me checkbox, his username and password will be saved in shared preferences so that he can directly go to the main app in the second time.
the main app has a tabbed layout with a viewpager. in one of the tabs, which is a fragment, I use a recyclerview to display data, that I get from a database, in rows.
now in each row there is a reply button that will show details corresponding to each row when clicked. the details will be shown in a new fragment.
so the point is that I managed to replace the tab's fragment with the new fragment using this code in the recyclerview's adapter:
public class recyclerviewAdapter : RecyclerView.Adapter
{
// Event handler for item clicks:
public event EventHandler<int> ItemClick;
List <summary_request> summary_Requests=new List<summary_request>();
//Context context;
public readonly stores_fragment context;
public recyclerviewAdapter(stores_fragment context, List<summary_request> sum_req)
{
this.context = context;
summary_Requests = sum_req;
}
public override RecyclerView.ViewHolder
OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.recycler_view_data, parent, false);
recyclerview_viewholder vh = new recyclerview_viewholder(itemView, OnClick);
return vh;
}
public override void
OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
recyclerview_viewholder vh = holder as recyclerview_viewholder;
vh.by_user.Text = summary_Requests[position].By;
vh.warehousename.Text = summary_Requests[position].warehousename;
vh.project.Text = summary_Requests[position].project;
vh.operations_note.Text = summary_Requests[position].destination_Note;
vh.source_Note.Text = summary_Requests[position].source_Note;
vh.stockType.Text = summary_Requests[position].stockType;
vh.requestStatus.Text = summary_Requests[position].requestStatus;
vh.reply.Click += delegate
{
summary_detail_req fragment = new summary_detail_req();
var fm = context.FragmentManager.BeginTransaction();
fm.Replace(Resource.Id.frameLayout1, fragment);
fm.AddToBackStack(null);
fm.Commit();
int nb = context.FragmentManager.BackStackEntryCount;
Toast.MakeText(context.Context, nb.ToString(), ToastLength.Long).Show();
};
}
private void Reply_Click(object sender, EventArgs e)
{
Toast.MakeText(context.Context, "reply" , ToastLength.Long).Show();
}
public override int ItemCount
{
get { return summary_Requests.Count; }
}
// Raise an event when the item-click takes place:
void OnClick(int position)
{
if (ItemClick != null)
ItemClick(this, position);
}
}
but my context.FragmentManager.BackStackEntryCount remain zero! I don't get it. in my main activity, I am using this code for the backpress function:
stores_fragment.recyclerviewAdapter adapter;
public override void OnBackPressed()
{
string userName = pref.GetString("Username", String.Empty);
string password = pref.GetString("Password", String.Empty);
if (userName != String.Empty || password != String.Empty && adapter.context.FragmentManager.BackStackEntryCount == 0)
{
this.FinishAffinity();
}
else
base.OnBackPressed();
}
but i'm not getting what i want. this function is getting me out of the whole app.the first part of the if statement is because without it, when the I press the back button from the main activity it takes me back to the login page and I don't want that.
my question is what should I do to manage my fragments and the backpress function?
thanks in advance.
so the point is that I managed to replace the tab's fragment with the new fragment using this code in the recyclerview's adapter
According to your description, you want to open another fragment from recyclerview Button.click, if yes, please take a look the following code:
on OnBindViewHolder
int selectedindex;
// Fill in the contents of the photo card (invoked by the layout manager):
public override void
OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
selectedindex =position;
PhotoViewHolder vh = holder as PhotoViewHolder;
// Set the ImageView and TextView in this ViewHolder's CardView
// from this position in the photo album:
vh.Image.SetImageResource(mPhotoAlbum[position].PhotoID);
vh.Caption.Text = mPhotoAlbum[position].Caption;
vh.btnreply.Click += Btnreply_Click;
}
To show detailed activity. MainActivity is the current activity for recyclerview.
private void Btnreply_Click(object sender, EventArgs e)
{
Showdetailed(selectedindex);
}
private void Showdetailed(int position)
{
var intent = new Intent();
intent.SetClass(MainActivity.mac, typeof(DetailsActivity));
intent.PutExtra("selectedid", position);
MainActivity.mac.StartActivity(intent);
}
The detailedactivity.cs:
public class DetailsActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
var index = Intent.Extras.GetInt("selectedid", 0);
var details = DetailsFragment.NewInstance(index); // Details
var fragmentTransaction = FragmentManager.BeginTransaction();
fragmentTransaction.Add(Android.Resource.Id.Content, details);
fragmentTransaction.Commit();
}
}
The DetailsFragment.cs:
public class DetailsFragment : Fragment
{
public int ShownPlayId => Arguments.GetInt("selectedid", 0);
public static DetailsFragment NewInstance(int index)
{
var detailsFrag = new DetailsFragment { Arguments = new Bundle() };
detailsFrag.Arguments.PutInt("selectedid", index);
return detailsFrag;
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
// return inflater.Inflate(Resource.Layout.YourFragment, container, false);
if (container == null)
{
// Currently in a layout without a container, so no reason to create our view.
return null;
}
var scroller = new ScrollView(Activity);
var text = new TextView(Activity);
var padding = Convert.ToInt32(TypedValue.ApplyDimension(ComplexUnitType.Dip, 4, Activity.Resources.DisplayMetrics));
text.SetPadding(padding, padding, padding, padding);
text.TextSize = 24;
Photo photo =PhotoAlbum.mBuiltInPhotos[ShownPlayId];
text.Text = photo.Caption;
scroller.AddView(text);
return scroller;
}
}
About implementing fragment, you can take a look:
https://learn.microsoft.com/en-us/samples/xamarin/monodroid-samples/fragmentswalkthrough/
I am busy with a book reader project for Android. I am using SQLite database. To get certain entries from certain chapters depending on switch/case, I am using an intent putextra/getextra which works just fine to get just entries and populate the standard array adapter. However, I need the items numbered.
I have created a custom adapter (EntryAdapter) to show the line numbers as follows:
entry
entry
entry
and so on... in the list view
The problem is that the customer adapter is passes the entire chapter to each list item view over and over. Without the customer adapter (and using a standard array adapter with the standard simple_list_item) it passes one line per list item as it is supposed to, however, I need the lines numbered... thus the custom adapter... How do I get the entries to pass properly... only one entry per list item while still having the lines numbered? Any help would be appreciated.
Here is a sample of the Activity that populates the listview...
public class ChapterActivity extends AppCompatActivity{
private ListView mListView;
private EntryAdapter mAdapter;
static List<String> mChapterEntries;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chapter_entries);
this.mListView = (ListView) findViewById(R.id.listView);
Integer chapterSelectedOne = getIntent().getIntExtra("chapter", 0);
final DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
switch (chapterSelectedOne) {
case 0:
databaseAccess.open();
mChapterEntries = databaseAccess.getEntriesChapterOne();
databaseAccess.close();
mAdapter = new EntryAdapter(this, R.layout.entry_list_item, mChapterEntries);
this.mListView.setAdapter(mAdapter);
break;
case 1:
databaseAccess.open();
mChapterEntries = databaseAccess.getEntriesChapterTwo();
databaseAccess.close();
mAdapter = new EntryAdapter(this, R.layout.entry_list_item, mChapterEntries);
this.mListView.setAdapter(mAdapter);
break;
case 2:
databaseAccess.open();
mChapterEntries = databaseAccess.getEntriesChapterThree();
databaseAccess.close();
mAdapter = new EntryAdapter(this, R.layout.entry_list_item, mChapterEntries);
this.mListView.setAdapter(mAdapter);
break;
case 3:
databaseAccess.open();
mChapterEntries = databaseAccess.getEntriesChapterFour();
databaseAccess.close();
mAdapter = new EntryAdapter(this, R.layout.entry_list_item, mChapterEntries);
this.mListView.setAdapter(mAdapter);
break;
This is the custom adapter "EntryAdapter"....
class EntryAdapter extends ArrayAdapter<String> {
public EntryAdapter(Context context, int layout, List<String>
mChapterEntries) {
super(context, R.layout.entry_list_item, mChapterEntries);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull
ViewGroup parent) {
View listItem = convertView;
int pos = position +1;
if(listItem == null)
listItem =
LayoutInflater.from(getContext()).inflate(R.layout.entry_list_item,
parent, false);
TextView entryTextView = (TextView)
listItem.findViewById(R.id.chapterEntries);
verseTextView.setText(String.valueOf(pos)+ mChapterEntries);
return listItem;
}
}
I fixed it by using by using this:
verseTextView.setText(String.valueOf(pos)+ mChapterEntries.get(position));
instead of this:
verseTextView.setText(String.valueOf(pos)+ mChapterEntries);
Hope that helps someone else.
I have created the module for loading database record with id=1,2,3,4,5,... by getting the position of the viewPage Swiped as position index +1 . It has been implemented in OnPageChangeListener onPageSelected method. When it comes to the testing, it shows that the index shows zero at the beginning as 0,2,3,4 instead of index 1,2,3,4 ..to load the record. When I swipe right , it loads another same record instead of none, even setting setOffscreenPageLimit as zero. I don't want this to happen
Would you please tell me the alternative to read the position of the viewPager page ?
The below is my working :
mViewPager = (CustomViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setEnabled(true);
mViewPager.setOffscreenPageLimit(0);
mViewPager.setOnPageChangeListener(viewPagerPageChangeListener);
mViewPager.setCurrentItem(0);
OnPageChangeListener viewPagerPageChangeListener = new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
pageId = position + 1;
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
final Animation animationFadeIn = AnimationUtils.loadAnimation(FlightBankActivity.this, R.anim.fade_in);
for (int i = 0; i < dotsCount; i++) {
dots[i].setImageResource(R.drawable.dot_e);
}
dots[position].setAnimation(animationFadeIn);
dots[position].setImageResource(R.drawable.dot_s);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
ArrayList<FlightProfile> fpList = (ArrayList<FlightProfile>) DatabaseManager.getInstance().getAllFlightProfile();
System.out.println(fpList.size() + " : is the size of profile");
for(FlightProfile gfg : fpList){
System.out.println(gfg.getId()+ " is the profile id");
System.out.println(gfg.getName()+ " is the profile i]name");
}
System.out.println(pageId+ " : is the pageId");
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
};
Fragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle bundle=getArguments();
final int type = bundle.getInt("type");
System.out.println("type :" + type);
fp = DatabaseManager.getInstance().getFlightProfile(pageId);
...
I have 3 ListFragments being handled by a viewPager (managed by a FragmentAdapter) - they work perfectly. Now when the user clicks an item in ListFragment #1, a new Fragment should open with the details. It's behaving strangely in the following manner:
Only clicking a list item twice opens the DetailFragment, yet debugging shows the first click indeed goes into the DetailFragment, but doesn't show the view (the view still shows the current ListFragment).
After clicking the 2nd time, the DetailFragment does show it's layout, but not the elements within it (like TextView, etc).
If the user 'accidently' swipes the screen when DetailFragment is showing, the viewPager sets it in place of the 2nd ListFragment! Only when pressing back on the DetailFragment view will 'reset' the viewPager to it's correct ListFragment. Of course if the user swipes when in a DetailFragment, the next ListFragment of the viewPager should appear, and the DetailFragment should be removed.
Thanks for any tips muddling through Android's odd world of fragments and views :)
public class PlanetFragment extends ListFragment{
LayoutInflater inflater;
ListView list;
ArrayList<HashMap<String, String>> planetListArray;
HashMap<String, String> planetMap;
Activity activity;
Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.planets_tab_layout, container, false);
inflater=(LayoutInflater)getLayoutInflater(savedInstanceState);
activity = getActivity();
context = PlanetFragment.this.getActivity();
String dbTableName = "Table_Planets";
SQLiteHelper info = new SQLiteHelper(getActivity().getBaseContext());
info.open();
ArrayList<HashMap<String, String>> datafromSQL = info.getData(dbTableName);
if(!datafromSQL.isEmpty()){
planetListArray = new ArrayList<HashMap<String, String>>();
for (int i = 0; i<datafromSQL.size(); i++){
planetMap = new HashMap<String, String>();
planetMap.put(PLANET_ID, datafromSQL.get(i).get(KEY_PLANET_ID));
planetMap.put(ZODIAC_ID, datafromSQL.get(i).get(KEY_ZODIAC_ID));
planetMap.put(DEGREES, datafromSQL.get(i).get(KEY_DEGREES));
planetMap.put(CONTENT, datafromSQL.get(i).get(KEY_CONTENT));
planetListArray.add(planetMap);
}
info.close();
}
list = (ListView) v.findViewById(android.R.id.list);
PlanetAdapter adapter=new PlanetAdapter(getActivity(), R.layout.planets_row, planetListArray);
list.setAdapter(adapter);
return v;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//the dividers
getListView().setDivider(getResources().getDrawable(R.drawable.purplebartop));
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
HashMap<String, String> item = planetListArray.get(position);
Bundle bundle = new Bundle();
bundle.putSerializable("itemMap", item);
bundle.putInt("position", position);
Fragment frag = DetailFragment.newInstance();
frag.setArguments(bundle);
if (frag != null) {
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.pager, frag, "frag")
.addToBackStack("frag")
.commit();
}
}
}
public class DetailFragment extends Fragment{
Context context;
Activity activity;
TextView planetName;
public static android.support.v4.app.Fragment newInstance() {
DetailFragment f = new DetailFragment();
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
inflater=(LayoutInflater)getLayoutInflater(savedInstanceState);
View v = inflater.inflate(R.layout.dialog_details, container, false);
activity = getActivity();
context = DetailFragment.this.getActivity();
planetName = (TextView)v.findViewById(R.id.planetNameExpanded);
planetName.setText("planetX");
return v;
}
}
EDIT:
Instead of getActivity().getSupportFragmentManager() I have also tried getChildFragmentManager() but it always gives the error: The method getChildFragmentManager() is undefined for the type PlanetFragment.
When you click on a list item, you are indeed constructing a new details fragment and telling the fragment manager to replace the tag "frag" with that fragment. However, you are not telling the view pager to switch over to that fragment.
Since you already have a back-pointer to your activity, you could use findViewById to find your view pager, and then call viewPager.setCurrentItem.
I think you might be asking for trouble by constructing a new details fragment inside of the list fragment. When you use a FragmentPagerAdapter, the adapter usually constructs the fragments. I would have implemented this by letting the adapter make the fragments, and then in your onListItemClick find the existing details fragment and call a method on it to configure it with the new data. But maybe just the setCurrentItem will fix your problem.
EDIT
First, I would write your FragmentPagerAdapter so you can use getItem to fetch the existing fragment, without creating a new one each time.
public class PlanetFragmentAdapter extends FragmentPagerAdapter {
private Fragment [] fragments = new Fragments[3];
public PlanetFragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 3;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = fragments[position];
if (fragment == null) {
switch (position) {
case 0:
fragment = new PlanetFragment();
break;
case 1:
fragment = new DetailFragment();
break;
case 2:
fragment = new MysteryFragment();
break;
}
fragments[position] = fragment;
}
return fragment;
}
}
Also add functions in your activity to work with your fragments:
public void setPage(int position) {
viewPager.setCurrentItem(position);
}
public DetailFragment getDetailFragment() {
return (DetailFragment) viewPager.getItem(1); // now it doesn't create a new instance
// you could also use getSupportFragmentManager().findFragmentById() here
}
Now when you click on an item in your list fragment, you can get the existing detail fragment, configure it, and set the ViewPager to show the detail fragment.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
HashMap<String, String> item = planetListArray.get(position);
Bundle bundle = new Bundle();
bundle.putSerializable("itemMap", item);
bundle.putInt("position", position);
PlanetActivity pa = (PlanetActivity) activity;
DetailFragment frag = pa.getDetailFragment();
frag.setArguments(bundle);
pa.setCurrentItem(1);
}
I'm using the Android Studio provided class for a tabbed activity that uses Action Bar Tabs with ViewPager. Inside this activity, I'm trying to initialize a RecyclerView with data from a Firebase database.
Problem: On the app's first run, the RecyclerView is empty as shown below.
If I close and reopen the application from within the emulator, my RecyclerView gets populated as it should, as shown below.
Any ideas as to why this might be happening? I have a theory but I haven't been able to find a solution. After trying to read the FragmentPagerAdapter page, I got the impression that the fragments must be static (I don't know what the implications of this might be, so if anyone can shed some light on this it would be appreciated). On the app's first run, it initializes the RecyclerView. It then adds the data from the Firebase database but since the RecyclerView has already been initialized it is empty and is never properly updated. I tried calling the notify... methods to no avail.
StudentFragment's onCreateView method:
private View view;
private Context c;
private RecyclerView mRecyclerView;
private LinearLayoutManager manager;
private Firebase mFirebaseRef;
private FirebaseRecyclerAdapter<Student, ViewHolder> firebaseRecyclerAdapter;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_students, container, false);
mFirebaseRef = new Firebase("<your Firebase link here>");
c = getContext();
//Initializes Recycler View and Layout Manager.
mRecyclerView = (RecyclerView) view.findViewById(R.id.studentRecyclerView);
manager = new LinearLayoutManager(c);
mRecyclerView.setHasFixedSize(true);
firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter<Student, ViewHolder>(
Student.class,
R.layout.single_student_recycler,
ViewHolder.class,
mFirebaseRef
) {
#Override
protected void populateViewHolder(ViewHolder viewHolder, Student student, int i) {
viewHolder.vFirst.setText(student.getFirst());
viewHolder.vLast.setText(student.getLast());
viewHolder.vDue.setText(Double.toString(student.getCurrentlyDue()));
viewHolder.vRadio.setButtonTintList(ColorStateList.valueOf(Color.parseColor(student.getColor())));
Log.d(TAG, "populateViewHolder called");
}
};
mRecyclerView.setAdapter(firebaseRecyclerAdapter);
mRecyclerView.setLayoutManager(manager);
return view;
}
ViewHolder:
public static class ViewHolder extends RecyclerView.ViewHolder {
public final TextView vFirst;
public final TextView vLast;
public final TextView vDue;
public final RadioButton vRadio;
public ViewHolder(View itemView) {
super(itemView);
vFirst = (TextView) itemView.findViewById(R.id.recycler_main_text);
vLast = (TextView) itemView.findViewById(R.id.recycler_sub_text);
vRadio = (RadioButton) itemView.findViewById(R.id.recycler_radio_button);
vDue = (TextView) itemView.findViewById(R.id.recycler_due_text);
}
Homescreen's onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homescreen);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
Firebase context is set on another application that starts as soon as the Homescreen activity starts. Any help will be appreciated.
Edit: I was digging through the FirebaseUI GitHub page, which is where the problem most likely lies, and found another user with the exact same problem. It seems that onBindViewHolder isn't called after notifyItemInserted in the FirebaseRecyclerAdapter class. Now to fix it...
In my case this was caused by mRecyclerView.setHasFixedSize(true); If you comment out this line of code the list loads properly. I got my solution from this discussion: https://github.com/firebase/FirebaseUI-Android/issues/204
Let me try, as you say on the question title,
RecyclerView not displaying on application start
so, the
Initializes Recycler View and Layout Manager.
should be declared on the onStart
#Override
public void onStart() {
super.onStart();
mFirebaseRef = new Firebase("<your Firebase link here>");
firebaseRecyclerAdapter = ...
//and so on
Hope it helps!
firebaseRecyclerAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = firebaseRecyclerAdapter.getItemCount();
int lastVisiblePosition =
linearLayoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the
// user is at the bottom of the list, scroll to the bottom
// of the list to show the newly added message.
if (lastVisiblePosition == -1 ||
(positionStart >= (friendlyMessageCount - 1) &&
lastVisiblePosition == (positionStart - 1))) {
linearLayoutManager.scrollToPosition(positionStart);
}
}
});
recyclerListIdeas.setAdapter(firebaseRecyclerAdapter);
** Just add Recyclerview.AdapterDataObserver() . worked for me ! hope it helps :)**
i had the same issue, check the documentation:
https://codelabs.developers.google.com/codelabs/firebase-android/#6
fixed it by adding a data observer:
mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = mFirebaseAdapter.getItemCount();
int lastVisiblePosition =
mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the
// user is at the bottom of the list, scroll to the bottom
// of the list to show the newly added message.
if (lastVisiblePosition == -1 ||
(positionStart >= (friendlyMessageCount - 1) &&
lastVisiblePosition == (positionStart - 1))) {
mMessageRecyclerView.scrollToPosition(positionStart);
}
}
});