Skip to content
Merged
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ tmp
*.tgz
*.lock
*.lck
*.zip
Binary file added MaterialSearchView.zip
Binary file not shown.
Binary file added MaterialSearchViewSample.zip
Binary file not shown.
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
classpath 'com.android.tools.build:gradle:4.0.1'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand All @@ -15,5 +16,6 @@ buildscript {
allprojects {
repositories {
jcenter()
google()
}
}
4 changes: 3 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# org.gradle.parallel=true
android.enableJetifier=true
android.useAndroidX=true
30 changes: 18 additions & 12 deletions library/build.gradle
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
apply plugin: 'com.android.library'
apply plugin: 'com.novoda.bintray-release'
//apply plugin: 'com.novoda.bintray-release'

buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.novoda:bintray-release:0.3.4'
//classpath 'com.novoda:bintray-release:0.9.2'
classpath 'com.android.tools.build:gradle:4.0.1'
}
}

android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
compileSdkVersion 29
buildToolsVersion "29.0.2"

defaultConfig {
minSdkVersion 14
targetSdkVersion 23
minSdkVersion 22
targetSdkVersion 29
versionCode 1
versionName "1.4.0"
}
Expand All @@ -26,19 +28,23 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
api fileTree(dir: 'libs', include: ['*.jar'])
api 'androidx.appcompat:appcompat:1.1.0'
api 'com.google.android.material:material:1.1.0'
}

