Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion autocomplete/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'

// Required by bintray
version = '1.0.2'
version = '1.0.3'
group = 'com.otaliastudios'

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,14 @@ public void click(T item) {
* There is rarely need to call this externally: it is already triggered by events on the anchor.
* To control when this is called, provide a good implementation of {@link AutocompletePolicy}.
*
* @param query query text.
* @param query query object.
*/
public void showPopup(CharSequence query) {
if (isPopupShowing() && lastQuery.equals(query.toString())) return;
lastQuery = query.toString();
public void showPopup(Query query) {
CharSequence queryCharSequence = query.getCharSequence();
if (isPopupShowing() && lastQuery.equals(queryCharSequence.toString())) return;
lastQuery = queryCharSequence.toString();

log("showPopup: called with filter "+query);
log("showPopup: called with filter " + queryCharSequence);
if (!isPopupShowing()) {
log("showPopup: showing");
presenter.registerDataSetObserver(new Observer()); // Calling new to avoid leaking... maybe...
Expand Down Expand Up @@ -387,7 +388,13 @@ public void run() {
* Popup is shown when text length is bigger than 0, and hidden when text is empty.
* The query string is the whole text.
*/
public static class SimplePolicy implements AutocompletePolicy {
public static class SimplePolicy implements AutocompletePolicy<CharQuery> {
private final CharQuery charQuery;

public SimplePolicy() {
this.charQuery = new CharQuery();
}

@Override
public boolean shouldShowPopup(Spannable text, int cursorPos) {
return text.length() > 0;
Expand All @@ -399,8 +406,9 @@ public boolean shouldDismissPopup(Spannable text, int cursorPos) {
}

@Override
public CharSequence getQuery(Spannable text) {
return text;
public CharQuery getQuery(Spannable text) {
charQuery.setCharSequence(text);
return charQuery;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*
* @see Autocomplete.SimplePolicy for the simplest possible implementation
*/
public interface AutocompletePolicy {
public interface AutocompletePolicy<T extends Query> {

/**
* Called to understand whether the popup should be shown. Some naive examples:
Expand Down Expand Up @@ -49,7 +49,7 @@ public interface AutocompletePolicy {
* @param text current text, along with its Spans
* @return the query for presenter
*/
CharSequence getQuery(Spannable text);
T getQuery(Spannable text);

/**
* Called when popup is dismissed. This can be used, for instance, to clear custom Spans
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/**
* Base class for presenting items inside a popup. This is abstract and must be implemented.
*
* Most important methods are {@link #getView()} and {@link #onQuery(CharSequence)}.
* Most important methods are {@link #getView()} and {@link #onQuery(Query)}.
*/
public abstract class AutocompletePresenter<T> {

Expand Down Expand Up @@ -73,7 +73,7 @@ protected PopupDimensions getPopupDimensions() {
*
* @param query query from the edit text, to filter our results
*/
protected abstract void onQuery(@Nullable CharSequence query);
protected abstract void onQuery(@Nullable Query query);

/**
* Called when the popup is hidden, to release resources.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.otaliastudios.autocomplete;

import android.support.annotation.CallSuper;
import android.support.annotation.Nullable;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Log;


Expand All @@ -18,7 +16,7 @@
* - text "You should see this @j" : presenter will be passed the query "j"
* - text "You should see this @john @m" : presenter will be passed the query "m"
*/
public class CharPolicy implements AutocompletePolicy {
public class CharPolicy implements AutocompletePolicy<CharQuery> {

private final static String TAG = CharPolicy.class.getSimpleName();
private final static boolean DEBUG = false;
Expand All @@ -29,15 +27,16 @@ private static void log(String log) {

private final char CH;
private final int[] INT = new int[2];
private boolean needSpaceBefore = true;
private final CharQuery charQuery;
private boolean needSpaceBefore;

/**
* Constructs a char policy for the given character.
*
* @param trigger the triggering character.
*/
public CharPolicy(char trigger) {
CH = trigger;
this(trigger, true);
}

/**
Expand All @@ -49,6 +48,7 @@ public CharPolicy(char trigger) {
*/
public CharPolicy(char trigger, boolean needSpaceBefore) {
CH = trigger;
charQuery = new CharQuery();
this.needSpaceBefore = needSpaceBefore;
}

Expand Down Expand Up @@ -133,20 +133,22 @@ public boolean shouldDismissPopup(Spannable text, int cursorPos) {
}

@Override
public CharSequence getQuery(Spannable text) {
public CharQuery getQuery(Spannable text) {
QuerySpan[] span = text.getSpans(0, text.length(), QuerySpan.class);
if (span == null || span.length == 0) {
// Should never happen.
log("getQuery: there's no span!");
return "";
charQuery.setCharSequence("");
return charQuery;
}
log("getQuery: found spans: "+span.length);
QuerySpan sp = span[0];
log("getQuery: span start is "+text.getSpanStart(sp));
log("getQuery: span end is "+text.getSpanEnd(sp));
CharSequence seq = text.subSequence(text.getSpanStart(sp), text.getSpanEnd(sp));
log("getQuery: returning "+seq);
return seq;
charQuery.setCharSequence(seq);
return charQuery;
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.otaliastudios.autocomplete;

public class CharQuery implements Query {
private CharSequence charSequence;

public CharQuery() {
}

@Override
public CharSequence getCharSequence() {
return charSequence;
}


public void setCharSequence(CharSequence charSequence) {
this.charSequence = charSequence;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.otaliastudios.autocomplete;

public interface Query {
CharSequence getCharSequence();
}
12 changes: 9 additions & 3 deletions sample/src/main/java/com/otaliastudios/sample/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Spanned;
import android.text.style.StyleSpan;
Expand All @@ -18,12 +18,14 @@
import com.otaliastudios.autocomplete.AutocompletePolicy;
import com.otaliastudios.autocomplete.AutocompletePresenter;
import com.otaliastudios.autocomplete.CharPolicy;
import com.otaliastudios.autocomplete.CharQuery;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Autocomplete userAutocomplete;
private Autocomplete mentionsAutocomplete;
private Autocomplete maleFemaleAutocomplete;
private CharQuery charQuery;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -37,6 +39,8 @@ protected void onCreate(Bundle savedInstanceState) {
setupUserAutocomplete();
setupMentionsAutocomplete();
setupMaleFemaleAutocomplete();

charQuery = new CharQuery();
}

private void setupUserAutocomplete() {
Expand Down Expand Up @@ -130,10 +134,12 @@ public void onPopupVisibilityChanged(boolean shown) {}
public void onClick(View v) {
switch (v.getId()) {
case R.id.single_button:
userAutocomplete.showPopup(" ");
charQuery.setCharSequence(" ");
userAutocomplete.showPopup(charQuery);
break;
case R.id.topbar_button:
maleFemaleAutocomplete.showPopup(" ");
charQuery.setCharSequence(" ");
maleFemaleAutocomplete.showPopup(charQuery);
break;
case R.id.multi_button:
((EditText) findViewById(R.id.multi)).setText("");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.otaliastudios.autocomplete.RecyclerViewPresenter;
import com.otaliastudios.autocomplete.Query;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -20,7 +17,7 @@
public class MaleFemalePresenter extends UserPresenter implements TabLayout.OnTabSelectedListener {

private boolean females;
private CharSequence lastQuery;
private Query lastQuery;

public MaleFemalePresenter(Context context) {
super(context);
Expand All @@ -44,29 +41,31 @@ protected ViewGroup getView() {
}

@Override
protected void onQuery(@Nullable CharSequence query) {
protected void onQuery(@Nullable Query query) {
lastQuery = query;

CharSequence queryCharSequence = query == null ? null : query.getCharSequence();

// First select males/females.
List<User> all = new ArrayList<>();
for (User u : User.USERS) {
if (u.isFemale() == females) all.add(u);
}

// Then filter based on query.
if (TextUtils.isEmpty(query)) {
if (TextUtils.isEmpty(queryCharSequence)) {
adapter.setData(all);
} else {
query = query.toString().toLowerCase();
queryCharSequence = queryCharSequence.toString().toLowerCase();
List<User> list = new ArrayList<>();
for (User u : all) {
if (u.getFullname().toLowerCase().contains(query) ||
u.getUsername().toLowerCase().contains(query)) {
if (u.getFullname().toLowerCase().contains(queryCharSequence) ||
u.getUsername().toLowerCase().contains(queryCharSequence)) {
list.add(u);
}
}
adapter.setData(list);
Log.e("MaleFemalePresenter", "found "+list.size()+" users for query "+query);
Log.e("MaleFemalePresenter", "found " + list.size() + " users for query " + queryCharSequence);
}
adapter.notifyDataSetChanged();
}
Expand Down
18 changes: 9 additions & 9 deletions sample/src/main/java/com/otaliastudios/sample/UserPresenter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.otaliastudios.autocomplete.AutocompletePresenter;
import com.otaliastudios.autocomplete.Query;
import com.otaliastudios.autocomplete.RecyclerViewPresenter;

import java.util.ArrayList;
Expand Down Expand Up @@ -42,21 +40,23 @@ protected RecyclerView.Adapter instantiateAdapter() {
}

@Override
protected void onQuery(@Nullable CharSequence query) {
protected void onQuery(@Nullable Query query) {
CharSequence queryCharSequence = query == null ? null : query.getCharSequence();

List<User> all = User.USERS;
if (TextUtils.isEmpty(query)) {
if (TextUtils.isEmpty(queryCharSequence)) {
adapter.setData(all);
} else {
query = query.toString().toLowerCase();
queryCharSequence = queryCharSequence.toString().toLowerCase();
List<User> list = new ArrayList<>();
for (User u : all) {
if (u.getFullname().toLowerCase().contains(query) ||
u.getUsername().toLowerCase().contains(query)) {
if (u.getFullname().toLowerCase().contains(queryCharSequence) ||
u.getUsername().toLowerCase().contains(queryCharSequence)) {
list.add(u);
}
}
adapter.setData(list);
Log.e("UserPresenter", "found "+list.size()+" users for query "+query);
Log.e("UserPresenter", "found " + list.size() + " users for query " + queryCharSequence);
}
adapter.notifyDataSetChanged();
}
Expand Down