使用 FirestoreUI 实现搜索
implementing search with FirestoreUI
我一直在尝试使用 firestoreUI 实现搜索,但是当我 运行 我的代码时 logcat 说:
java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'void com.firebase.ui.firestore.FirestoreRecyclerAdapter.startListening()'
在 com.example.homebarberv1.Search.onStart(Search.java:93)
下面是我的代码:
public class Search extends AppCompatActivity implements FirebaseAuth.AuthStateListener{
private EditText searchField;
private Button searchButton;
private RecyclerView searchRecyclerview;
private FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
private FirestoreRecyclerAdapter<User, UsersViewHolder> adapter;
private String searchText;
static {
FirebaseFirestore.setLoggingEnabled(true);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_search);
searchField = findViewById(R.id.SearchField);
searchButton = findViewById(R.id.SearchButton);
searchRecyclerview = findViewById(R.id.SearchContainer);
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setReverseLayout(true);
manager.setStackFromEnd(true);
searchRecyclerview .setHasFixedSize(true);
searchRecyclerview .setLayoutManager(manager);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
bottomNavigationView.setSelectedItemId(R.id.search);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.search:
return true;
case R.id.appointment:
startActivity(new Intent(getApplicationContext(),HomePage.class));
overridePendingTransition(0,0);
return true;
case R.id.profile:
startActivity(new Intent(getApplicationContext(),Profile.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
searchText = searchField.getText().toString();
firebaseUserSearch(searchText);
}
});
}
@Override
public void onStart() {
super.onStart();
if (isSignedIn()) {
adapter.startListening();
}
firebaseAuth.addAuthStateListener(this);
}
@Override
protected void onStop() {
super.onStop();
adapter.stopListening();
FirebaseAuth.getInstance().removeAuthStateListener(this);
}
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth auth) {
if (isSignedIn()) {
adapter.startListening();
} else {
Toast.makeText(Search.this,"user are not signed in",Toast.LENGTH_LONG);
}
}
private boolean isSignedIn() {
return FirebaseAuth.getInstance().getCurrentUser() != null;
}
@NonNull
private void firebaseUserSearch(String searchText){
CollectionReference sCollection =
FirebaseFirestore.getInstance().collection("Barbers");
Query sQuery = sCollection.startAt(searchText).endAt(searchText + "\uf8ff");
FirestoreRecyclerOptions<User> options =
new FirestoreRecyclerOptions.Builder<User>()
.setQuery(sQuery, User.class)
.setLifecycleOwner(this)
.build();
adapter = new FirestoreRecyclerAdapter<User, UsersViewHolder>(options) {
@NonNull
@Override
public UsersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.searchlist, parent, false);
return new UsersViewHolder(view);
}
@Override
protected void onBindViewHolder(@NonNull UsersViewHolder holder, int position, @NonNull User model) {
holder.setName(model.getShopname());
holder.setPic(model.getPiclink());
holder.setAddress(model.getAddress() + ", " + model.getPostcode().toString() + ", " + model.getCity());
}
};
searchRecyclerview.setAdapter(adapter);
}
public class UsersViewHolder extends RecyclerView.ViewHolder {
private View mView;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setName(String name){
TextView userNameView = (TextView) mView.findViewById(R.id.shopNameS);
userNameView.setText(name);
}
public void setPic(String link){
ImageView imageView = (ImageView)mView.findViewById(R.id.imageS);
Picasso.get().load(link).into(imageView);
}
public void setAddress(String address){
TextView addressView = (TextView) mView.findViewById(R.id.shopAddressS);
addressView.setText(address);
}
}
}
错误指的是这一行:
adapter.startListening();
我还是Android的新手,所以我不太明白我在这里做错了什么,非常感谢帮助
在调用 adapter.startListening
之前,您需要确保 adapter
已被赋值。
这意味着在 onStart
中您需要确保适配器存在:
@Override
public void onStart() {
super.onStart();
if (isSignedIn() && adapter != null) {
adapter.startListening();
}
firebaseAuth.addAuthStateListener(this);
}
然后在创建适配器并且用户登录时也开始监听适配器。因此:
adapter = new FirestoreRecyclerAdapter<User, UsersViewHolder>(options) {
...
});
if (isSignedIn()) {
adapter.startListening();
}
我一直在尝试使用 firestoreUI 实现搜索,但是当我 运行 我的代码时 logcat 说:
java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'void com.firebase.ui.firestore.FirestoreRecyclerAdapter.startListening()' 在 com.example.homebarberv1.Search.onStart(Search.java:93)
下面是我的代码:
public class Search extends AppCompatActivity implements FirebaseAuth.AuthStateListener{
private EditText searchField;
private Button searchButton;
private RecyclerView searchRecyclerview;
private FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
private FirestoreRecyclerAdapter<User, UsersViewHolder> adapter;
private String searchText;
static {
FirebaseFirestore.setLoggingEnabled(true);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_search);
searchField = findViewById(R.id.SearchField);
searchButton = findViewById(R.id.SearchButton);
searchRecyclerview = findViewById(R.id.SearchContainer);
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setReverseLayout(true);
manager.setStackFromEnd(true);
searchRecyclerview .setHasFixedSize(true);
searchRecyclerview .setLayoutManager(manager);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
bottomNavigationView.setSelectedItemId(R.id.search);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.search:
return true;
case R.id.appointment:
startActivity(new Intent(getApplicationContext(),HomePage.class));
overridePendingTransition(0,0);
return true;
case R.id.profile:
startActivity(new Intent(getApplicationContext(),Profile.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
searchText = searchField.getText().toString();
firebaseUserSearch(searchText);
}
});
}
@Override
public void onStart() {
super.onStart();
if (isSignedIn()) {
adapter.startListening();
}
firebaseAuth.addAuthStateListener(this);
}
@Override
protected void onStop() {
super.onStop();
adapter.stopListening();
FirebaseAuth.getInstance().removeAuthStateListener(this);
}
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth auth) {
if (isSignedIn()) {
adapter.startListening();
} else {
Toast.makeText(Search.this,"user are not signed in",Toast.LENGTH_LONG);
}
}
private boolean isSignedIn() {
return FirebaseAuth.getInstance().getCurrentUser() != null;
}
@NonNull
private void firebaseUserSearch(String searchText){
CollectionReference sCollection =
FirebaseFirestore.getInstance().collection("Barbers");
Query sQuery = sCollection.startAt(searchText).endAt(searchText + "\uf8ff");
FirestoreRecyclerOptions<User> options =
new FirestoreRecyclerOptions.Builder<User>()
.setQuery(sQuery, User.class)
.setLifecycleOwner(this)
.build();
adapter = new FirestoreRecyclerAdapter<User, UsersViewHolder>(options) {
@NonNull
@Override
public UsersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.searchlist, parent, false);
return new UsersViewHolder(view);
}
@Override
protected void onBindViewHolder(@NonNull UsersViewHolder holder, int position, @NonNull User model) {
holder.setName(model.getShopname());
holder.setPic(model.getPiclink());
holder.setAddress(model.getAddress() + ", " + model.getPostcode().toString() + ", " + model.getCity());
}
};
searchRecyclerview.setAdapter(adapter);
}
public class UsersViewHolder extends RecyclerView.ViewHolder {
private View mView;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setName(String name){
TextView userNameView = (TextView) mView.findViewById(R.id.shopNameS);
userNameView.setText(name);
}
public void setPic(String link){
ImageView imageView = (ImageView)mView.findViewById(R.id.imageS);
Picasso.get().load(link).into(imageView);
}
public void setAddress(String address){
TextView addressView = (TextView) mView.findViewById(R.id.shopAddressS);
addressView.setText(address);
}
}
}
错误指的是这一行:
adapter.startListening();
我还是Android的新手,所以我不太明白我在这里做错了什么,非常感谢帮助
在调用 adapter.startListening
之前,您需要确保 adapter
已被赋值。
这意味着在 onStart
中您需要确保适配器存在:
@Override
public void onStart() {
super.onStart();
if (isSignedIn() && adapter != null) {
adapter.startListening();
}
firebaseAuth.addAuthStateListener(this);
}
然后在创建适配器并且用户登录时也开始监听适配器。因此:
adapter = new FirestoreRecyclerAdapter<User, UsersViewHolder>(options) {
...
});
if (isSignedIn()) {
adapter.startListening();
}