sagar
sagar

Reputation: 11

Firebase:Recycler view No Adater attached , Skipping Layout

Hey I just started out with firebase and its been great so far. However when I try to hook my data in CardView using Firebase-UI and Firebase RecyclerView, I get the following error:

E/Recyclerview:No Adapter attached :skipping layout

I am even new on stackover flow if any one can help then it will be honored.

    **This is MainActivity.java**

    package com.example.uploadfirebase;

    import android.content.ContentResolver;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Handler;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.webkit.MimeTypeMap;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ImageView;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.Toast;

    import com.google.android.gms.tasks.OnFailureListener;
    import com.google.android.gms.tasks.OnSuccessListener;
    import com.google.firebase.FirebaseApp;
    import com.google.firebase.database.DatabaseReference;
    import com.google.firebase.database.FirebaseDatabase;
    import com.google.firebase.storage.FirebaseStorage;
    import com.google.firebase.storage.OnProgressListener;
    import com.google.firebase.storage.StorageReference;
    import com.google.firebase.storage.StorageTask;
    import com.google.firebase.storage.UploadTask;
    import com.squareup.picasso.Picasso;

    public class MainActivity extends AppCompatActivity {


        private static final int PICK_IMAGE_REQUEST =1;
        private Button mButtonChooseImage;
        private Button mButtonUpload;
        private TextView mTextViewShowUploads;
        private EditText mEditTextFileName;
        private ImageView mImageView;
        private ProgressBar mProgressBar;;
        private Uri mImageUri;

        private StorageReference mStorageRef;
        private DatabaseReference mDatabaseRef;
        private StorageTask muploadtask;



        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate( savedInstanceState );
            setContentView( R.layout.activity_main );

            mButtonChooseImage =findViewById( R.id.button_choose_image );
            mButtonUpload=findViewById( R.id.button_upload );
            mTextViewShowUploads=findViewById( R.id.text_view_show_upload );
            mEditTextFileName=findViewById( R.id.edit_text_file_name );
            mImageView =findViewById( R.id.image_view );
            mProgressBar=findViewById( R.id.progress_bar );

            FirebaseApp.initializeApp( this );

            mStorageRef = FirebaseStorage.getInstance().getReference("uploads ");
            mDatabaseRef= FirebaseDatabase.getInstance().getReference("uploads");

            mButtonChooseImage.setOnClickListener( new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    openFileChooser();
                }
            } );

            mButtonUpload.setOnClickListener( new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    if(muploadtask !=null && muploadtask.isInProgress())
                    {
                        Toast.makeText( MainActivity.this,"upload in progress",Toast.LENGTH_SHORT ).show();
                    } else {
                        uploadFile();
                    }
                }
            } );

            mTextViewShowUploads.setOnClickListener( new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                OpenImagesActivity();
                }
            } );
        }

        private void openFileChooser()
        {
            Intent intent=new Intent(  );
            intent.setType("image/*" );
            intent.setAction( intent.ACTION_GET_CONTENT );
            startActivityForResult( intent,PICK_IMAGE_REQUEST );
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            super.onActivityResult( requestCode, resultCode, data );

            if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK
            && data !=null && data.getData()!=null)
            {
                mImageUri=data.getData();
                Picasso.with( this ).load(mImageUri).into(mImageView);
            }

        }
        private String getfileExtension(Uri uri)
        {
            ContentResolver cr=getContentResolver();
            MimeTypeMap mime= MimeTypeMap.getSingleton();
            return mime.getExtensionFromMimeType( cr.getType( uri ) );
        }


        private void uploadFile()
        {
            if (mImageUri != null)
            {
                StorageReference fileReference =mStorageRef.child( System.currentTimeMillis() +"."+ getfileExtension( mImageUri ) );

               muploadtask= fileReference.putFile( mImageUri )
                        .addOnSuccessListener( new OnSuccessListener<UploadTask.TaskSnapshot>() {
                            @Override
                            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

                                Handler handler=new Handler(  );
                                handler.postDelayed( new Runnable() {
                                    @Override
                                    public void run() {
                                        mProgressBar.setProgress( 0 );
                                    }
                                } ,5000 );
                                Toast.makeText( MainActivity.this,"upload successfull",Toast.LENGTH_LONG ).show();
                                upload upload=new upload(mEditTextFileName.getText().toString().trim(),
                                        taskSnapshot.getMetadata().getReference().getDownloadUrl().toString());

                                String uploadId=mDatabaseRef.push().getKey();
                                mDatabaseRef.child( uploadId ).setValue( upload );
                            }
                        } )
                        .addOnFailureListener( new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {

                                Toast.makeText( MainActivity.this,e.getMessage(),Toast.LENGTH_SHORT ).show();

                            }
                        } )
                        .addOnProgressListener( new OnProgressListener<UploadTask.TaskSnapshot>() {
                            @Override
                            public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {

                                double progress =(100.0 * taskSnapshot .getBytesTransferred() / taskSnapshot.getTotalByteCount());
                                mProgressBar.setProgress((int) progress );
                            }
                        } );
            }
            else
            {
                Toast.makeText( this,"no file is selected",Toast.LENGTH_SHORT ).show();
            }
        }



        private void OpenImagesActivity()
        {
            Intent intent=new Intent( this,ImagesActivity.class );
            startActivity( intent );
        }
    }

