Firebase:“回收者”视图没有附加数据,跳过布局

时间:2019-02-13 19:17:05

标签: java android firebase firebase-realtime-database

嘿,我刚开始使用Firebase,到目前为止它很棒。但是,当我尝试使用Firebase-UI和Firebase RecyclerView将数据挂接到CardView中时,出现以下错误:

  

E / Recyclerview:未连接适配器:跳过布局

如果有人可以帮助我,那么我对Stackover流程还是陌生的。

    **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 );
        }
    }

这是我的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;
    }
}

这是我的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;
    }
}

这是我的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();

    }
}

3 个答案:

答案 0 :(得分:1)

要解决此问题,请将适配器设置在回调函数的内部和内部,只需将更改通知给它即可

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 );
    }
});

答案 1 :(得分:0)

这是因为在valueEventListener回调中设置了适配器。

使用空列表创建适配器,并在调用数据库之前进行设置。 在您的valueEventListener回调中,填充您的上传列表,然后调用mAdapter.notifyDataSetChanged();

答案 2 :(得分:-1)

在行下使用

mAdapter.notifyDataSetChanged();

此后在您的代码中

mRecyclerView.setAdapter( mAdapter );