publish {
/*publish {
userOrg = 'miguelcatalan'
groupId = 'com.miguelcatalan'
artifactId = 'materialsearchview'
publishVersion = '1.4.0'
publishVersion = '1.5.0'
desc = 'Cute library to implement SearchView in a Material Design Approach'
website = 'https://github.com/MiguelCatalan/MaterialSearchView'
}
}*/
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.TypedArray;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
Expand Down Expand Up @@ -34,6 +35,10 @@
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;

import com.miguelcatalan.materialsearchview.utils.AnimationUtil;

import java.lang.reflect.Field;
Expand All @@ -45,7 +50,7 @@
public class MaterialSearchView extends FrameLayout implements Filter.FilterListener {
public static final int REQUEST_VOICE = 9999;

private MenuItem mMenuItem;
//private MenuItem mMenuItem;
private boolean mIsSearchOpen = false;
private int mAnimationDuration;
private boolean mClearingFocus;
Expand Down Expand Up @@ -169,6 +174,7 @@ private void initiateView() {
initSearchView();

mSuggestionsListView.setVisibility(GONE);
mTintView.setVisibility(VISIBLE);
setAnimationDuration(AnimationUtil.ANIMATION_DURATION_MEDIUM);
}

Expand Down Expand Up @@ -279,7 +285,7 @@ private boolean isVoiceAvailable() {
PackageManager pm = getContext().getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(
new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
return activities.size() == 0;
return activities.size() != 0;
}

public void hideKeyboard(View view) {
Expand Down Expand Up @@ -363,6 +369,31 @@ public void setCursorDrawable(int drawable) {
}
}

public void setCursorColor(@ColorInt int color) {
try {
// Get the cursor resource id
Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
field.setAccessible(true);
int drawableResId = field.getInt(mSearchSrcTextView);

// Get the editor
field = TextView.class.getDeclaredField("mEditor");
field.setAccessible(true);
Object editor = field.get(mSearchSrcTextView);

// Get the drawable and set a color filter
Drawable drawable = ContextCompat.getDrawable(mSearchSrcTextView.getContext(), drawableResId);
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
Drawable[] drawables = {drawable, drawable};

// Set the drawables
field = editor.getClass().getDeclaredField("mCursorDrawable");
field.setAccessible(true);
field.set(editor, drawables);
} catch (Exception ignored) {
}
}

public void setVoiceSearch(boolean voiceSearch) {
allowVoiceSearch = voiceSearch;
}
Expand Down Expand Up @@ -415,15 +446,22 @@ public void setAdapter(ListAdapter adapter) {
public void setSuggestions(String[] suggestions) {
if (suggestions != null && suggestions.length > 0) {
mTintView.setVisibility(VISIBLE);
final SearchAdapter adapter = new SearchAdapter(mContext, suggestions, suggestionIcon, ellipsize);
final SearchAdapter adapter = new SearchAdapter(mContext, suggestions, suggestionIcon, ellipsize, false);
setAdapter(adapter);

setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setQuery((String) adapter.getItem(position), submit);
}
});
setOnItemClickListener((parent, view, position, id) -> setQuery((String) adapter.getItem(position), submit));
} else {
mTintView.setVisibility(GONE);
}
}

public void setSuggestions(String[] suggestions, boolean checkSuggestion) {
if (suggestions != null && suggestions.length > 0) {
mTintView.setVisibility(VISIBLE);
final SearchAdapter adapter = new SearchAdapter(mContext, suggestions, suggestionIcon, ellipsize, checkSuggestion);
setAdapter(adapter);

setOnItemClickListener((parent, view, position, id) -> setQuery((String) adapter.getItem(position), submit));
} else {
mTintView.setVisibility(GONE);
}
Expand All @@ -438,7 +476,6 @@ public void dismissSuggestions() {
}
}


/**
* Calling this will set the query to search text box. if submit is true, it'll submit the query.
*
Expand Down Expand Up @@ -475,8 +512,7 @@ public void showVoice(boolean show) {
* @param menuItem
*/
public void setMenuItem(MenuItem menuItem) {
this.mMenuItem = menuItem;
mMenuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
showSearch();
Expand Down Expand Up @@ -515,6 +551,7 @@ public void showSearch() {
*
* @param animate true for animate
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void showSearch(boolean animate) {
if (isSearchOpen()) {
return;
Expand All @@ -536,6 +573,7 @@ public void showSearch(boolean animate) {
mIsSearchOpen = true;
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void setVisibleWithAnimation() {
AnimationUtil.AnimationListener animationListener = new AnimationUtil.AnimationListener() {
@Override
Expand All @@ -557,13 +595,8 @@ public boolean onAnimationCancel(View view) {
}
};

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mSearchLayout.setVisibility(View.VISIBLE);
AnimationUtil.reveal(mSearchTopBar, animationListener);

} else {
AnimationUtil.fadeInView(mSearchLayout, mAnimationDuration, animationListener);
}
mSearchLayout.setVisibility(View.VISIBLE);
AnimationUtil.reveal(mSearchTopBar, animationListener, mAnimationDuration);
}

/**
Expand All @@ -574,15 +607,45 @@ public void closeSearch() {
return;
}

mSearchSrcTextView.setText(null);
dismissSuggestions();
clearFocus();
AnimationUtil.AnimationListener animationListener = new AnimationUtil.AnimationListener(){

@Override
public boolean onAnimationStart(View view) {
return false;
}

@Override
public boolean onAnimationEnd(View view) {
mSearchSrcTextView.setText(null);
dismissSuggestions();
clearFocus();

mSearchLayout.setVisibility(GONE);
if (mSearchViewListener != null) {
mSearchViewListener.onSearchViewClosed();
}
mIsSearchOpen = false;

return false;
}

@Override
public boolean onAnimationCancel(View view) {
return false;
}
};


mSearchLayout.setVisibility(GONE);
if (mSearchViewListener != null) {
mSearchViewListener.onSearchViewClosed();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mSearchLayout.setVisibility(View.VISIBLE);
AnimationUtil.hide(mSearchTopBar, animationListener);

} else {
mSearchLayout.setVisibility(VISIBLE);
AnimationUtil.fadeOutView(mSearchLayout, AnimationUtil.ANIMATION_DURATION_MEDIUM, animationListener);
}
mIsSearchOpen = false;



}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,21 @@ public class SearchAdapter extends BaseAdapter implements Filterable {
private Drawable suggestionIcon;
private LayoutInflater inflater;
private boolean ellipsize;
private boolean checkWholeString;

public SearchAdapter(Context context, String[] suggestions) {
inflater = LayoutInflater.from(context);
data = new ArrayList<>();
this.suggestions = suggestions;
}

public SearchAdapter(Context context, String[] suggestions, Drawable suggestionIcon, boolean ellipsize) {
public SearchAdapter(Context context, String[] suggestions, Drawable suggestionIcon, boolean ellipsize, boolean checkWholeString) {
inflater = LayoutInflater.from(context);
data = new ArrayList<>();
this.suggestions = suggestions;
this.suggestionIcon = suggestionIcon;
this.ellipsize = ellipsize;
this.checkWholeString = checkWholeString;
}

@Override
Expand All @@ -54,8 +56,14 @@ protected FilterResults performFiltering(CharSequence constraint) {
List<String> searchData = new ArrayList<>();

for (String string : suggestions) {
if (string.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
searchData.add(string);
if(checkWholeString){
if(string.toLowerCase().contains(constraint.toString().toLowerCase())){
searchData.add(string);
}
} else {
if (string.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
searchData.add(string);
}
}
}

Expand Down Expand Up @@ -122,9 +130,9 @@ private class SuggestionsViewHolder {
ImageView imageView;

public SuggestionsViewHolder(View convertView) {
textView = (TextView) convertView.findViewById(R.id.suggestion_text);
textView = convertView.findViewById(R.id.suggestion_text);
if (suggestionIcon != null) {
imageView = (ImageView) convertView.findViewById(R.id.suggestion_icon);
imageView = convertView.findViewById(R.id.suggestion_icon);
imageView.setImageDrawable(suggestionIcon);
}
}
Expand Down
Loading