使用Firebase和体系结构组件从搜索查询

时间:2018-12-08 21:16:17

标签: java android firebase android-architecture-components

我是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来实现。任何能将我指向正确方向的见解都将受到高度赞赏。

0 个答案:

没有答案