[英]Firebase:Recycler view No Adater attached , Skipping Layout
Hey I just started out with firebase and its been great so far.嘿,我刚开始使用 firebase,到目前为止它很棒。 However when I try to hook my data in CardView
using Firebase-UI and Firebase RecyclerView, I get the following error:但是,当我尝试使用 Firebase-UI 和 Firebase RecyclerView 将我的数据挂接到CardView
中时,我收到以下错误:
E/Recyclerview:No Adapter attached :skipping layout E/Recyclerview:没有附加适配器:跳过布局
I am even new on stackover flow if any one can help then it will be honored.如果有人可以提供帮助,我什至是stackover flow的新手,那么它将受到尊重。
**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这是我的 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这是我的 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这是我的 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();
}
}
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 );
}
});
It's because your adapter is being set in the valueEventListener callback.这是因为您的适配器正在 valueEventListener 回调中设置。
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();在您的 valueEventListener 回调中,填充您的上传列表并调用 mAdapter.notifyDataSetChanged();
Use below line使用下面的行
mAdapter.notifyDataSetChanged();
after this in your code在你的代码之后
mRecyclerView.setAdapter( mAdapter );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.