Dick Harris
Dick Harris

Reputation: 41

How do i fix RecyclerView: No adapter attached; skipping layout?

I've been at this for while and i keep getting an error : E/RecyclerView: No adapter attached; skipping layout.

I started changing things in ViewProfilePostsFragment where the setAdapter is called, i had no success in making it work. I cant seem to figure out why this is happening.

Here are my scripts so you can tell me what i did wrong, there is the script that's calling the setAdapter method and another for the RecyclerAdapter script.

ViewProfilePostsFragment.java

public class ViewProfilePostsFragment extends Fragment{
private static final String TAG = "ViewProfilePostsFragmen";

private ArrayList<Photo> mPhotos;
private ArrayList<String> mFriends;
private RecyclerView mRecView;
private ViewProfilePostsAdapter mAdapter;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_profile_posts, container, false);
    mRecView = (RecyclerView) view.findViewById(R.id.lvProfilePosts);
    mFriends = new ArrayList<>();
    mPhotos = new ArrayList<>();

    getFriends();


    return view;
}

private void getFriends(){
    Log.d(TAG, "getFollowing: searching for FRIENDS **************************************");

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
    Query query = reference
            .child(getString(R.string.dbname_friends))
            .child(FirebaseAuth.getInstance().getCurrentUser().getUid());
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
                mFriends.add(singleSnapshot.child(getString(R.string.field_user_id)).getValue().toString());
            }
            //get the photos
            getPhotos();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

