我是Firebase和体系结构组件的新手。我目前正在尝试实现一个搜索栏,您可以在其中键入并自动过滤片段中的列表和适配器。我试图遵循这些教程:
Android Using Architecture Components
和
https://www.youtube.com/watch?v=BofWWZE1wts&t=1623s
这是我的片段:
public class MeasureOptionsFragment extends Fragment {
private static final String TAG = "MeasureOptionsFragment";
private MeasureOptionViewModel measureOptionViewModel;
private RecyclerView recyclerView;
private List<MeasureOption> measureOptionList;
private MeasureOptionRecyclerViewAdapter adapter;
private SearchView searchView;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onActivityCreated: started");
super.onActivityCreated(savedInstanceState);
measureOptionList = new ArrayList<>();
recyclerView = getActivity().findViewById(R.id.measure_options_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
// Setting up the view model
measureOptionViewModel = ViewModelProviders.of(getActivity())
.get(MeasureOptionViewModel.class);
measureOptionViewModel.getLiveData().observe(getActivity(), new Observer<DataSnapshot>() {
@Override
public void onChanged(@Nullable DataSnapshot dataSnapshot) {
measureOptionList = MeasureOptionViewModel.convertToList(dataSnapshot);
adapter.submitList(measureOptionList);
}
});
//Setting up the measure options adapter
adapter = new MeasureOptionRecyclerViewAdapter();
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.measure_menu, menu);
searchView = (SearchView) menu.findItem(R.id.measure_search_view).getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
Log.d(TAG, "onQueryTextChange: sending query = " + s);
measureOptionViewModel.searchMeasureOptions(s);
adapter.submitList(MeasureOptionViewModel.convertToList(measureOptionViewModel.getLiveData().getValue()));
return true;
}
});
// Fill up the fragment with all options
LiveData<DataSnapshot> allMeasures = measureOptionViewModel.getLiveData();
measureOptionViewModel.setLiveData(allMeasures);
adapter.notifyDataSetChanged();
searchView.setIconified(false);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.measure_settings:
return true;
case R.id.add_measure_options:
addMeasureOptions();
}
return super.onOptionsItemSelected(item);
}
}
这是我的视图模型:
public class MeasureOptionViewModel extends AndroidViewModel {
private static final String TAG = MeasureOptionViewModel.class.getSimpleName();
private static final DatabaseReference MEASURE_OPTIONS_REF =
FirebaseDatabase.getInstance().getReference(MeasureOption.MEASURE_OPTION_NODE);
private LiveData<DataSnapshot> liveData;
private MutableLiveData<String> searchTerm;
private Context context;
public MeasureOptionViewModel(@NonNull Application application) {
super(application);
this.context = application.getApplicationContext();
searchTerm = new MutableLiveData<>();
liveData = Transformations.switchMap(searchTerm,
query -> queryMeasureOptions(query));
}
public static List<MeasureOption> convertToList(DataSnapshot dataSnapshot) {
List<MeasureOption> list = new ArrayList<>();
if (dataSnapshot == null) {
Log.d(TAG, "convertToList: input is null");
return null;
} else {
for (DataSnapshot d : dataSnapshot.getChildren()){
list.add(d.getValue(MeasureOption.class));
}
return list;
}
}
private LiveData<DataSnapshot> queryMeasureOptions(String query) {
if(query.isEmpty()) {
Log.d(TAG, "queryMeasureOptions: is empty");
liveData = new FirebaseQueryLiveData(MEASURE_OPTIONS_REF);
} else {
Log.d(TAG, "queryMeasureOptions: is not empty");
liveData = new FirebaseQueryLiveData(MEASURE_OPTIONS_REF
.startAt(query)
.endAt(query + "\uf8ff"));
}
return liveData;
}
public void searchMeasureOptions(String searchTerm) {
Log.d(TAG, "searchMeasureOptions: " + searchTerm);
if(searchTerm != null){
this.searchTerm.setValue(searchTerm);
}
}
public String getSearchTermString(){
return this.searchTerm.getValue();
}
public LiveData<DataSnapshot> getLiveData() {
return liveData;
}
public void setLiveData(LiveData<DataSnapshot> liveData) {
this.liveData = liveData;
}
}
最后是我的FirebaseQueryLiveData类:
public class FirebaseQueryLiveData extends LiveData<DataSnapshot> {
private static final String TAG = "FirebaseQueryLiveData";
private final Query query;
private final MyValueEventListener listener = new MyValueEventListener();
public FirebaseQueryLiveData(Query query) {
this.query = query;
}
public FirebaseQueryLiveData(DatabaseReference ref) {
this.query = ref;
}
@Override
protected void onActive() {
super.onActive();
query.addValueEventListener(listener);
}
@Override
protected void onInactive() {
super.onInactive();
query.removeEventListener(listener);
}
private class MyValueEventListener implements ValueEventListener {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
setValue(dataSnapshot);
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "Can't listen to query " + query,databaseError.toException());
}
}
}
我能够通过使用相同的结构但通过使用Room来实现这一点,不幸的是,我无法使用firebase来实现。任何能将我指向正确方向的见解都将受到高度赞赏。