{"id":3766,"date":"2021-11-05T19:17:44","date_gmt":"2021-11-05T10:17:44","guid":{"rendered":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=3766"},"modified":"2021-11-06T20:24:43","modified_gmt":"2021-11-06T11:24:43","slug":"rxjava-autocomplete","status":"publish","type":"post","link":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=3766","title":{"rendered":"RxJava Retrofit2 Autocomplete"},"content":{"rendered":"<h1>RxJava Retrofit2 Autocomplete<\/h1>\n<p><a href=\"https:\/\/github.com\/alexander-mironov\/AndroidRxJavaAutocomplete\/blob\/master\/app\/src\/main\/java\/ru\/eightbps\/rxjavaautocomplete\/MainActivity.java\">\ucc38\uc8701<\/a><\/p>\n<p><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=3772\">\ucc38\uc8702<\/a><\/p>\n<p>\ucc38\uc8702 \ub97c \uae30\uc900\uc73c\ub85c \uc124\uba85\ud569\ub2c8\ub2e4.<\/p>\n<p>\ucc38\uc8702\uc5d0\uc11c \uc124\uba85\ub41c \ub0b4\uc6a9\uc740 \uc911\ubcf5\uc73c\ub85c \uc124\uba85\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<\/p>\n<h2>\uc758\uc874\uc131 \ucd94\uac00<\/h2>\n<pre><code class=\"language-gradle\">dependencies {\n    implementation &#039;com.squareup.retrofit2:retrofit:2.9.0&#039;\n    implementation &#039;com.squareup.retrofit2:converter-gson:2.9.0&#039;\n    implementation &quot;com.squareup.retrofit2:adapter-rxjava2:2.4.0&quot;\n    implementation &#039;com.squareup.okhttp3:logging-interceptor:4.2.1&#039;\n\n    implementation &#039;io.reactivex.rxjava2:rxjava:2.2.21&#039;\n    implementation &#039;io.reactivex.rxjava2:rxandroid:2.1.1&#039;\n    implementation &#039;com.jakewharton.rxbinding2:rxbinding:2.0.0&#039;\n}<\/code><\/pre>\n<h2>\ud074\ub77c\uc774\uc5b8\ud2b8<\/h2>\n<p><code>addCallAdapterFactory<\/code> \ub97c \ucd94\uac00\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">public class MGApiClient {\n\n    private static final String BASE_URL = &quot;https:\/\/&lt;API \uc11c\ubc84 \uc544\uc774\ud53c&gt;\/&quot;;\n    private static Retrofit retrofit;\n\n    public static Retrofit getApiClient() {\n\n        if(retrofit == null){\n            retrofit = new Retrofit.Builder()\n                    .baseUrl(BASE_URL)\n                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())\n                    .addConverterFactory(GsonConverterFactory.create())\n                    .build();\n        }\n        return  retrofit;\n    }\n}<\/code><\/pre>\n<h2>\uc778\ud130\ud398\uc774\uc2a4<\/h2>\n<p><code>Observable<\/code> \ub85c \ubcc0\uacbd\ud574 \uc90d\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">public interface MGApiInterface {\n\n    @GET(&quot;v1\/esautocomplete\/&quot;)\n    Observable&lt;AutoCompleteResponse&gt; getAutoComplete(\n            @Header(&quot;Authorization&quot;) String token,\n            @Query(&quot;q&quot;) String query,\n            @Query(&quot;s&quot;) int size,\n            @Query(&quot;p&quot;) int page\n    );\n}<\/code><\/pre>\n<h2>MainActivity<\/h2>\n<pre><code class=\"language-java\">public class MainActivity extends AppCompatActivity {\n\n    private static final String TAG = &quot;MainActivity&quot;;\n    private static final long DELAY_IN_MILLIS = 200;\n    public static final int MIN_LENGTH_TO_START = 1;\n    private final CompositeDisposable compositeDisposable = new CompositeDisposable();\n\n    AutoCompleteTextView searchBox;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n\n        searchBox       = findViewById(R.id.editTextSearchBox);\n\n        List&lt;String&gt; list = new ArrayList&lt;&gt;();\n\n        searchBox.setAdapter(new ArrayAdapter&lt;&gt;(this,\n                android.R.layout.simple_dropdown_item_1line, list));\n\n        addOnAutoCompleteTextViewTextChangedObserver(searchBox);\n\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        compositeDisposable.dispose();\n    }\n\n    private void addOnAutoCompleteTextViewTextChangedObserver(final AutoCompleteTextView autoCompleteTextView) {\n\n        Observable&lt;AutoCompleteResponse&gt; autocompleteResponseObservable =\n                RxTextView.textChangeEvents(autoCompleteTextView)\n                        .debounce(DELAY_IN_MILLIS, TimeUnit.MILLISECONDS)\n                        .map(textViewTextChangeEvent -&gt; textViewTextChangeEvent.text().toString())\n                        .filter(s -&gt; s.length() &gt;= MIN_LENGTH_TO_START)\n                        .observeOn(Schedulers.io())\n                        .switchMap(s -&gt; {\n                            return MGApiClient.getApiClient().create(MGApiInterface.class)\n                                    .getAutoComplete(\n                                    getString(R.string.mgapi_key),\n                                    s,\n                                    5,\n                                    0);\n                        })\n                        .observeOn(AndroidSchedulers.mainThread())\n                        .retry(1);\n\n        compositeDisposable.add(\n                autocompleteResponseObservable.subscribe(\n                        autoCompleteResponse -&gt; {\n                            List&lt;AutoCompleteItem&gt; list = autoCompleteResponse.getData();\n\n                            List&lt;String&gt; items = new ArrayList&lt;&gt;();\n                            for (AutoCompleteItem item : list) {\n                                items.add(item.getSearchString());\n                            }\n\n                            autoCompleteTextView.setAdapter(new ArrayAdapter&lt;&gt;(this,\n                                    android.R.layout.simple_dropdown_item_1line, items));\n\n                            String enteredText = autoCompleteTextView.getText().toString();\n                            if (list.size() == 1 &amp;&amp; enteredText.equals(list.get(0).getSearchString())) {\n                                autoCompleteTextView.dismissDropDown();\n                            } else {\n                                autoCompleteTextView.showDropDown();\n                            }\n                        },\n                        e -&gt; Log.e(TAG, &quot;onError&quot;, e),\n                        () -&gt; Log.i(TAG, &quot;onCompleted&quot;)));\n    }<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>RxJava Retrofit2 Autocomplete \ucc38\uc8701 \ucc38\uc8702 \ucc38\uc8702 \ub97c \uae30\uc900\uc73c\ub85c \uc124\uba85\ud569\ub2c8\ub2e4. \ucc38\uc8702\uc5d0\uc11c \uc124\uba85\ub41c \ub0b4\uc6a9\uc740 \uc911\ubcf5\uc73c\ub85c \uc124\uba85\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uc758\uc874\uc131 \ucd94\uac00 dependencies { implementation &#039;com.squareup.retrofit2:retrofit:2.9.0&#039; implementation &#039;com.squareup.retrofit2:converter-gson:2.9.0&#039; implementation &quot;com.squareup.retrofit2:adapter-rxjava2:2.4.0&quot; implementation &#039;com.squareup.okhttp3:logging-interceptor:4.2.1&#039; implementation &#039;io.reactivex.rxjava2:rxjava:2.2.21&#039; implementation &#039;io.reactivex.rxjava2:rxandroid:2.1.1&#039; implementation &#039;com.jakewharton.rxbinding2:rxbinding:2.0.0&#039; } \ud074\ub77c\uc774\uc5b8\ud2b8 addCallAdapterFactory \ub97c \ucd94\uac00\ud569\ub2c8\ub2e4. public class MGApiClient { private static final String BASE_URL = &quot;https:\/\/&lt;API \uc11c\ubc84 \uc544\uc774\ud53c&gt;\/&quot;; private static Retrofit retrofit;\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=3766\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,33,1],"tags":[],"class_list":["post-3766","post","type-post","status-publish","format-standard","hentry","category-java","category-rxjava","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/3766","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3766"}],"version-history":[{"count":4,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/3766\/revisions"}],"predecessor-version":[{"id":3777,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/3766\/revisions\/3777"}],"wp:attachment":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3766"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3766"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3766"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}