I'm looking to implement a search function. When it runs, logcat is telling me:
E/RecyclerView: No adapter attached; skipping layout.
I have searched SO and the net and the answers tell me that I need to set the adapter and the linear layout manager. As you will see with my code, I set both. Alex Mamo's (@AlexMamo) work on here seems to point me in the right direction but I'm still getting the error.
My Activity
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.MyApp.Objects.ParticipantsObject;
import com.MyApp.R;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
public class ParticipantsActivity extends AppCompatActivity {
private EditText mSearchField;
private ImageButton mSearchBtn;
private RecyclerView mResultList;
private DatabaseReference mUserDatabase;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_neighbors);
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child("Participants");
mSearchField = (EditText) findViewById(R.id.search_field);
mSearchBtn = (ImageButton) findViewById(R.id.search_btn);
mResultList = (RecyclerView) findViewById(R.id.result_list);
mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(this));
mSearchBtn.setOnClickListener(view -> {
String searchText = mSearchField.getText().toString();
firebaseUserSearch(searchText);
});
}
private void firebaseUserSearch(String searchText) {
Toast.makeText(ParticipantsActivity.this, "Started Search", Toast.LENGTH_LONG).show();
Query firebaseSearchQuery = mUserDatabase.orderByChild("name").startAt(searchText);
FirebaseRecyclerOptions<ParticipantsObject> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<ParticipantsObject>()
.setQuery(firebaseSearchQuery, ParticipantsObject.class)
.build();
class UserHolder extends RecyclerView.ViewHolder {
private TextView imageThumbTextView, nameTextView
UserHolder(View itemView) {
super(itemView);
imageThumbTextView = itemView.findViewById(R.id.profile_image);
nameTextView = itemView.findViewById(R.id.name_text);
}
void setUsers(ParticipantsObject participantsObject) {
String imageThumb = driverObject.getThumb_image();
imageThumbTextView.setText(imageThumb);
String name = participantsObject.getName();
nameTextView.setText(name);
}
}
FirebaseRecyclerAdapter<ParticipantsObject, UserHolder> firebaseRecyclerAdapter;
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ParticipantsObject, UserHolder>(firebaseRecyclerOptions) {
@Override
protected void onBindViewHolder(@NonNull UserHolder userHolder, int position, @NonNull ParticipantsObject participantsObject) {
userHolder.setUsers(participantsObject);
}
@Override
public UserHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout, parent, false);
return new UserHolder(view);
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
firebaseRecyclerAdapter.startListening();
}
}
My Activity XML file
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context="com.MyApp.ParticipantsActivity">
<TextView
android:id="@+id/heading_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="30dp"
android:layout_marginTop="30dp"
android:text="Firebase Search"
android:textColor="#555555"
android:textSize="24sp" />
<EditText
android:id="@+id/search_field"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/heading_label"
android:layout_below="@+id/heading_label"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:layout_toStartOf="@+id/search_btn"
android:background="@drawable/search_layout"
android:ems="10"
android:hint="Search here"
android:inputType="textPersonName"
android:paddingBottom="10dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="10dp"
android:textColor="#999999"
android:textSize="16sp" />
<ImageButton
android:id="@+id/search_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/search_field"
android:layout_alignParentEnd="true"
android:layout_alignTop="@+id/search_field"
android:layout_marginRight="30dp"
android:background="@android:color/background_light"
app:srcCompat="@mipmap/search_button" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/result_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/search_field"
android:layout_marginTop="50dp">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
My list 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:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/profile_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="30dp"
android:layout_marginTop="20dp"
app:srcCompat="@mipmap/ic_default_user" />
<TextView
android:id="@+id/name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="14dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="213dp"
android:layout_marginRight="20dp"
android:layout_toEndOf="@+id/profile_image"
android:text="Username"
android:textColor="#555555"
android:textSize="16sp" />
</RelativeLayout>
Any ideas or advice would be much appreciated.
Your code is setting the adapter only after a button is pushed. Because you didn't set it before the first time the RecyclerView needed to render itself on screen, it's going to warn you about that with the message you see in the log. The RecyclerView must have an adapter attached at the time of rendering in order for it to display anything.