private void getPhotos(){
    Log.d(TAG, "getPhotos: getting photos");
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
    for(int i = 0; i < mFriends.size(); i++){
        final int count = i;
        Query query = reference
                .child(getString(R.string.dbname_user_photos))
                .child(mFriends.get(i))
                .orderByChild(getString(R.string.field_user_id))
                .equalTo(mFriends.get(i));
        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){

                    Photo photo = new Photo();
                    Map<String, Object> objectMap = (HashMap<String, Object>) singleSnapshot.getValue();

                    photo.setCaption(objectMap.get(getString(R.string.field_caption)).toString());
                    photo.setTags(objectMap.get(getString(R.string.field_tags)).toString());
                    photo.setPhoto_id(objectMap.get(getString(R.string.field_photo_id)).toString());
                    photo.setUser_id(objectMap.get(getString(R.string.field_user_id)).toString());
                    photo.setDate_created(objectMap.get(getString(R.string.field_date_created)).toString());
                    photo.setImage_path(objectMap.get(getString(R.string.field_image_path)).toString());

                    mPhotos.add(photo);
                }
                if(count >= mFriends.size() -1){
                    //display our photos
                    displayPhotos();
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
}

private void displayPhotos(){
    if(mPhotos != null){
        Collections.sort(mPhotos, new Comparator<Photo>() {
            @Override
            public int compare(Photo o1, Photo o2) {
                return o2.getDate_created().compareTo(o1.getDate_created());
            }
        });

        LinearLayoutManager llm = new LinearLayoutManager(getActivity());
        llm.setOrientation(LinearLayoutManager.VERTICAL);
        mRecView.setLayoutManager(llm);
        mAdapter = new ViewProfilePostsAdapter(getActivity(), mPhotos);
        mRecView.setAdapter( mAdapter );

    }
}

ViewProfilePostsAdapter.java

public class ViewProfilePostsAdapter extends RecyclerView.Adapter<ViewProfilePostsAdapter.ViewHolder> {
private static final String TAG = "CustomAdapter";

//private int[] getItemIn;

private LayoutInflater mInflater;
//private int mLayoutResource;
private Context mContext;
private DatabaseReference mReference;
private String currentUsername;

private ArrayList<Photo> list;


public static class ViewHolder extends RecyclerView.ViewHolder {
    //private final TextView textView;

    ImageView mProfileImage;
    String likesString;
    TextView username, timeDelta, caption, likes, liked;
    ImageView postImage;
    ImageView heartRed, heartWhite;

    UserAccountSettings settings = new UserAccountSettings();
    User user = new User();
    StringBuilder users;
    String mLikesString;
    boolean likeByCurrentUser;
    Heart heart;
    GestureDetector detector;
    Photo photo;

    public ViewHolder(View convertView) {
        super(convertView);
        username = (TextView) convertView.findViewById(R.id.display_name);
        postImage = (ImageView) convertView.findViewById(R.id.post_image);
        caption = (TextView) convertView.findViewById(R.id.image_caption);
        timeDelta = (TextView) convertView.findViewById(R.id.image_time_posted);
        likes = (TextView) convertView.findViewById(R.id.tvLikesString);
        mProfileImage = (ImageView) convertView.findViewById(R.id.f_profile_image);
        heartRed = (ImageView) convertView.findViewById(R.id.image_heart_red);
        heartWhite = (ImageView) convertView.findViewById(R.id.image_heart_white);
        heart = new Heart(heartWhite, heartRed);
        liked = (TextView) convertView.findViewById(R.id.likeText);
    }

}



public ViewProfilePostsAdapter(Context context, ArrayList<Photo> photo) {
    this.mContext = context;
    this.list = photo;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    // Create a new view.
    LayoutInflater mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = mInflater.inflate(R.layout.layout_post_listitem, null);

    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
    Log.d(TAG, "Element " + position + " set.");

    mReference = FirebaseDatabase.getInstance().getReference();


    viewHolder.photo = getItem(position);
    viewHolder.detector = new GestureDetector(mContext, new GestureListener(viewHolder));

    getCurrentUsername();

    getLikesString(viewHolder);

    viewHolder.caption.setText(getItem(position).getCaption());

    String timestampDifference = getTimestampDifference(getItem(position));
    if(!timestampDifference.equals("0")){
        viewHolder.timeDelta.setText(timestampDifference + " DAYS AGO");
    }else{
        viewHolder.timeDelta.setText("TODAY");
    }

    final ImageLoader imageLoader = ImageLoader.getInstance();
    imageLoader.displayImage(getItem(position).getImage_path(), viewHolder.postImage);


    //get the profile image and username
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
    Query query = reference
            .child(mContext.getString(R.string.dbname_user_account_settings))
            .orderByChild(mContext.getString(R.string.field_user_id))
            .equalTo(getItem(position).getUser_id());
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.e(TAG, "onDataChange: OnDataChange ******************************************************************************");
            for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){


                Log.e(TAG, "onDataChange: found user: "
                        + singleSnapshot.getValue(UserAccountSettings.class).getUsername() + "****************************");

                viewHolder.username.setText(singleSnapshot.getValue(UserAccountSettings.class).getUsername());


                imageLoader.displayImage(singleSnapshot.getValue(UserAccountSettings.class).getProfile_photo(),
                        viewHolder.mProfileImage);

                viewHolder.settings = singleSnapshot.getValue(UserAccountSettings.class);

            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

    Query userQuery = mReference
            .child(mContext.getString(R.string.dbname_users))
            .orderByChild(mContext.getString(R.string.field_user_id))
            .equalTo(getItem(position).getUser_id());
    userQuery.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
                Log.d(TAG, "onDataChange: found user: " +
                        singleSnapshot.getValue(User.class).getUsername());

                viewHolder.user = singleSnapshot.getValue(User.class);
            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}

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

public Photo getItem(int pos){
    return list.get(pos);
}



public class GestureListener extends GestureDetector.SimpleOnGestureListener{

    ViewHolder mHolder;
    public GestureListener(ViewHolder holder) {
        mHolder = holder;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Log.d(TAG, "onDoubleTap: double tap detected.");

        DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
        Query query = reference
                .child(mContext.getString(R.string.dbname_photos))
                .child(mHolder.photo.getPhoto_id())
                .child(mContext.getString(R.string.field_likes));
        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){

                    String keyID = singleSnapshot.getKey();

                    //case1: Then user already liked the photo
                    if(mHolder.likeByCurrentUser &&
                            singleSnapshot.getValue(Like.class).getUser_id()
                                    .equals(FirebaseAuth.getInstance().getCurrentUser().getUid())){

                        mReference.child(mContext.getString(R.string.dbname_photos))
                                .child(mHolder.photo.getPhoto_id())
                                .child(mContext.getString(R.string.field_likes))
                                .child(keyID)
                                .removeValue();

                        mReference.child(mContext.getString(R.string.dbname_user_photos))
                                .child(mHolder.photo.getUser_id())
                                .child(mHolder.photo.getPhoto_id())
                                .child(mContext.getString(R.string.field_likes))
                                .child(keyID)
                                .removeValue();

                        mHolder.heart.toggleLike();
                        getLikesString(mHolder);
                    }
                    //case2: The user has not liked the photo
                    else if(!mHolder.likeByCurrentUser){
                        //add new like
                        addNewLike(mHolder);
                        break;
                    }
                }
                if(!dataSnapshot.exists()){
                    //add new like
                    addNewLike(mHolder);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

        return true;
    }
}

private void addNewLike(final ViewHolder holder){
    Log.d(TAG, "addNewLike: adding new like");

    String newLikeID = mReference.push().getKey();
    Like like = new Like();
    like.setUser_id(FirebaseAuth.getInstance().getCurrentUser().getUid());

    mReference.child(mContext.getString(R.string.dbname_photos))
            .child(holder.photo.getPhoto_id())
            .child(mContext.getString(R.string.field_likes))
            .child(newLikeID)
            .setValue(like);

    mReference.child(mContext.getString(R.string.dbname_user_photos))
            .child(holder.photo.getUser_id())
            .child(holder.photo.getPhoto_id())
            .child(mContext.getString(R.string.field_likes))
            .child(newLikeID)
            .setValue(like);

    holder.heart.toggleLike();
    getLikesString(holder);
}

private void getCurrentUsername(){
    Log.d(TAG, "getCurrentUsername: retrieving user account settings");
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
    Query query = reference
            .child(mContext.getString(R.string.dbname_users))
            .orderByChild(mContext.getString(R.string.field_user_id))
            .equalTo(FirebaseAuth.getInstance().getCurrentUser().getUid());
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
                currentUsername = singleSnapshot.getValue(UserAccountSettings.class).getUsername();
            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

private void getLikesString(final ViewHolder holder){
    Log.d(TAG, "getLikesString: getting likes string");

    try{
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
        Query query = reference
                .child(mContext.getString(R.string.dbname_photos))
                .child(holder.photo.getPhoto_id())
                .child(mContext.getString(R.string.field_likes));
        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                holder.users = new StringBuilder();
                for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){

                    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
                    Query query = reference
                            .child(mContext.getString(R.string.dbname_users))
                            .orderByChild(mContext.getString(R.string.field_user_id))
                            .equalTo(singleSnapshot.getValue(Like.class).getUser_id());
                    query.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
                                Log.d(TAG, "onDataChange: found like: " +
                                        singleSnapshot.getValue(User.class).getUsername());

                                holder.users.append(singleSnapshot.getValue(User.class).getUsername());
                                holder.users.append(",");
                            }

                            String[] splitUsers = holder.users.toString().split(",");

                            if(holder.users.toString().contains(currentUsername + ",")){//mitch, mitchell.tabian
                                holder.likeByCurrentUser = true;
                            }else{
                                holder.likeByCurrentUser = false;
                            }

                            int length = splitUsers.length;
                            if(length == 1){
                                holder.likesString = "Liked by " + splitUsers[0];
                            }
                            else if(length == 2){
                                holder.likesString = "Liked by " + splitUsers[0]
                                        + " and " + splitUsers[1];
                            }
                            else if(length == 3){
                                holder.likesString = "Liked by " + splitUsers[0]
                                        + ", " + splitUsers[1]
                                        + " and " + splitUsers[2];

                            }
                            else if(length == 4){
                                holder.likesString = "Liked by " + splitUsers[0]
                                        + ", " + splitUsers[1]
                                        + ", " + splitUsers[2]
                                        + " and " + splitUsers[3];
                            }
                            else if(length > 4){
                                holder.likesString = "Liked by " + splitUsers[0]
                                        + ", " + splitUsers[1]
                                        + ", " + splitUsers[2]
                                        + " and " + (splitUsers.length - 3) + " others";
                            }
                            Log.d(TAG, "onDataChange: likes string: " + holder.likesString);
                            //setup likes string
                            setupLikesString(holder, holder.likesString);
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });
                }
                if(!dataSnapshot.exists()){
                    holder.likesString = "";
                    holder.likeByCurrentUser = false;
                    //setup likes string
                    setupLikesString(holder, holder.likesString);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }catch (NullPointerException e){
        Log.e(TAG, "getLikesString: NullPointerException: " + e.getMessage() );
        holder.likesString = "";
        holder.likeByCurrentUser = false;
        //setup likes string
        setupLikesString(holder, holder.likesString);
    }
}