this is my Upload.java

package com.example.uploadfirebase;

public class upload {
    // contains name and url

    private String mName;
    private String mImageUrl;

    public upload()
    {
        // empty constr needed
    }
    public upload(String name ,String imageUrl)
    {

        if(name.trim().equals(""))
        {
            name="No Name";
        }
        mName=name;
        mImageUrl=imageUrl;
    }

    public String getName()
    {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public String getImageUrl() {
        return mImageUrl;
    }

    public void setImageUrl(String imageUrl) {
        mImageUrl = imageUrl;
    }
}

this is my ImageAdapter.java

package com.example.uploadfirebase;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

import java.util.List;

public class ImageAdapter extends RecyclerView.Adapter <ImageAdapter.ImageviewHolder> {

   private Context mContext;
   private List<upload> mUploads;

   private OnItemClickListner mListner;

   public ImageAdapter (Context context,List<upload> uploads)
   {
       mContext=context;
       mUploads=uploads;
   }


    @NonNull
    @Override
    public ImageviewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
        View v= LayoutInflater.from( mContext ).inflate( R.layout.image_item,parent,false );
        return new ImageviewHolder( v );
    }

    @Override
    public void onBindViewHolder(@NonNull ImageviewHolder imageviewHolder, int position) {

       upload uploadCurrent =mUploads.get(position);
       imageviewHolder.textviewName.setText( uploadCurrent.getName() );

        Picasso.with(mContext)
                .load( uploadCurrent.getImageUrl() )
                .placeholder( R.mipmap.ic_launcher )
                .fit()
                .centerCrop()
                .into( imageviewHolder.imageView  );

    }

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

    public class ImageviewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
            View.OnCreateContextMenuListener , MenuItem.OnMenuItemClickListener {

       public TextView textviewName;
       public ImageView imageView;

        public ImageviewHolder(@NonNull View itemView) {
            super( itemView );

            textviewName=itemView.findViewById( R.id.text_view_name );
            imageView=itemView.findViewById( R.id.image_view_upload);


            itemView.setOnClickListener( this );
            itemView.setOnCreateContextMenuListener( this );
        }

        @Override
        public void onClick(View v) {

            if (mListner !=null )
            {
                int position=getAdapterPosition();
                if (position != RecyclerView.NO_POSITION){
                    mListner.onItemClick( position );
                }
            }
        }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {

            menu.setHeaderTitle( "select Action" );
            MenuItem doWhatever = menu.add( Menu.NONE,1,1,"Do Whatever");

            MenuItem delete = menu.add( Menu.NONE,2,2,"Delete" );
            doWhatever.setOnMenuItemClickListener( this );
            delete.setOnMenuItemClickListener( this );

        }


        @Override
        public boolean onMenuItemClick(MenuItem item) {

            if (mListner !=null )
            {
                int position=getAdapterPosition();
                if (position != RecyclerView.NO_POSITION){

                    switch (item.getItemId())
                    {
                        case 1:
                            mListner.onWhateverClick( position );
                            return true;
                        case 2:
                            mListner.OndeleteClick( position );
                            return true;
                    }
                }
            }

            return false;
        }
    }


