Skip to content

Commit

Permalink
Rx SearchView
Browse files Browse the repository at this point in the history
#11
- CheeseActivity.java with Rx search implementation
  • Loading branch information
eurosecom committed Mar 22, 2017
1 parent 74980d8 commit fe3c010
Show file tree
Hide file tree
Showing 10 changed files with 818 additions and 3 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<activity android:name=".SettingsActivity"/>
<activity android:name=".MapActivity"/>
<activity android:name=".RxbusActivity"/>
<activity android:name=".CheeseActivity"/>



Expand Down
163 changes: 163 additions & 0 deletions app/src/main/java/com/eusecom/attendance/CheeseActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2016 Razeware LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.eusecom.attendance;

import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;

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

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Cancellable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;

//by https://www.raywenderlich.com/141980/rxandroid-tutorial

public class CheeseActivity extends CheeseBaseSearchActivity {

private Disposable mDisposable;

@Override
protected void onStart() {
super.onStart();

Observable<String> buttonClickStream = createButtonClickObservable();
Observable<String> textChangeStream = createTextChangeObservable();

Observable<String> searchTextObservable = Observable.merge(textChangeStream, buttonClickStream);

mDisposable = searchTextObservable // change this line
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(new Consumer<String>() {
@Override
public void accept(String s) {
showProgressBar();
}
})
.observeOn(Schedulers.io())
.map(new Function<String, List<String>>() {
@Override
public List<String> apply(String query) {
return mCheeseSearchEngine.search(query);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<String>>() {
@Override
public void accept(List<String> result) {
hideProgressBar();
showResult(result);
}
});
}

@Override
protected void onStop() {
super.onStop();
if (!mDisposable.isDisposed()) {
mDisposable.dispose();
}
}

// 1
private Observable<String> createButtonClickObservable() {

// 2
return Observable.create(new ObservableOnSubscribe<String>() {

// 3
@Override
public void subscribe(final ObservableEmitter<String> emitter) throws Exception {
// 4
mSearchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 5
emitter.onNext(mQueryEditText.getText().toString());
}
});

// 6
emitter.setCancellable(new Cancellable() {
@Override
public void cancel() throws Exception {
// 7
mSearchButton.setOnClickListener(null);
}
});
}
});
}

//1
private Observable<String> createTextChangeObservable() {
//2
Observable<String> textChangeObservable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(final ObservableEmitter<String> emitter) throws Exception {
//3
final TextWatcher watcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

@Override
public void afterTextChanged(Editable s) {}

//4
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
emitter.onNext(s.toString());
}
};

//5
mQueryEditText.addTextChangedListener(watcher);

//6
emitter.setCancellable(new Cancellable() {
@Override
public void cancel() throws Exception {
mQueryEditText.removeTextChangedListener(watcher);
}
});
}
});

return textChangeObservable
.filter(new Predicate<String>() {
@Override
public boolean test(String query) throws Exception {
return query.length() >= 2;
}
}).debounce(1000, TimeUnit.MILLISECONDS); // add this line
}
}
67 changes: 67 additions & 0 deletions app/src/main/java/com/eusecom/attendance/CheeseAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2016 Razeware LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.eusecom.attendance;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

public class CheeseAdapter extends RecyclerView.Adapter<CheeseAdapter.CheeseViewHolder> {

private List<String> mCheeses;

@Override
public CheeseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
return new CheeseViewHolder(view);
}

@Override
public void onBindViewHolder(CheeseViewHolder holder, int position) {
holder.title.setText(mCheeses.get(position));
}

@Override
public int getItemCount() {
return mCheeses == null ? 0 : mCheeses.size();
}

public void setCheeses(List<String> cheeses) {
mCheeses = cheeses;
notifyDataSetChanged();
}

public static class CheeseViewHolder extends RecyclerView.ViewHolder {
public final TextView title;

public CheeseViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(android.R.id.text1);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2016 Razeware LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.eusecom.attendance;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public abstract class CheeseBaseSearchActivity extends AppCompatActivity {

protected CheeseSearchEngine mCheeseSearchEngine;
protected EditText mQueryEditText;
protected Button mSearchButton;
private CheeseAdapter mAdapter;
private ProgressBar mProgressBar;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheeses);

RecyclerView list = (RecyclerView) findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setAdapter(mAdapter = new CheeseAdapter());

mQueryEditText = (EditText) findViewById(R.id.query_edit_text);
mSearchButton = (Button) findViewById(R.id.search_button);
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);

List<String> cheeses = Arrays.asList(getResources().getStringArray(R.array.cheeses));
mCheeseSearchEngine = new CheeseSearchEngine(cheeses);
}

protected void showProgressBar() {
mProgressBar.setVisibility(View.VISIBLE);
}

protected void hideProgressBar() {
mProgressBar.setVisibility(View.GONE);
}

protected void showResult(List<String> result) {
if (result.isEmpty()) {
Toast.makeText(this, R.string.nothing_found, Toast.LENGTH_SHORT).show();
mAdapter.setCheeses(Collections.<String>emptyList());
} else {
mAdapter.setCheeses(result);
}
}

}
58 changes: 58 additions & 0 deletions app/src/main/java/com/eusecom/attendance/CheeseSearchEngine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2016 Razeware LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.eusecom.attendance;

import java.util.LinkedList;
import java.util.List;

public class CheeseSearchEngine {

private final List<String> mCheeses;
private final int mCheesesCount;

public CheeseSearchEngine(List<String> cheeses) {
mCheeses = cheeses;
mCheesesCount = mCheeses.size();
}

public List<String> search(String query) {
query = query.toLowerCase();

try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}

List<String> result = new LinkedList<>();

for (int i = 0; i < mCheesesCount; i++) {
if (mCheeses.get(i).toLowerCase().contains(query)) {
result.add(mCheeses.get(i));
}
}

return result;
}

}
4 changes: 2 additions & 2 deletions app/src/main/java/com/eusecom/attendance/MyAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ public void onClick(View v, int pos, boolean isLongClick) {
case 6:

// View v at position pos is clicked.
//Intent i6 = new Intent(mContext, CustomAuthActivity.class);
//v.getContext().startActivity(i6);
Intent i6 = new Intent(mContext, CheeseActivity.class);
v.getContext().startActivity(i6);

break;

Expand Down
Loading

0 comments on commit fe3c010

Please sign in to comment.