private void setupLikesString(final ViewHolder holder, String likesString) {
    Log.d(TAG, "setupLikesString: likes string:" + holder.likesString);

    if (holder.likeByCurrentUser) {
        Log.d(TAG, "setupLikesString: photo is liked by current user");
        holder.liked.setText("UnLike");
        holder.heartWhite.setVisibility(View.GONE);
        holder.heartRed.setVisibility(View.VISIBLE);
        holder.heartRed.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return holder.detector.onTouchEvent(event);
            }
        });
    } else {
        Log.d(TAG, "setupLikesString: photo is not liked by current user");
        holder.liked.setText("Like");
        holder.heartWhite.setVisibility(View.VISIBLE);
        holder.heartRed.setVisibility(View.GONE);
        holder.heartWhite.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return holder.detector.onTouchEvent(event);
            }
        });
    }
    holder.likes.setText(likesString);

}


//---------------------------------------------end of likes----------------------------

private String getTimestampDifference(Photo photo){
    Log.d(TAG, "getTimestampDifference: getting timestamp difference.");

    String difference = "";
    Calendar c = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.CANADA);
    sdf.setTimeZone(TimeZone.getTimeZone("Canada/Pacific"));//google 'android list of timezones'
    Date today = c.getTime();
    sdf.format(today);
    Date timestamp;
    final String photoTimestamp = photo.getDate_created();
    try{
        timestamp = sdf.parse(photoTimestamp);
        difference = String.valueOf(Math.round(((today.getTime() - timestamp.getTime()) / 1000 / 60 / 60 / 24 )));
    }catch (ParseException e){
        Log.e(TAG, "getTimestampDifference: ParseException: " + e.getMessage() );
        difference = "0";
    }
    return difference;
}

