com.gm.goldencity.fragment.search.SearchFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.gm.goldencity.fragment.search.SearchFragment.java

Source

/*
 * Copyright (c) 2017 Gowtham Parimelazhagan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.gm.goldencity.fragment.search;

import android.app.SearchManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.InputType;
import android.text.TextUtils;
import android.transition.TransitionSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import android.widget.SearchView;
import android.widget.Toast;

import com.gm.common.ui.transition.CircularReveal;
import com.gm.common.util.ImeUtils;
import com.gm.common.util.TransitionUtils;
import com.gm.glog.library.GLog;
import com.gm.goldencity.GoldenCityApplication;
import com.gm.goldencity.R;
import com.gm.goldencity.activity.search.SearchActivity;
import com.gm.goldencity.base.basic.BaseFragment;
import com.gm.goldencity.domain.model.Search;
import com.gm.goldencity.domain.model.SearchResults;
import com.gm.goldencity.util.SchedulerProvider;
import com.gm.grecyclerview.GmRecyclerView;
import com.jakewharton.rxbinding2.widget.RxSearchView;

import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;

import static android.content.Context.SEARCH_SERVICE;

/**
 * Name       : Gowtham
 * Created on : 21/3/17.
 * Email      : goutham.gm11@gmail.com
 * GitHub     : https://github.com/goutham106
 */

public class SearchFragment extends BaseFragment implements Searchview {
    private static final String TAG = "SearchFragment";

    @Inject
    Context context;
    @Inject
    Resources resources;
    @Inject
    SearchPresenter presenter;
    @Inject
    SchedulerProvider scheduler;

    @BindView(android.R.id.empty)
    ProgressBar progress;
    @BindView(R.id.search_results)
    GmRecyclerView results;
    @BindView(R.id.container)
    ViewGroup container;
    @BindView(R.id.results_container)
    ViewGroup resultsContainer;

    PublishSubject<Search> notifyCharacter = PublishSubject.create();
    PublishSubject<String> notifyMessage = PublishSubject.create();
    PublishSubject<Boolean> notifyOffline = PublishSubject.create();

    public SearchFragment() {
    }

    public static SearchFragment newInstance() {
        return new SearchFragment();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        presenter.bind(this);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_search, container, false);

        ButterKnife.bind(this, view);

        ((SearchActivity) getActivity()).setupSearchView();
        doSearch(((SearchActivity) getActivity()).getSearchview());
        setupTransitions();

        return view;
    }

    @Override
    public void onDetach() {
        super.onDetach();
        presenter.unbind();
    }

    @Override
    public void onPause() {
        super.onPause();
        getActivity().overridePendingTransition(0, 0);
    }

    @Override
    protected void injectDependencies(GoldenCityApplication application) {
        application.getSearchSubComponent().inject(this);
    }

    private void doSearch(SearchView searchView) {

        RxSearchView.queryTextChangeEvents(searchView).skip(1)
                .doOnNext(charSequence -> GLog.e("Search", "Searching: " + charSequence))
                .throttleLast(100, TimeUnit.MILLISECONDS).debounce(300, TimeUnit.MILLISECONDS)
                // .onBackpressureLatest()
                .observeOn(scheduler.mainThread()).filter(searchViewQueryTextEvent -> {
                    final boolean empty = TextUtils.isEmpty(searchViewQueryTextEvent.queryText());
                    if (empty) {
                        GLog.e("Search", "empty view");
                        clearAdapter();
                    }
                    return !empty;
                }).switchMap(searchViewQueryTextEvent -> {
                    GLog.e("Search", "requesting " + searchViewQueryTextEvent.queryText().toString());
                    String searchTerm = searchViewQueryTextEvent.queryText().toString();
                    boolean submitted = searchViewQueryTextEvent.isSubmitted();
                    //Show Loading and Hide RecyclerView
                    Observable<SearchResults> observable;
                    if (submitted) {
                        observable = presenter.fullSearch(searchTerm);
                    } else {
                        if (TextUtils.isEmpty(searchTerm)) {
                            clearResults();
                        }
                        observable = presenter.searchSuggestion(searchTerm);
                    }
                    //Hide Loading and show RecyclerView
                    return observable.compose(scheduler.normalSchedulers()).doOnComplete(this::showContent);
                }).doOnNext(charSequence -> GLog.e("Search", "got data"))
                .subscribe(this::showSearchResponse, throwable -> {
                    throwable.printStackTrace();
                    showEmptyErrorView(throwable.getMessage());
                });

        searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
            @Override
            public boolean onSuggestionSelect(int position) {
                return true;
            }

            @Override
            public boolean onSuggestionClick(int position) {
                return true;
            }
        });

    }

    private void showContent() {
        presenter.getObservableEnd(true);
    }

    private Observable<SearchResults> getFullSearch(String searchTerm) {
        return null;
    }

    private void clearAdapter() {

    }

    public void showSearchResponse(SearchResults list) {
        // adapter.swap(list);
        GLog.e(TAG, " " + list.getSearch());
    }

    private void showEmptyErrorView(String message) {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
    }

    void clearResults() {
        results.setVisibility(View.GONE);
        progress.setVisibility(View.GONE);
    }

    @Override
    public void showMessage(String message) {
    }

    @Override
    public void showOfflineMessage(boolean isCritical) {

    }

    @Override
    public void showQueryError(Throwable throwable) {

    }

    @Override
    public void showCharacter(Search character) {

    }

    @Override
    public void showRetryMessage(Throwable throwable) {

    }

    @Override
    public void showQueryNoResult() {

    }

    @Override
    public void setCharactersCachedData(List<Search> characters) {

    }

    @Override
    public void showError(Throwable throwable) {

    }

    @Override
    public void showProgress() {
        progress.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgress() {
        progress.setVisibility(View.GONE);
    }

    @Override
    public void showServiceError(ApiResponseCodeException throwable) {

    }

    public Observable<Search> characterObservable() {
        return notifyCharacter.hide();
    }

    public Observable<String> messageObservable() {
        return notifyMessage.hide();
    }

    public Observable<Boolean> offlineObservable() {
        return notifyOffline.hide();
    }

    private void setupTransitions() {
        // grab the position that the search icon transitions in *from*
        // & use it to configure the return transition
        setEnterSharedElementCallback(new android.support.v4.app.SharedElementCallback() {
            @Override
            public void onSharedElementStart(List<String> sharedElementNames, List<View> sharedElements,
                    List<View> sharedElementSnapshots) {
                if (sharedElements != null && !sharedElements.isEmpty()) {
                    View searchIcon = sharedElements.get(0);
                    if (searchIcon.getId() != R.id.searchback)
                        return;
                    int centerX = (searchIcon.getLeft() + searchIcon.getRight()) / 2;
                    CircularReveal hideResults = (CircularReveal) TransitionUtils.findTransition(
                            (TransitionSet) getActivity().getWindow().getReturnTransition(), CircularReveal.class,
                            R.id.results_container);
                    if (hideResults != null) {
                        hideResults.setCenter(new Point(centerX, 0));
                    }
                }
            }
        });
    }

}