    public interface OnItemClickListner{

       void onItemClick (int Position);

       void  onWhateverClick (int Position);

       void OndeleteClick(int Position);


    }

    public void setOnItemClickListner (OnItemClickListner listner)
    {
        mListner=listner;
    }
}

this is my ImagesActivty.java

package com.example.uploadfirebase;

import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.google.firebase.FirebaseApp;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.List;

public class ImagesActivity extends AppCompatActivity implements ImageAdapter.OnItemClickListner {

    private RecyclerView mRecyclerView;
    private  ImageAdapter mAdapter;
    private DatabaseReference mDatabaseRef;
    private List <upload> mUploads;


    private ProgressBar mProgressCircle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_images );


        mRecyclerView=findViewById( R.id.recycler_view );
        mRecyclerView.setHasFixedSize( true );
        mRecyclerView.setLayoutManager( new LinearLayoutManager( this ) );

        mProgressCircle =findViewById( R.id.progress_cirle );
        mUploads = new ArrayList<>(  );

        FirebaseApp.initializeApp( this );
        mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");


        mDatabaseRef.addValueEventListener( new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                for (DataSnapshot postSnapshot:dataSnapshot.getChildren())
                {
                    // upload with small u is my class and activty name
                    // upload with big u is my object name and paremter showld be passed with Big Uploads

                    upload Upload=postSnapshot.getValue(upload.class);
                    mUploads.add( Upload );
                }

                mAdapter=new ImageAdapter( ImagesActivity.this,mUploads );
                mRecyclerView.setAdapter( mAdapter );



                mAdapter.setOnItemClickListner( ImagesActivity.this );
                mProgressCircle.setVisibility( View.INVISIBLE );


            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Toast.makeText( ImagesActivity.this,databaseError.getMessage(),Toast.LENGTH_SHORT ).show();
                mProgressCircle.setVisibility( View.INVISIBLE );
            }
        } );
    }

    @Override
    public void onItemClick(int Position) {
        Toast.makeText( this,"normal click "+ Position, Toast.LENGTH_SHORT ).show();
    }

    @Override
    public void onWhateverClick(int Position) {
        Toast.makeText( this,"whatever  click "+ Position, Toast.LENGTH_SHORT ).show();

    }

    @Override
    public void OndeleteClick(int Position) {
        Toast.makeText( this,"delete click "+ Position, Toast.LENGTH_SHORT ).show();

    }
}

Upvotes: 1

Views: 261

Answers (3)

Alex Mamo
Alex Mamo

Reputation: 138969

To solve this, set the adapter outside the callback and inside it, just notify it about the changes:

mAdapter = new ImageAdapter(ImagesActivity.this,mUploads);
mRecyclerView.setAdapter(mAdapter);
mDatabaseRef.addValueEventListener( new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot postSnapshot:dataSnapshot.getChildren()) {
            // upload with small u is my class and activty name
            // upload with big u is my object name and paremter showld be passed with Big Uploads

            upload Upload=postSnapshot.getValue(upload.class);
            mUploads.add( Upload );
        }
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Toast.makeText( ImagesActivity.this,databaseError.getMessage(),Toast.LENGTH_SHORT ).show();
        mProgressCircle.setVisibility( View.INVISIBLE );
    }
});

Upvotes: 2

seewilker
seewilker

Reputation: 41

It's because your adapter is being set in the valueEventListener callback.

Create the adapter with an empty list and set it before calling the database. In your valueEventListener callback, populate your uploads list and call mAdapter.notifyDataSetChanged();

Upvotes: 0

Sajith
Sajith

Reputation: 771

Use below line

mAdapter.notifyDataSetChanged();

after this in your code

mRecyclerView.setAdapter( mAdapter );

Upvotes: -1

Related Questions