3

Everytime we open the activity that bares the recycler adapter it fails to load on the first try. Exiting the activity and re-entering fixes the problem. Here is a gif for example. https://gyazo.com/32dc664dd427ef1129704a09861a3708

The Item i am spawning in:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:card_view="http://schemas.android.com/tools"
    android:id="@+id/show_chat_single_item_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="70dp"

        app:cardBackgroundColor="#dcdada"
        app:cardCornerRadius="0dp"
        app:contentPadding="3dp"
        card_view:cardCornerRadius="5dp"
        card_view:cardElevation="2dp"
        card_view:cardUseCompatPadding="true">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/chat_persion_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginLeft="8dp"
                android:layout_marginTop="8dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@mipmap/ic_launcher" />

            <TextView
                android:id="@+id/chat_persion_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="0dp"
                android:text="Name"
                android:textSize="18sp"
                android:textStyle="bold"
                app:layout_constraintLeft_toRightOf="@+id/chat_persion_image"
                app:layout_constraintTop_toTopOf="@+id/chat_persion_image" />

            <TextView
                android:id="@+id/chat_persion_email"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="0dp"
                android:layout_marginTop="8dp"
                android:text="Email"
                app:layout_constraintLeft_toLeftOf="@+id/chat_persion_name"
                app:layout_constraintTop_toBottomOf="@+id/chat_persion_name" />
        </android.support.constraint.ConstraintLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

My conversation layout:

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/msgs_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:theme="@style/AppTheme2"

        >


        <android.support.v7.widget.RecyclerView

            android:id="@+id/active_chats"
            android:layout_width="match_parent"
            android:layout_height="510dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="2dp"
            android:layout_marginTop="57dp">


        </android.support.v7.widget.RecyclerView>


        <include
            android:id="@+id/include2"
            layout="@layout/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            />


    </RelativeLayout>

My Adapter:

public class ActiveChatConvo extends RecyclerView.Adapter<ActiveChatConvo.ViewHolder>
{
    private ArrayList<User> mUsers;
    private Context mContext;

    public ActiveChatConvo(ArrayList<User> photos,Context dick) {
        mUsers = photos;
        mContext = dick;
    }

    private Context getContext() {
        return mContext;
    }

    @Override
    public ActiveChatConvo.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        // Inflate the custom layout
        View contactView = inflater.inflate(R.layout.chat_single_item, parent, false);

        // Return a new holder instance
        ViewHolder viewHolder = new ViewHolder(contactView);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // Get the data model based on position
        User user = mUsers.get(position);

        // Set item views based on your views and data model
        TextView name = holder.mItemName;
        name.setText(user.getName());
        TextView description = holder.mItemDescription;
        description.setText(user.getEmail());
        ImageView pic = holder.mItemImage;
        Picasso.with(pic.getContext()).load(Uri.parse(user.getPic())).into(pic);

    }

    @Override
    public int getItemCount() {
        return mUsers.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private ImageView mItemImage;
        private TextView mItemName;
        private TextView mItemDescription;
        private LinearLayout layout;
        final LinearLayout.LayoutParams params;


        public ViewHolder(View v) {
            super(v);

            mItemImage = (ImageView) v.findViewById(R.id.chat_persion_image);
            mItemName = (TextView) v.findViewById(R.id.chat_persion_name);
            mItemDescription = (TextView) v.findViewById(R.id.chat_persion_email);
            layout = (LinearLayout) itemView.findViewById(R.id.show_chat_single_item_layout);
            params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            v.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            Context context = itemView.getContext();
            Intent showChatIntent = new Intent(context, ChatConversationActivity.class);
            //showPhotoIntent.putExtra(PHOTO_KEY, mPhoto);
            context.startActivity(showChatIntent);
        }
    }
}

My main class