Upvotes: 1

Views: 1547

Answers (2)

Amit Joshi
Amit Joshi

Reputation: 126

Try to set an empty adapter in onCreateView() and call adapter.notifyDataSetChanged when you want to update data.

So in your onCreateView() method beore calling getFriends() you should initialise the adapter and set it to recyler view

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_profile_posts, container, false);
    mRecView = (RecyclerView) view.findViewById(R.id.lvProfilePosts);
    mFriends = new ArrayList<>();
    mPhotos = new ArrayList<>();

    mAdapter = new ViewProfilePostsAdapter(getActivity(), mPhotos);
    mRecView.setAdapter(mAdapter);
    getFriends();


    return view;
}

And in your displayPhotos() call mAdapter.notifyDataSetChanged();

    private void displayPhotos(){
    if(mPhotos != null){
        Collections.sort(mPhotos, new Comparator<Photo>() {
            @Override
            public int compare(Photo o1, Photo o2) {
                return o2.getDate_created().compareTo(o1.getDate_created());
            }
        });

        LinearLayoutManager llm = new LinearLayoutManager(getActivity());
        llm.setOrientation(LinearLayoutManager.VERTICAL);
        mRecView.setLayoutManager(llm);
        mAdapter.notifyDataSetChanged();

    }
}

Upvotes: 2

Veneet Reddy
Veneet Reddy

Reputation: 2927

This message shows when setAdapter() is not called on the RecyclerView.

Put a breakpoint inside your displayPhotos() and ensure it is getting called.

Upvotes: 0

Related Questions