public class ConnectionsActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private ViewPager mViewPager;
    private TextView person_name,person_email;
    private RecyclerView recyclerView;
    private DatabaseReference mRef;
    private LinearLayoutManager mLinearLayoutManager;
    private ArrayList<User> users;
    private FirebaseAuth mAuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        setContentView(R.layout.activity_connections);

        //Database
        mRef = FirebaseDatabase.getInstance().getReference("Users");
        mRef.keepSynced(true);

        mAuth = FirebaseAuth.getInstance();
        FirebaseUser user = mAuth.getCurrentUser();

        users = new ArrayList<>();


        mRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists())
                {

                    for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
                        String name = postSnapshot.child("Name").getValue(String.class);
                        String email = postSnapshot.child("Email").getValue(String.class);
                        String pic = postSnapshot.child("image").getValue(String.class);

                        users.add(new User(name,email,pic));
                    }
                }

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });



        //Recycler View
        recyclerView = (RecyclerView)findViewById(R.id.active_chats);
        ActiveChatConvo adapter = new ActiveChatConvo(users,this);
        recyclerView.setAdapter(adapter);
        mLinearLayoutManager = new LinearLayoutManager(this);
        //mLinearLayoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(mLinearLayoutManager);

        //VIEWS

        toolbar = (Toolbar) findViewById(R.id.tToolbar);
        if (toolbar != null)
            setSupportActionBar(toolbar);

        ImageView profileActivity = (ImageView) toolbar.findViewById(R.id.action_profile);
        ImageView homeActivity = (ImageView) toolbar.findViewById(R.id.action_home);

        profileActivity.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent profileActivity = new Intent(ConnectionsActivity.this, ProfileActivity.class);
                startActivity(profileActivity);
                finish();
                overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
            }

        });

        homeActivity.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent home = new Intent(ConnectionsActivity.this, HomeActivity.class);
                startActivity(home);
                finish();
                overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
            }

        });
    }







    }

So if the recyclerView Activity is the first activity I visit then it will not create the items.

KENdi
  • 7,576
  • 2
  • 16
  • 31
Peter Shepherd
  • 168
  • 1
  • 10
  • 2
    add `adapter.notifiyDatasetChanged()` after `users.add(new User(name,email,pic));` – Ralph Bergmann Jun 07 '17 at 08:34
  • it needs some time to load the data from Firebase but you don't tell the adapter that the data are loaded – Ralph Bergmann Jun 07 '17 at 08:34
  • @RalphBergmann Thank you for the reply but I am not sure what you mean by adding that after `users.add(new User(name,email,pic));`.Adapter is not instantiated when i am collecting the users and I also need the full users list to construct the adapter. – Peter Shepherd Jun 07 '17 at 08:58
  • 1
    you call `mRef.addListenerForSingleValueEvent` but this can take a couple of seconds. And the app doesn't wait for it, instead it still goes on. This means you create an adapter with an empty `users` list. And when the data are loaded and `onDataChange` is called you don't tell the adapter that the content has change. At the end create your adatper before you call `mRef.addListenerForSingleValueEvent` and call `adapter.notifyDatasetChanged` at the end of `onDataChange ` – Ralph Bergmann Jun 07 '17 at 14:24
  • @RalphBergmann Alright i got it working now thank you very much! – Peter Shepherd Jun 07 '17 at 16:31

4 Answers4

4

Firebase is synchronize so it doesn't block the main thread of your application, that mean that your application continue executing, you need to notify the adapter after firebase finishing his job by using adapter.notifiyDatasetChanged() after the for loop

Oussema Aroua
  • 5,225
  • 1
  • 24
  • 44
3

Replace this:

recyclerView = (RecyclerView)findViewById(R.id.active_chats);
ActiveChatConvo adapter = new ActiveChatConvo(users,this);
recyclerView.setAdapter(adapter);
mLinearLayoutManager = new LinearLayoutManager(this);
//mLinearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(mLinearLayoutManager);

with this:

recyclerView = (RecyclerView)findViewById(R.id.active_chats);
ActiveChatConvo adapter = new ActiveChatConvo(users,this);
mLinearLayoutManager = new LinearLayoutManager(this);
//mLinearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(mLinearLayoutManager);
recyclerView.setAdapter(adapter);

You need to set adapter after you set LayoutManager.

Cătălin Florescu
  • 5,012
  • 1
  • 25
  • 36
0

In my case I managed to solve it I found a way to start FirebaseDatabase before opening the activity and added the cod

adapter.notifyDataSetChanged();

and then I started the firebase before opening it with this

FirebaseDatabase.getInstance().getReference().keepSynced(true);
Victor Sam VS
  • 139
  • 3
  • 4
0

You can use Boolean button to check if it is true adapter is made

MMG
  • 3,226
  • 5
  • 16
  • 43