From e39f1965f41be8b89e88342846e6c7030aa74494 Mon Sep 17 00:00:00 2001 From: Emre Hamurcu Date: Wed, 13 May 2020 17:15:55 +0300 Subject: [PATCH 1/6] #Migrate to androidx #Add view issue solved --- build.gradle | 15 +- gradle.properties | 2 + gradle/wrapper/gradle-wrapper.properties | 4 +- library/build.gradle | 26 ++-- .../ExampleInstrumentedTest.java | 4 +- .../com/pchmn/materialchips/ChipView.java | 103 ++++++------- .../com/pchmn/materialchips/ChipsInput.java | 59 ++++---- .../materialchips/adapter/ChipsAdapter.java | 84 +++++------ .../adapter/FilterableAdapter.java | 140 +++++++++--------- .../com/pchmn/materialchips/model/Chip.java | 5 +- .../pchmn/materialchips/util/ColorUtil.java | 10 +- .../util/LetterTileProvider.java | 126 +++++++++------- .../materialchips/util/MyWindowCallback.java | 5 +- .../pchmn/materialchips/util/ViewUtil.java | 15 +- .../views/ChipsInputEditText.java | 3 +- .../materialchips/views/DetailedChipView.java | 105 +++++++------ .../views/FilterableListView.java | 24 +-- .../views/ScrollViewMaxHeight.java | 6 +- library/src/main/res/layout/chip_view.xml | 17 +-- library/src/main/res/layout/chips_input.xml | 4 +- .../main/res/layout/detailed_chip_view.xml | 38 ++--- .../main/res/layout/item_list_filterable.xml | 22 +-- .../main/res/layout/list_filterable_view.xml | 6 +- sample/build.gradle | 28 ++-- .../ExampleInstrumentedTest.java | 4 +- .../ChipExamplesActivity.java | 5 +- .../ContactListActivity.java | 2 +- .../materialchipsinput/MainActivity.java | 6 +- .../materialchipsinput/MyDialogFragment.java | 2 +- 29 files changed, 447 insertions(+), 423 deletions(-) diff --git a/build.gradle b/build.gradle index 64dc55d3..b72671fd 100644 --- a/build.gradle +++ b/build.gradle @@ -4,15 +4,20 @@ buildscript { repositories { jcenter() mavenCentral() + maven { + url 'https://maven.google.com/' + name 'Google' + } + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:3.6.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files - classpath 'com.jakewharton:butterknife-gradle-plugin:8.5.1' + classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.1' classpath 'me.tatarka:gradle-retrolambda:3.6.0' - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } } @@ -20,6 +25,10 @@ allprojects { repositories { jcenter() mavenCentral() + maven { + url 'https://maven.google.com/' + name 'Google' + } } } diff --git a/gradle.properties b/gradle.properties index aac7c9b4..9e6fce10 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,6 +9,8 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. +android.enableJetifier=true +android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7f3b2ff9..1e6bca49 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Mar 28 20:31:03 CEST 2017 +#Wed May 13 16:38:42 EET 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip diff --git a/library/build.gradle b/library/build.gradle index 974cc24f..5748a6ea 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -2,16 +2,16 @@ apply plugin: 'com.android.library' apply plugin: 'com.jakewharton.butterknife' android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 29 + buildToolsVersion '29.0.0' defaultConfig { minSdkVersion 15 - targetSdkVersion 25 + targetSdkVersion 29 versionCode 9 versionName "1.0.8" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -23,23 +23,23 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + implementation fileTree(dir: 'libs', include: ['*.jar']) + androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile 'com.android.support:appcompat-v7:25.3.0' - testCompile 'junit:junit:4.12' + implementation 'androidx.appcompat:appcompat:1.1.0' + testImplementation 'junit:junit:4.13' // recycler - compile 'com.android.support:recyclerview-v7:25.3.0' - compile 'com.beloo.widget:ChipsLayoutManager:0.3.7@aar' + implementation 'androidx.recyclerview:recyclerview:1.1.0' + implementation 'com.beloo.widget:ChipsLayoutManager:0.3.7@aar' // circle image view - compile 'de.hdodenhof:circleimageview:2.1.0' + implementation 'de.hdodenhof:circleimageview:3.1.0' // butter knife - compile 'com.jakewharton:butterknife:8.5.1' - annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1' + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' } apply plugin: 'com.github.dcendents.android-maven' diff --git a/library/src/androidTest/java/com/pchmn/materialchips/ExampleInstrumentedTest.java b/library/src/androidTest/java/com/pchmn/materialchips/ExampleInstrumentedTest.java index a28c3f32..862e2e99 100644 --- a/library/src/androidTest/java/com/pchmn/materialchips/ExampleInstrumentedTest.java +++ b/library/src/androidTest/java/com/pchmn/materialchips/ExampleInstrumentedTest.java @@ -1,8 +1,8 @@ package com.pchmn.materialchips; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/library/src/main/java/com/pchmn/materialchips/ChipView.java b/library/src/main/java/com/pchmn/materialchips/ChipView.java index 07e3aea9..0ee54b8b 100644 --- a/library/src/main/java/com/pchmn/materialchips/ChipView.java +++ b/library/src/main/java/com/pchmn/materialchips/ChipView.java @@ -7,17 +7,16 @@ import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.support.annotation.ColorInt; -import android.support.v4.content.ContextCompat; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; -import com.pchmn.materialchips.model.Chip; +import androidx.annotation.ColorInt; +import androidx.core.content.ContextCompat; + import com.pchmn.materialchips.model.ChipInterface; import com.pchmn.materialchips.util.LetterTileProvider; import com.pchmn.materialchips.util.ViewUtil; @@ -29,15 +28,19 @@ public class ChipView extends RelativeLayout { private static final String TAG = ChipView.class.toString(); - // context - private Context mContext; - // xml elements - @BindView(R2.id.content) LinearLayout mContentLayout; - @BindView(R2.id.icon) CircleImageView mAvatarIconImageView; - @BindView(R2.id.label) TextView mLabelTextView; - @BindView(R2.id.delete_button) ImageButton mDeleteButton; // attributes private static final int NONE = -1; + // xml elements + @BindView(R2.id.content) + LinearLayout mContentLayout; + @BindView(R2.id.icon) + CircleImageView mAvatarIconImageView; + @BindView(R2.id.label) + TextView mLabelTextView; + @BindView(R2.id.delete_button) + ImageButton mDeleteButton; + // context + private Context mContext; private String mLabel; private ColorStateList mLabelColor; private boolean mHasAvatarIcon = false; @@ -64,6 +67,23 @@ public ChipView(Context context, AttributeSet attrs) { init(attrs); } + private static ChipView newInstance(Builder builder) { + ChipView chipView = new ChipView(builder.context); + chipView.mLabel = builder.label; + chipView.mLabelColor = builder.labelColor; + chipView.mHasAvatarIcon = builder.hasAvatarIcon; + chipView.mAvatarIconUri = builder.avatarIconUri; + chipView.mAvatarIconDrawable = builder.avatarIconDrawable; + chipView.mDeletable = builder.deletable; + chipView.mDeleteIcon = builder.deleteIcon; + chipView.mDeleteIconColor = builder.deleteIconColor; + chipView.mBackgroundColor = builder.backgroundColor; + chipView.mChip = builder.chip; + chipView.inflateWithAttributes(); + + return chipView; + } + /** * Inflate the view according to attributes * @@ -78,7 +98,7 @@ private void init(AttributeSet attrs) { mLetterTileProvider = new LetterTileProvider(mContext); // attributes - if(attrs != null) { + if (attrs != null) { TypedArray a = mContext.getTheme().obtainStyledAttributes( attrs, R.styleable.ChipView, @@ -91,17 +111,19 @@ private void init(AttributeSet attrs) { // avatar icon mHasAvatarIcon = a.getBoolean(R.styleable.ChipView_hasAvatarIcon, false); int avatarIconId = a.getResourceId(R.styleable.ChipView_avatarIcon, NONE); - if(avatarIconId != NONE) mAvatarIconDrawable = ContextCompat.getDrawable(mContext, avatarIconId); - if(mAvatarIconDrawable != null) mHasAvatarIcon = true; + if (avatarIconId != NONE) + mAvatarIconDrawable = ContextCompat.getDrawable(mContext, avatarIconId); + if (mAvatarIconDrawable != null) + mHasAvatarIcon = true; // delete icon mDeletable = a.getBoolean(R.styleable.ChipView_deletable, false); mDeleteIconColor = a.getColorStateList(R.styleable.ChipView_deleteIconColor); int deleteIconId = a.getResourceId(R.styleable.ChipView_deleteIcon, NONE); - if(deleteIconId != NONE) mDeleteIcon = ContextCompat.getDrawable(mContext, deleteIconId); + if (deleteIconId != NONE) + mDeleteIcon = ContextCompat.getDrawable(mContext, deleteIconId); // background color mBackgroundColor = a.getColorStateList(R.styleable.ChipView_backgroundColor); - } - finally { + } finally { a.recycle(); } } @@ -116,7 +138,7 @@ private void init(AttributeSet attrs) { private void inflateWithAttributes() { // label setLabel(mLabel); - if(mLabelColor != null) + if (mLabelColor != null) setLabelColor(mLabelColor); // avatar @@ -126,7 +148,7 @@ private void inflateWithAttributes() { setDeletable(mDeletable); // background color - if(mBackgroundColor != null) + if (mBackgroundColor != null) setChipBackgroundColor(mBackgroundColor); } @@ -189,29 +211,28 @@ public void setLabelColor(@ColorInt int color) { public void setHasAvatarIcon(boolean hasAvatarIcon) { mHasAvatarIcon = hasAvatarIcon; - if(!mHasAvatarIcon) { + if (!mHasAvatarIcon) { // hide icon mAvatarIconImageView.setVisibility(GONE); // adjust padding - if(mDeleteButton.getVisibility() == VISIBLE) + if (mDeleteButton.getVisibility() == VISIBLE) mLabelTextView.setPadding(ViewUtil.dpToPx(12), 0, 0, 0); else mLabelTextView.setPadding(ViewUtil.dpToPx(12), 0, ViewUtil.dpToPx(12), 0); - } - else { + } else { // show icon mAvatarIconImageView.setVisibility(VISIBLE); // adjust padding - if(mDeleteButton.getVisibility() == VISIBLE) + if (mDeleteButton.getVisibility() == VISIBLE) mLabelTextView.setPadding(ViewUtil.dpToPx(8), 0, 0, 0); else mLabelTextView.setPadding(ViewUtil.dpToPx(8), 0, ViewUtil.dpToPx(12), 0); // set icon - if(mAvatarIconUri != null) + if (mAvatarIconUri != null) mAvatarIconImageView.setImageURI(mAvatarIconUri); - else if(mAvatarIconDrawable != null) + else if (mAvatarIconDrawable != null) mAvatarIconImageView.setImageDrawable(mAvatarIconDrawable); else mAvatarIconImageView.setImageBitmap(mLetterTileProvider.getLetterTile(getLabel())); @@ -247,28 +268,27 @@ public void setAvatarIcon(Uri avatarUri) { */ public void setDeletable(boolean deletable) { mDeletable = deletable; - if(!mDeletable) { + if (!mDeletable) { // hide delete icon mDeleteButton.setVisibility(GONE); // adjust padding - if(mAvatarIconImageView.getVisibility() == VISIBLE) + if (mAvatarIconImageView.getVisibility() == VISIBLE) mLabelTextView.setPadding(ViewUtil.dpToPx(8), 0, ViewUtil.dpToPx(12), 0); else mLabelTextView.setPadding(ViewUtil.dpToPx(12), 0, ViewUtil.dpToPx(12), 0); - } - else { + } else { // show icon mDeleteButton.setVisibility(VISIBLE); // adjust padding - if(mAvatarIconImageView.getVisibility() == VISIBLE) + if (mAvatarIconImageView.getVisibility() == VISIBLE) mLabelTextView.setPadding(ViewUtil.dpToPx(8), 0, 0, 0); else mLabelTextView.setPadding(ViewUtil.dpToPx(12), 0, 0, 0); // set icon - if(mDeleteIcon != null) + if (mDeleteIcon != null) mDeleteButton.setImageDrawable(mDeleteIcon); - if(mDeleteIconColor != null) + if (mDeleteIconColor != null) mDeleteButton.getDrawable().mutate().setColorFilter(mDeleteIconColor.getDefaultColor(), PorterDuff.Mode.SRC_ATOP); } } @@ -430,21 +450,4 @@ public ChipView build() { return newInstance(this); } } - - private static ChipView newInstance(Builder builder) { - ChipView chipView = new ChipView(builder.context); - chipView.mLabel = builder.label; - chipView.mLabelColor = builder.labelColor; - chipView.mHasAvatarIcon = builder.hasAvatarIcon; - chipView.mAvatarIconUri = builder.avatarIconUri; - chipView.mAvatarIconDrawable = builder.avatarIconDrawable; - chipView.mDeletable = builder.deletable; - chipView.mDeleteIcon = builder.deleteIcon; - chipView.mDeleteIconColor = builder.deleteIconColor; - chipView.mBackgroundColor = builder.backgroundColor; - chipView.mChip = builder.chip; - chipView.inflateWithAttributes(); - - return chipView; - } } diff --git a/library/src/main/java/com/pchmn/materialchips/ChipsInput.java b/library/src/main/java/com/pchmn/materialchips/ChipsInput.java index ba3dbd56..f16ff222 100644 --- a/library/src/main/java/com/pchmn/materialchips/ChipsInput.java +++ b/library/src/main/java/com/pchmn/materialchips/ChipsInput.java @@ -7,11 +7,11 @@ import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.View; -import android.widget.EditText; + +import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.RecyclerView; import com.beloo.widget.chipslayoutmanager.ChipsLayoutManager; import com.pchmn.materialchips.adapter.ChipsAdapter; @@ -34,14 +34,15 @@ public class ChipsInput extends ScrollViewMaxHeight { private static final String TAG = ChipsInput.class.toString(); + // attributes + private static final int NONE = -1; + // xml element + @BindView(R2.id.chips_recycler) + RecyclerView mRecyclerView; // context private Context mContext; - // xml element - @BindView(R2.id.chips_recycler) RecyclerView mRecyclerView; // adapter private ChipsAdapter mChipsAdapter; - // attributes - private static final int NONE = -1; private String mHint; private ColorStateList mHintColor; private ColorStateList mTextColor; @@ -91,7 +92,7 @@ private void init(AttributeSet attrs) { ButterKnife.bind(this, rootView); // attributes - if(attrs != null) { + if (attrs != null) { TypedArray a = mContext.getTheme().obtainStyledAttributes( attrs, R.styleable.ChipsInput, @@ -113,7 +114,8 @@ private void init(AttributeSet attrs) { mChipDeletable = a.getBoolean(R.styleable.ChipsInput_chip_deletable, false); mChipDeleteIconColor = a.getColorStateList(R.styleable.ChipsInput_chip_deleteIconColor); int deleteIconId = a.getResourceId(R.styleable.ChipsInput_chip_deleteIcon, NONE); - if(deleteIconId != NONE) mChipDeleteIcon = ContextCompat.getDrawable(mContext, deleteIconId); + if (deleteIconId != NONE) + mChipDeleteIcon = ContextCompat.getDrawable(mContext, deleteIconId); // chip background color mChipBackgroundColor = a.getColorStateList(R.styleable.ChipsInput_chip_backgroundColor); // show chip detailed @@ -125,8 +127,7 @@ private void init(AttributeSet attrs) { // filterable list mFilterableListBackgroundColor = a.getColorStateList(R.styleable.ChipsInput_filterable_list_backgroundColor); mFilterableListTextColor = a.getColorStateList(R.styleable.ChipsInput_filterable_list_textColor); - } - finally { + } finally { a.recycle(); } } @@ -143,7 +144,7 @@ private void init(AttributeSet attrs) { // set window callback // will hide DetailedOpenView and hide keyboard on touch outside Activity activity = ActivityUtil.scanForActivity(mContext); - if(activity == null) + if (activity == null) throw new ClassCastException("android.view.Context cannot be cast to android.app.Activity"); android.view.Window.Callback mCallBack = (activity).getWindow().getCallback(); @@ -213,9 +214,9 @@ public ChipView getChipView() { public ChipsInputEditText getEditText() { ChipsInputEditText editText = new ChipsInputEditText(mContext); - if(mHintColor != null) + if (mHintColor != null) editText.setHintTextColor(mHintColor); - if(mTextColor != null) + if (mTextColor != null) editText.setTextColor(mTextColor); return editText; @@ -236,25 +237,25 @@ public void addChipsListener(ChipsListener chipsListener) { } public void onChipAdded(ChipInterface chip, int size) { - for(ChipsListener chipsListener: mChipsListenerList) { + for (ChipsListener chipsListener : mChipsListenerList) { chipsListener.onChipAdded(chip, size); } } public void onChipRemoved(ChipInterface chip, int size) { - for(ChipsListener chipsListener: mChipsListenerList) { + for (ChipsListener chipsListener : mChipsListenerList) { chipsListener.onChipRemoved(chip, size); } } public void onTextChanged(CharSequence text) { - if(mChipsListener != null) { - for(ChipsListener chipsListener: mChipsListenerList) { + if (mChipsListener != null) { + for (ChipsListener chipsListener : mChipsListenerList) { chipsListener.onTextChanged(text); } // show filterable list - if(mFilterableListView != null) { - if(text.length() > 0) + if (mFilterableListView != null) { + if (text.length() > 0) mFilterableListView.filterList(text); else mFilterableListView.fadeOut(); @@ -315,15 +316,15 @@ public void setChipBackgroundColor(ColorStateList mBackgroundColor) { this.mChipBackgroundColor = mBackgroundColor; } + public boolean isShowChipDetailed() { + return mShowChipDetailed; + } + public ChipsInput setShowChipDetailed(boolean mShowChipDetailed) { this.mShowChipDetailed = mShowChipDetailed; return this; } - public boolean isShowChipDetailed() { - return mShowChipDetailed; - } - public void setChipDetailedTextColor(ColorStateList mChipDetailedTextColor) { this.mChipDetailedTextColor = mChipDetailedTextColor; } @@ -336,6 +337,10 @@ public void setChipDetailedBackgroundColor(ColorStateList mChipDetailedBackgroun this.mChipDetailedBackgroundColor = mChipDetailedBackgroundColor; } + public List getFilterableList() { + return mChipList; + } + public void setFilterableList(List list) { mChipList = list; mFilterableListView = new FilterableListView(mContext); @@ -343,10 +348,6 @@ public void setFilterableList(List list) { mChipsAdapter.setFilterableListView(mFilterableListView); } - public List getFilterableList() { - return mChipList; - } - public ChipValidator getChipValidator() { return mChipValidator; } @@ -357,7 +358,9 @@ public void setChipValidator(ChipValidator mChipValidator) { public interface ChipsListener { void onChipAdded(ChipInterface chip, int newSize); + void onChipRemoved(ChipInterface chip, int newSize); + void onTextChanged(CharSequence text); } diff --git a/library/src/main/java/com/pchmn/materialchips/adapter/ChipsAdapter.java b/library/src/main/java/com/pchmn/materialchips/adapter/ChipsAdapter.java index 6e000411..79ee017a 100644 --- a/library/src/main/java/com/pchmn/materialchips/adapter/ChipsAdapter.java +++ b/library/src/main/java/com/pchmn/materialchips/adapter/ChipsAdapter.java @@ -2,11 +2,9 @@ import android.content.Context; import android.os.Build; -import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; -import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; @@ -15,13 +13,14 @@ import android.widget.EditText; import android.widget.RelativeLayout; +import androidx.recyclerview.widget.RecyclerView; + import com.pchmn.materialchips.ChipView; import com.pchmn.materialchips.ChipsInput; import com.pchmn.materialchips.model.ChipInterface; +import com.pchmn.materialchips.util.ViewUtil; import com.pchmn.materialchips.views.ChipsInputEditText; import com.pchmn.materialchips.views.DetailedChipView; -import com.pchmn.materialchips.model.Chip; -import com.pchmn.materialchips.util.ViewUtil; import com.pchmn.materialchips.views.FilterableListView; import java.util.ArrayList; @@ -50,29 +49,9 @@ public ChipsAdapter(Context context, ChipsInput chipsInput, RecyclerView recycle initEditText(); } - private class ItemViewHolder extends RecyclerView.ViewHolder { - - private final ChipView chipView; - - ItemViewHolder(View view) { - super(view); - chipView = (ChipView) view; - } - } - - private class EditTextViewHolder extends RecyclerView.ViewHolder { - - private final EditText editText; - - EditTextViewHolder(View view) { - super(view); - editText = (EditText) view; - } - } - @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - if(viewType == TYPE_EDIT_TEXT) + if (viewType == TYPE_EDIT_TEXT) return new EditTextViewHolder(mEditText); else return new ItemViewHolder(mChipsInput.getChipView()); @@ -82,15 +61,15 @@ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { // edit text - if(position == mChipList.size()) { - if(mChipList.size() == 0) + if (position == mChipList.size()) { + if (mChipList.size() == 0) mEditText.setHint(mHintLabel); // auto fit edit text autofitEditText(); } // chip - else if(getItemCount() > 1) { + else if (getItemCount() > 1) { ItemViewHolder itemViewHolder = (ItemViewHolder) holder; itemViewHolder.chipView.inflate(getItem(position)); // handle click @@ -137,10 +116,10 @@ private void initEditText() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { // backspace - if(event.getAction() == KeyEvent.ACTION_DOWN + if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_DEL) { // remove last chip - if(mChipList.size() > 0 && mEditText.getText().toString().length() == 0) + if (mChipList.size() > 0 && mEditText.getText().toString().length() == 0) removeChip(mChipList.size() - 1); } return false; @@ -210,7 +189,7 @@ public void onClick(View v) { }); // show detailed chip - if(mChipsInput.isShowChipDetailed()) { + if (mChipsInput.isShowChipDetailed()) { chipView.setOnChipClicked(new View.OnClickListener() { @Override public void onClick(View v) { @@ -248,13 +227,13 @@ private void setDetailedChipViewPosition(DetailedChipView detailedChipView, int[ layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); // align left window - if(coord[0] <= 0) { + if (coord[0] <= 0) { layoutParams.leftMargin = 0; layoutParams.topMargin = coord[1] - ViewUtil.dpToPx(13); detailedChipView.alignLeft(); } // align right - else if(coord[0] + ViewUtil.dpToPx(300) > windowWidth + ViewUtil.dpToPx(13)) { + else if (coord[0] + ViewUtil.dpToPx(300) > windowWidth + ViewUtil.dpToPx(13)) { layoutParams.leftMargin = windowWidth - ViewUtil.dpToPx(300); layoutParams.topMargin = coord[1] - ViewUtil.dpToPx(13); detailedChipView.alignRight(); @@ -271,12 +250,12 @@ else if(coord[0] + ViewUtil.dpToPx(300) > windowWidth + ViewUtil.dpToPx(13)) { } public void setFilterableListView(FilterableListView filterableListView) { - if(mEditText != null) + if (mEditText != null) mEditText.setFilterableListView(filterableListView); } public void addChip(ChipInterface chip) { - if(!listContains(mChipList, chip)) { + if (!listContains(mChipList, chip)) { mChipList.add(chip); // notify listener mChipsInput.onChipAdded(chip, mChipList.size()); @@ -371,21 +350,40 @@ public List getChipList() { private boolean listContains(List contactList, ChipInterface chip) { - if(mChipsInput.getChipValidator() != null) { - for(ChipInterface item: contactList) { - if(mChipsInput.getChipValidator().areEquals(item, chip)) + if (mChipsInput.getChipValidator() != null) { + for (ChipInterface item : contactList) { + if (mChipsInput.getChipValidator().areEquals(item, chip)) return true; } - } - else { - for(ChipInterface item: contactList) { - if(chip.getId() != null && chip.getId().equals(item.getId())) + } else { + for (ChipInterface item : contactList) { + if (chip.getId() != null && chip.getId().equals(item.getId())) return true; - if(chip.getLabel().equals(item.getLabel())) + if (chip.getLabel().equals(item.getLabel())) return true; } } return false; } + + private class ItemViewHolder extends RecyclerView.ViewHolder { + + private final ChipView chipView; + + ItemViewHolder(View view) { + super(view); + chipView = (ChipView) view; + } + } + + private class EditTextViewHolder extends RecyclerView.ViewHolder { + + private final EditText editText; + + EditTextViewHolder(View view) { + super(view); + editText = (EditText) view; + } + } } diff --git a/library/src/main/java/com/pchmn/materialchips/adapter/FilterableAdapter.java b/library/src/main/java/com/pchmn/materialchips/adapter/FilterableAdapter.java index 5fd1273f..7b417a16 100644 --- a/library/src/main/java/com/pchmn/materialchips/adapter/FilterableAdapter.java +++ b/library/src/main/java/com/pchmn/materialchips/adapter/FilterableAdapter.java @@ -4,29 +4,26 @@ import android.content.Context; import android.content.res.ColorStateList; import android.graphics.PorterDuff; -import android.support.v7.widget.RecyclerView; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Filter; import android.widget.Filterable; import android.widget.TextView; -import android.widget.Toast; + +import androidx.recyclerview.widget.RecyclerView; import com.pchmn.materialchips.ChipsInput; import com.pchmn.materialchips.R; import com.pchmn.materialchips.model.ChipInterface; import com.pchmn.materialchips.util.ColorUtil; import com.pchmn.materialchips.util.LetterTileProvider; -import com.pchmn.materialchips.util.ViewUtil; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -73,8 +70,8 @@ public int compare(ChipInterface o1, ChipInterface o2) { }; // remove chips that do not have label Iterator iterator = chipList.iterator(); - while(iterator.hasNext()) { - if(iterator.next().getLabel() == null) + while (iterator.hasNext()) { + if (iterator.next().getLabel() == null) iterator.remove(); } sortList(chipList); @@ -104,20 +101,6 @@ public void onTextChanged(CharSequence text) { }); } - private class ItemViewHolder extends RecyclerView.ViewHolder { - - private CircleImageView mAvatar; - private TextView mLabel; - private TextView mInfo; - - ItemViewHolder(View view) { - super(view); - mAvatar = (CircleImageView) view.findViewById(R.id.avatar); - mLabel = (TextView) view.findViewById(R.id.label); - mInfo = (TextView) view.findViewById(R.id.info); - } - } - @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.item_list_filterable, parent, false); @@ -130,19 +113,16 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { final ChipInterface chip = getItem(position); // avatar - if(mChipsInput.chipHasAvatarIcon() && chip.getAvatarUri() != null) { + if (mChipsInput.chipHasAvatarIcon() && chip.getAvatarUri() != null) { itemViewHolder.mAvatar.setVisibility(View.VISIBLE); itemViewHolder.mAvatar.setImageURI(chip.getAvatarUri()); - } - else if(mChipsInput.chipHasAvatarIcon() && chip.getAvatarDrawable() != null) { + } else if (mChipsInput.chipHasAvatarIcon() && chip.getAvatarDrawable() != null) { itemViewHolder.mAvatar.setVisibility(View.VISIBLE); itemViewHolder.mAvatar.setImageDrawable(chip.getAvatarDrawable()); - } - else if(mChipsInput.chipHasAvatarIcon()) { + } else if (mChipsInput.chipHasAvatarIcon()) { itemViewHolder.mAvatar.setVisibility(View.VISIBLE); itemViewHolder.mAvatar.setImageBitmap(mLetterTileProvider.getLetterTile(chip.getLabel())); - } - else { + } else { itemViewHolder.mAvatar.setVisibility(GONE); } @@ -150,18 +130,17 @@ else if(mChipsInput.chipHasAvatarIcon()) { itemViewHolder.mLabel.setText(chip.getLabel()); // info - if(chip.getInfo() != null) { + if (chip.getInfo() != null) { itemViewHolder.mInfo.setVisibility(View.VISIBLE); itemViewHolder.mInfo.setText(chip.getInfo()); - } - else { + } else { itemViewHolder.mInfo.setVisibility(GONE); } // colors - if(mBackgroundColor != null) + if (mBackgroundColor != null) itemViewHolder.itemView.getBackground().setColorFilter(mBackgroundColor.getDefaultColor(), PorterDuff.Mode.SRC_ATOP); - if(mTextColor != null) { + if (mTextColor != null) { itemViewHolder.mLabel.setTextColor(mTextColor); itemViewHolder.mInfo.setTextColor(ColorUtil.alpha(mTextColor.getDefaultColor(), 150)); } @@ -170,7 +149,7 @@ else if(mChipsInput.chipHasAvatarIcon()) { itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if(mChipsInput != null) + if (mChipsInput != null) mChipsInput.addChip(chip); } }); @@ -187,11 +166,62 @@ private ChipInterface getItem(int position) { @Override public Filter getFilter() { - if(mFilter == null) + if (mFilter == null) mFilter = new ChipFilter(this, mChipList); return mFilter; } + private void removeChip(ChipInterface chip) { + int position = mFilteredList.indexOf(chip); + if (position >= 0) + mFilteredList.remove(position); + + position = mChipList.indexOf(chip); + if (position >= 0) + mChipList.remove(position); + + notifyDataSetChanged(); + } + + private void addChip(ChipInterface chip) { + if (contains(chip)) { + mChipList.add(chip); + mFilteredList.add(chip); + // sort original list + sortList(mChipList); + // sort filtered list + sortList(mFilteredList); + + notifyDataSetChanged(); + } + } + + private boolean contains(ChipInterface chip) { + for (ChipInterface item : mOriginalList) { + if (item.equals(chip)) + return true; + } + return false; + } + + private void sortList(List list) { + Collections.sort(list, mComparator); + } + + private class ItemViewHolder extends RecyclerView.ViewHolder { + + private CircleImageView mAvatar; + private TextView mLabel; + private TextView mInfo; + + ItemViewHolder(View view) { + super(view); + mAvatar = (CircleImageView) view.findViewById(R.id.avatar); + mLabel = (TextView) view.findViewById(R.id.label); + mInfo = (TextView) view.findViewById(R.id.info); + } + } + private class ChipFilter extends Filter { private FilterableAdapter adapter; @@ -216,8 +246,7 @@ protected FilterResults performFiltering(CharSequence constraint) { for (ChipInterface chip : originalList) { if (chip.getLabel().toLowerCase().contains(filterPattern)) { filteredList.add(chip); - } - else if(chip.getInfo() != null && chip.getInfo().toLowerCase().replaceAll("\\s", "").contains(filterPattern)) { + } else if (chip.getInfo() != null && chip.getInfo().toLowerCase().replaceAll("\\s", "").contains(filterPattern)) { filteredList.add(chip); } } @@ -235,41 +264,4 @@ protected void publishResults(CharSequence constraint, FilterResults results) { notifyDataSetChanged(); } } - - private void removeChip(ChipInterface chip) { - int position = mFilteredList.indexOf(chip); - if (position >= 0) - mFilteredList.remove(position); - - position = mChipList.indexOf(chip); - if(position >= 0) - mChipList.remove(position); - - notifyDataSetChanged(); - } - - private void addChip(ChipInterface chip) { - if(contains(chip)) { - mChipList.add(chip); - mFilteredList.add(chip); - // sort original list - sortList(mChipList); - // sort filtered list - sortList(mFilteredList); - - notifyDataSetChanged(); - } - } - - private boolean contains(ChipInterface chip) { - for(ChipInterface item: mOriginalList) { - if(item.equals(chip)) - return true; - } - return false; - } - - private void sortList(List list) { - Collections.sort(list, mComparator); - } } diff --git a/library/src/main/java/com/pchmn/materialchips/model/Chip.java b/library/src/main/java/com/pchmn/materialchips/model/Chip.java index 892e9366..93184443 100644 --- a/library/src/main/java/com/pchmn/materialchips/model/Chip.java +++ b/library/src/main/java/com/pchmn/materialchips/model/Chip.java @@ -3,8 +3,9 @@ import android.graphics.drawable.Drawable; import android.net.Uri; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; public class Chip implements ChipInterface { diff --git a/library/src/main/java/com/pchmn/materialchips/util/ColorUtil.java b/library/src/main/java/com/pchmn/materialchips/util/ColorUtil.java index c1b118c1..bb762bef 100644 --- a/library/src/main/java/com/pchmn/materialchips/util/ColorUtil.java +++ b/library/src/main/java/com/pchmn/materialchips/util/ColorUtil.java @@ -25,14 +25,14 @@ public static int alpha(int color, int alpha) { return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)); } - public static boolean isColorDark(int color){ - double darkness = 1 - (0.2126*Color.red(color) + 0.7152*Color.green(color) + 0.0722*Color.blue(color))/255; + public static boolean isColorDark(int color) { + double darkness = 1 - (0.2126 * Color.red(color) + 0.7152 * Color.green(color) + 0.0722 * Color.blue(color)) / 255; return darkness >= 0.5; } - public static int getThemeAccentColor (final Context context) { - final TypedValue value = new TypedValue (); - context.getTheme ().resolveAttribute (R.attr.colorAccent, value, true); + public static int getThemeAccentColor(final Context context) { + final TypedValue value = new TypedValue(); + context.getTheme().resolveAttribute(R.attr.colorAccent, value, true); return value.data; } } diff --git a/library/src/main/java/com/pchmn/materialchips/util/LetterTileProvider.java b/library/src/main/java/com/pchmn/materialchips/util/LetterTileProvider.java index 9028a528..00451bcc 100644 --- a/library/src/main/java/com/pchmn/materialchips/util/LetterTileProvider.java +++ b/library/src/main/java/com/pchmn/materialchips/util/LetterTileProvider.java @@ -4,7 +4,6 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; @@ -14,9 +13,9 @@ import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import android.support.v4.content.ContextCompat; import android.text.TextPaint; -import android.util.Log; + +import androidx.core.content.ContextCompat; import com.pchmn.materialchips.R; @@ -27,28 +26,48 @@ */ public class LetterTileProvider { - /** The number of available tile colors (see R.array.letter_tile_colors) */ + /** + * The number of available tile colors (see R.array.letter_tile_colors) + */ private static final int NUM_OF_TILE_COLORS = 8; - /** The {@link TextPaint} used to draw the letter onto the tile */ + /** + * The {@link TextPaint} used to draw the letter onto the tile + */ private final TextPaint mPaint = new TextPaint(); - /** The bounds that enclose the letter */ + /** + * The bounds that enclose the letter + */ private final Rect mBounds = new Rect(); - /** The {@link Canvas} to draw on */ + /** + * The {@link Canvas} to draw on + */ private final Canvas mCanvas = new Canvas(); - /** The first char of the name being displayed */ + /** + * The first char of the name being displayed + */ private final char[] mFirstChar = new char[1]; - /** The background colors of the tile */ + /** + * The background colors of the tile + */ private final TypedArray mColors; - /** The font size used to display the letter */ + /** + * The font size used to display the letter + */ private final int mTileLetterFontSize; - /** The default image to display */ + /** + * The default image to display + */ private final Bitmap mDefaultBitmap; - /** Width */ + /** + * Width + */ private final int mWidth; - /** Height */ + /** + * Height + */ private final int mHeight; /** @@ -73,15 +92,47 @@ public LetterTileProvider(Context context) { mHeight = res.getDimensionPixelSize(R.dimen.letter_tile_size); } + /** + * @param c The char to check + * @return True if c is in the English alphabet or is a digit, + * false otherwise + */ + private static boolean isLetterOrDigit(char c) { + //return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9'; + return Character.isLetterOrDigit(c); + } + + public static Bitmap drawableToBitmap(Drawable drawable) { + Bitmap bitmap = null; + + if (drawable instanceof BitmapDrawable) { + BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; + if (bitmapDrawable.getBitmap() != null) { + return bitmapDrawable.getBitmap(); + } + } + + if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) { + bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel + } else { + bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + } + + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + return bitmap; + } + /** * @param displayName The name used to create the letter for the tile * @return A {@link Bitmap} that contains a letter used in the English - * alphabet or digit, if there is no letter or digit available, a - * default image is shown instead + * alphabet or digit, if there is no letter or digit available, a + * default image is shown instead */ public Bitmap getLetterTile(String displayName) { // workaround - if(displayName == null || displayName.length() == 0) + if (displayName == null || displayName.length() == 0) return null; final Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); @@ -98,8 +149,7 @@ public Bitmap getLetterTile(String displayName) { mPaint.getTextBounds(mFirstChar, 0, 1, mBounds); c.drawText(mFirstChar, 0, 1, mWidth / 2, mHeight / 2 + (mBounds.bottom - mBounds.top) / 2, mPaint); - } - else { + } else { // (32 - 24) / 2 = 4 c.drawBitmap(mDefaultBitmap, ViewUtil.dpToPx(4), ViewUtil.dpToPx(4), null); } @@ -109,12 +159,12 @@ public Bitmap getLetterTile(String displayName) { /** * @param displayName The name used to create the letter for the tile * @return A circular {@link Bitmap} that contains a letter used in the English - * alphabet or digit, if there is no letter or digit available, a - * default image is shown instead + * alphabet or digit, if there is no letter or digit available, a + * default image is shown instead */ public Bitmap getCircularLetterTile(String displayName) { // workaround - if(displayName == null || displayName.length() == 0) + if (displayName == null || displayName.length() == 0) displayName = "."; final Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); @@ -137,20 +187,10 @@ public Bitmap getCircularLetterTile(String displayName) { return getCircularBitmap(bitmap); } - /** - * @param c The char to check - * @return True if c is in the English alphabet or is a digit, - * false otherwise - */ - private static boolean isLetterOrDigit(char c) { - //return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9'; - return Character.isLetterOrDigit(c); - } - /** * @param key The key used to generate the tile color * @return A new or previously chosen color for key used as the - * tile background color + * tile background color */ private int pickColor(String key) { // String.hashCode() is not supposed to change across java versions, so @@ -196,26 +236,4 @@ private Bitmap getCircularBitmap(Bitmap bitmap) { return output; } - public static Bitmap drawableToBitmap (Drawable drawable) { - Bitmap bitmap = null; - - if (drawable instanceof BitmapDrawable) { - BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; - if(bitmapDrawable.getBitmap() != null) { - return bitmapDrawable.getBitmap(); - } - } - - if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) { - bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel - } else { - bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); - } - - Canvas canvas = new Canvas(bitmap); - drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); - drawable.draw(canvas); - return bitmap; - } - } diff --git a/library/src/main/java/com/pchmn/materialchips/util/MyWindowCallback.java b/library/src/main/java/com/pchmn/materialchips/util/MyWindowCallback.java index 92435080..8e3e1474 100644 --- a/library/src/main/java/com/pchmn/materialchips/util/MyWindowCallback.java +++ b/library/src/main/java/com/pchmn/materialchips/util/MyWindowCallback.java @@ -4,8 +4,8 @@ import android.content.Context; import android.graphics.Rect; import android.os.Build; -import android.support.annotation.Nullable; -import android.support.annotation.RequiresApi; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import android.view.ActionMode; import android.view.KeyEvent; import android.view.Menu; @@ -17,7 +17,6 @@ import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; import com.pchmn.materialchips.views.ChipsInputEditText; import com.pchmn.materialchips.views.DetailedChipView; diff --git a/library/src/main/java/com/pchmn/materialchips/util/ViewUtil.java b/library/src/main/java/com/pchmn/materialchips/util/ViewUtil.java index 1cae87da..f3ca6e28 100644 --- a/library/src/main/java/com/pchmn/materialchips/util/ViewUtil.java +++ b/library/src/main/java/com/pchmn/materialchips/util/ViewUtil.java @@ -22,16 +22,15 @@ public static int pxToDp(int px) { } public static int getWindowWidth(Context context) { - if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){ + if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { return getWindowWidthPortrait(context); - } - else { + } else { return getWindowWidthLandscape(context); } } private static int getWindowWidthPortrait(Context context) { - if(windowWidthPortrait == 0) { + if (windowWidthPortrait == 0) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); windowWidthPortrait = metrics.widthPixels; } @@ -40,7 +39,7 @@ private static int getWindowWidthPortrait(Context context) { } private static int getWindowWidthLandscape(Context context) { - if(windowWidthLandscape == 0) { + if (windowWidthLandscape == 0) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); windowWidthLandscape = metrics.widthPixels; } @@ -53,15 +52,15 @@ public static int getNavBarHeight(Context context) { boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey(); boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); - if(!hasMenuKey && !hasBackKey) { + if (!hasMenuKey && !hasBackKey) { //The device has a navigation bar Resources resources = context.getResources(); int orientation = context.getResources().getConfiguration().orientation; int resourceId; - if (isTablet(context)){ + if (isTablet(context)) { resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape", "dimen", "android"); - } else { + } else { resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_width", "dimen", "android"); } diff --git a/library/src/main/java/com/pchmn/materialchips/views/ChipsInputEditText.java b/library/src/main/java/com/pchmn/materialchips/views/ChipsInputEditText.java index d3bb04f5..5166ec61 100644 --- a/library/src/main/java/com/pchmn/materialchips/views/ChipsInputEditText.java +++ b/library/src/main/java/com/pchmn/materialchips/views/ChipsInputEditText.java @@ -3,9 +3,8 @@ import android.content.Context; import android.util.AttributeSet; -import android.util.Log; -public class ChipsInputEditText extends android.support.v7.widget.AppCompatEditText { +public class ChipsInputEditText extends androidx.appcompat.widget.AppCompatEditText { private FilterableListView filterableListView; diff --git a/library/src/main/java/com/pchmn/materialchips/views/DetailedChipView.java b/library/src/main/java/com/pchmn/materialchips/views/DetailedChipView.java index 766a2e92..81069f70 100644 --- a/library/src/main/java/com/pchmn/materialchips/views/DetailedChipView.java +++ b/library/src/main/java/com/pchmn/materialchips/views/DetailedChipView.java @@ -1,16 +1,12 @@ package com.pchmn.materialchips.views; -import android.app.Activity; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.PorterDuff; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; import android.net.Uri; -import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.view.View; import android.view.animation.AlphaAnimation; @@ -18,14 +14,13 @@ import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.core.content.ContextCompat; + import com.pchmn.materialchips.R; import com.pchmn.materialchips.R2; -import com.pchmn.materialchips.model.Chip; import com.pchmn.materialchips.model.ChipInterface; import com.pchmn.materialchips.util.ColorUtil; import com.pchmn.materialchips.util.LetterTileProvider; -import com.pchmn.materialchips.util.MyWindowCallback; -import com.pchmn.materialchips.util.ViewUtil; import butterknife.BindView; import butterknife.ButterKnife; @@ -35,16 +30,21 @@ public class DetailedChipView extends RelativeLayout { private static final String TAG = DetailedChipView.class.toString(); - // context - private Context mContext; - // xml elements - @BindView(R2.id.content) RelativeLayout mContentLayout; - @BindView(R2.id.avatar_icon) CircleImageView mAvatarIconImageView; - @BindView(R2.id.name) TextView mNameTextView; - @BindView(R2.id.info) TextView mInfoTextView; - @BindView(R2.id.delete_button) ImageButton mDeleteButton; // letter tile provider private static LetterTileProvider mLetterTileProvider; + // xml elements + @BindView(R2.id.content) + RelativeLayout mContentLayout; + @BindView(R2.id.avatar_icon) + CircleImageView mAvatarIconImageView; + @BindView(R2.id.name) + TextView mNameTextView; + @BindView(R2.id.info) + TextView mInfoTextView; + @BindView(R2.id.delete_button) + ImageButton mDeleteButton; + // context + private Context mContext; // attributes private ColorStateList mBackgroundColor; @@ -60,6 +60,41 @@ public DetailedChipView(Context context, AttributeSet attrs) { init(attrs); } + private static DetailedChipView newInstance(Builder builder) { + DetailedChipView detailedChipView = new DetailedChipView(builder.context); + // avatar + if (builder.avatarUri != null) + detailedChipView.setAvatarIcon(builder.avatarUri); + else if (builder.avatarDrawable != null) + detailedChipView.setAvatarIcon(builder.avatarDrawable); + else + detailedChipView.setAvatarIcon(mLetterTileProvider.getLetterTile(builder.name)); + + // background color + if (builder.backgroundColor != null) + detailedChipView.setBackGroundcolor(builder.backgroundColor); + + // text color + if (builder.textColor != null) + detailedChipView.setTextColor(builder.textColor); + else if (ColorUtil.isColorDark(detailedChipView.getBackgroundColor())) + detailedChipView.setTextColor(ColorStateList.valueOf(Color.WHITE)); + else + detailedChipView.setTextColor(ColorStateList.valueOf(Color.BLACK)); + + // delete icon color + if (builder.deleteIconColor != null) + detailedChipView.setDeleteIconColor(builder.deleteIconColor); + else if (ColorUtil.isColorDark(detailedChipView.getBackgroundColor())) + detailedChipView.setDeleteIconColor(ColorStateList.valueOf(Color.WHITE)); + else + detailedChipView.setDeleteIconColor(ColorStateList.valueOf(Color.BLACK)); + + detailedChipView.setName(builder.name); + detailedChipView.setInfo(builder.info); + return detailedChipView; + } + /** * Inflate the view according to attributes * @@ -131,11 +166,10 @@ public void setName(String name) { } public void setInfo(String info) { - if(info != null) { + if (info != null) { mInfoTextView.setVisibility(VISIBLE); mInfoTextView.setText(info); - } - else { + } else { mInfoTextView.setVisibility(GONE); } } @@ -235,39 +269,4 @@ public DetailedChipView build() { return DetailedChipView.newInstance(this); } } - - private static DetailedChipView newInstance(Builder builder) { - DetailedChipView detailedChipView = new DetailedChipView(builder.context); - // avatar - if(builder.avatarUri != null) - detailedChipView.setAvatarIcon(builder.avatarUri); - else if(builder.avatarDrawable != null) - detailedChipView.setAvatarIcon(builder.avatarDrawable); - else - detailedChipView.setAvatarIcon(mLetterTileProvider.getLetterTile(builder.name)); - - // background color - if(builder.backgroundColor != null) - detailedChipView.setBackGroundcolor(builder.backgroundColor); - - // text color - if(builder.textColor != null) - detailedChipView.setTextColor(builder.textColor); - else if(ColorUtil.isColorDark(detailedChipView.getBackgroundColor())) - detailedChipView.setTextColor(ColorStateList.valueOf(Color.WHITE)); - else - detailedChipView.setTextColor(ColorStateList.valueOf(Color.BLACK)); - - // delete icon color - if(builder.deleteIconColor != null) - detailedChipView.setDeleteIconColor(builder.deleteIconColor); - else if(ColorUtil.isColorDark(detailedChipView.getBackgroundColor())) - detailedChipView.setDeleteIconColor(ColorStateList.valueOf(Color.WHITE)); - else - detailedChipView.setDeleteIconColor(ColorStateList.valueOf(Color.BLACK)); - - detailedChipView.setName(builder.name); - detailedChipView.setInfo(builder.info); - return detailedChipView; - } } diff --git a/library/src/main/java/com/pchmn/materialchips/views/FilterableListView.java b/library/src/main/java/com/pchmn/materialchips/views/FilterableListView.java index 8e94cd52..25ff5be0 100644 --- a/library/src/main/java/com/pchmn/materialchips/views/FilterableListView.java +++ b/library/src/main/java/com/pchmn/materialchips/views/FilterableListView.java @@ -7,8 +7,6 @@ import android.graphics.PorterDuff; import android.graphics.Rect; import android.os.Build; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; @@ -16,6 +14,9 @@ import android.widget.Filter; import android.widget.RelativeLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.pchmn.materialchips.ChipsInput; import com.pchmn.materialchips.R; import com.pchmn.materialchips.R2; @@ -31,9 +32,10 @@ public class FilterableListView extends RelativeLayout { private static final String TAG = FilterableListView.class.toString(); - private Context mContext; // list - @BindView(R2.id.recycler_view) RecyclerView mRecyclerView; + @BindView(R2.id.recycler_view) + RecyclerView mRecyclerView; + private Context mContext; private FilterableAdapter mAdapter; private List mFilterableList; // others @@ -65,7 +67,7 @@ public void build(List filterableList, ChipsInput chips // adapter mAdapter = new FilterableAdapter(mContext, mRecyclerView, filterableList, chipsInput, backgroundColor, textColor); mRecyclerView.setAdapter(mAdapter); - if(backgroundColor != null) + if (backgroundColor != null) mRecyclerView.getBackground().setColorFilter(backgroundColor.getDefaultColor(), PorterDuff.Mode.SRC_ATOP); // listen to change in the tree @@ -85,11 +87,13 @@ public void onGlobalLayout() { layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); - if(mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){ + if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { layoutParams.bottomMargin = ViewUtil.getNavBarHeight(mContext); } - + if (rootView.getParent() != null) { + ((ViewGroup) rootView.getParent()).removeView(rootView); + } // add view rootView.addView(FilterableListView.this, layoutParams); @@ -109,7 +113,7 @@ public void filterList(CharSequence text) { @Override public void onFilterComplete(int count) { // show if there are results - if(mAdapter.getItemCount() > 0) + if (mAdapter.getItemCount() > 0) fadeIn(); else fadeOut(); @@ -121,7 +125,7 @@ public void onFilterComplete(int count) { * Fade in */ public void fadeIn() { - if(getVisibility() == VISIBLE) + if (getVisibility() == VISIBLE) return; // get visible window (keyboard shown) @@ -147,7 +151,7 @@ public void fadeIn() { * Fade out */ public void fadeOut() { - if(getVisibility() == GONE) + if (getVisibility() == GONE) return; AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f); diff --git a/library/src/main/java/com/pchmn/materialchips/views/ScrollViewMaxHeight.java b/library/src/main/java/com/pchmn/materialchips/views/ScrollViewMaxHeight.java index db212ff6..70924a38 100644 --- a/library/src/main/java/com/pchmn/materialchips/views/ScrollViewMaxHeight.java +++ b/library/src/main/java/com/pchmn/materialchips/views/ScrollViewMaxHeight.java @@ -3,9 +3,10 @@ import android.content.Context; import android.content.res.TypedArray; -import android.support.v4.widget.NestedScrollView; import android.util.AttributeSet; +import androidx.core.widget.NestedScrollView; + import com.pchmn.materialchips.R; import com.pchmn.materialchips.util.ViewUtil; @@ -28,8 +29,7 @@ public ScrollViewMaxHeight(Context context, AttributeSet attrs) { try { mMaxHeight = a.getDimensionPixelSize(R.styleable.ScrollViewMaxHeight_maxHeight, ViewUtil.dpToPx(300)); - } - finally { + } finally { a.recycle(); } } diff --git a/library/src/main/res/layout/chip_view.xml b/library/src/main/res/layout/chip_view.xml index ce7310b2..8039f580 100644 --- a/library/src/main/res/layout/chip_view.xml +++ b/library/src/main/res/layout/chip_view.xml @@ -1,6 +1,5 @@ + android:orientation="horizontal"> + android:visibility="gone" /> + android:text="Paulcito" + android:textSize="14sp" /> + android:layout_marginRight="4dp" + android:background="?attr/selectableItemBackgroundBorderless" + android:src="@drawable/ic_cancel_grey_24dp" /> diff --git a/library/src/main/res/layout/chips_input.xml b/library/src/main/res/layout/chips_input.xml index f39d6fc7..e75107bc 100644 --- a/library/src/main/res/layout/chips_input.xml +++ b/library/src/main/res/layout/chips_input.xml @@ -5,9 +5,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="vertical" - app:maxHeight="150dp" > + app:maxHeight="150dp"> - - + android:focusableInTouchMode="true"> + + android:background="@drawable/bg_chip_view_opened" + android:clickable="true" + android:elevation="6dp"> + android:src="@drawable/avatar" /> @@ -50,8 +50,8 @@ android:ellipsize="end" android:maxLines="1" android:scrollHorizontally="true" - android:textSize="16sp" - android:text="Contact name sdfdsfdsfdgs"/> + android:text="Contact name sdfdsfdsfdgs" + android:textSize="16sp" /> + android:text="paul@gmail.comdfdgdgsdggdgdgdgdsgdgdgdg" + android:textSize="14sp" /> @@ -74,10 +74,10 @@ android:layout_height="30dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" - android:background="?attr/selectableItemBackgroundBorderless" android:layout_marginRight="10dp" - android:src="@drawable/ic_cancel_white_24dp"/> - + android:background="?attr/selectableItemBackgroundBorderless" + android:src="@drawable/ic_cancel_white_24dp" /> + \ No newline at end of file diff --git a/library/src/main/res/layout/item_list_filterable.xml b/library/src/main/res/layout/item_list_filterable.xml index cbe46c5a..1e7462dc 100644 --- a/library/src/main/res/layout/item_list_filterable.xml +++ b/library/src/main/res/layout/item_list_filterable.xml @@ -1,11 +1,11 @@ + android:clickable="true" + android:foreground="?attr/selectableItemBackground" + android:orientation="horizontal"> + android:gravity="center_vertical" + android:orientation="vertical"> + android:textSize="14sp" /> + android:text="secondary text" + android:textSize="13sp" /> diff --git a/library/src/main/res/layout/list_filterable_view.xml b/library/src/main/res/layout/list_filterable_view.xml index 3dc22897..94972c9a 100644 --- a/library/src/main/res/layout/list_filterable_view.xml +++ b/library/src/main/res/layout/list_filterable_view.xml @@ -3,11 +3,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:background="@android:color/white" + android:scrollbars="vertical" /> \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 15b85c09..fbfba780 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -3,15 +3,15 @@ apply plugin: 'me.tatarka.retrolambda' apply plugin: 'com.jakewharton.butterknife' android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 29 + buildToolsVersion '29.0.0' defaultConfig { applicationId "com.pchmn.sample.materialchipsinput" minSdkVersion 15 - targetSdkVersion 25 + targetSdkVersion 26 versionCode 9 versionName "1.0.8" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { @@ -26,18 +26,18 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + implementation fileTree(dir: 'libs', include: ['*.jar']) + androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile project(path: ':library') + implementation project(path: ':library') // butter knife - compile 'com.android.support:appcompat-v7:25.3.0' - compile 'com.android.support.constraint:constraint-layout:1.0.2' - compile 'io.reactivex.rxjava2:rxjava:2.0.8' - compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar' - compile 'com.jakewharton:butterknife:8.5.1' - testCompile 'junit:junit:4.12' - annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1' + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'io.reactivex.rxjava2:rxjava:2.2.19' + implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar' + implementation 'com.jakewharton:butterknife:10.2.1' + testImplementation 'junit:junit:4.13' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' } diff --git a/sample/src/androidTest/java/com/pchmn/sample/materialchipsinput/ExampleInstrumentedTest.java b/sample/src/androidTest/java/com/pchmn/sample/materialchipsinput/ExampleInstrumentedTest.java index 400aed59..a78f9596 100644 --- a/sample/src/androidTest/java/com/pchmn/sample/materialchipsinput/ExampleInstrumentedTest.java +++ b/sample/src/androidTest/java/com/pchmn/sample/materialchipsinput/ExampleInstrumentedTest.java @@ -1,8 +1,8 @@ package com.pchmn.sample.materialchipsinput; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/sample/src/main/java/com/pchmn/sample/materialchipsinput/ChipExamplesActivity.java b/sample/src/main/java/com/pchmn/sample/materialchipsinput/ChipExamplesActivity.java index 0ec3aa70..0f8cb8fa 100644 --- a/sample/src/main/java/com/pchmn/sample/materialchipsinput/ChipExamplesActivity.java +++ b/sample/src/main/java/com/pchmn/sample/materialchipsinput/ChipExamplesActivity.java @@ -1,10 +1,9 @@ package com.pchmn.sample.materialchipsinput; import android.net.Uri; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AppCompatActivity; +import androidx.core.content.ContextCompat; +import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; -import android.view.View; import android.widget.LinearLayout; import android.widget.Toast; diff --git a/sample/src/main/java/com/pchmn/sample/materialchipsinput/ContactListActivity.java b/sample/src/main/java/com/pchmn/sample/materialchipsinput/ContactListActivity.java index 33c7adba..e0f7ce41 100644 --- a/sample/src/main/java/com/pchmn/sample/materialchipsinput/ContactListActivity.java +++ b/sample/src/main/java/com/pchmn/sample/materialchipsinput/ContactListActivity.java @@ -5,7 +5,7 @@ import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; diff --git a/sample/src/main/java/com/pchmn/sample/materialchipsinput/MainActivity.java b/sample/src/main/java/com/pchmn/sample/materialchipsinput/MainActivity.java index 95e88ffd..ba13a739 100644 --- a/sample/src/main/java/com/pchmn/sample/materialchipsinput/MainActivity.java +++ b/sample/src/main/java/com/pchmn/sample/materialchipsinput/MainActivity.java @@ -2,9 +2,9 @@ import android.content.Intent; import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentTransaction; -import android.support.v7.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentTransaction; +import androidx.appcompat.app.AppCompatActivity; import android.widget.Button; import butterknife.BindView; diff --git a/sample/src/main/java/com/pchmn/sample/materialchipsinput/MyDialogFragment.java b/sample/src/main/java/com/pchmn/sample/materialchipsinput/MyDialogFragment.java index bfe3bca6..6efe69d3 100644 --- a/sample/src/main/java/com/pchmn/sample/materialchipsinput/MyDialogFragment.java +++ b/sample/src/main/java/com/pchmn/sample/materialchipsinput/MyDialogFragment.java @@ -1,7 +1,7 @@ package com.pchmn.sample.materialchipsinput; import android.os.Bundle; -import android.support.v7.app.AppCompatDialogFragment; +import androidx.appcompat.app.AppCompatDialogFragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; From 3beb6072f1c2f492f6f5d28fa1ce03e6bb26c11d Mon Sep 17 00:00:00 2001 From: Emre Hamurcu Date: Wed, 13 May 2020 17:16:33 +0300 Subject: [PATCH 2/6] #Migrate to androidx #Add view issue solved --- library/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/build.gradle b/library/build.gradle index 5748a6ea..773bdceb 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -8,8 +8,8 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 29 - versionCode 9 - versionName "1.0.8" + versionCode 10 + versionName "1.1.8" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From 7708d6e6a8ba0751f1818bc04ef8dc98052bb267 Mon Sep 17 00:00:00 2001 From: Emre Hamurcu Date: Wed, 13 May 2020 17:51:23 +0300 Subject: [PATCH 3/6] #Migrate to androidx --- .../ExampleInstrumentedTest.java | 26 ------------------- .../views/FilterableListView.java | 3 --- 2 files changed, 29 deletions(-) delete mode 100644 library/src/androidTest/java/com/pchmn/materialchips/ExampleInstrumentedTest.java diff --git a/library/src/androidTest/java/com/pchmn/materialchips/ExampleInstrumentedTest.java b/library/src/androidTest/java/com/pchmn/materialchips/ExampleInstrumentedTest.java deleted file mode 100644 index 862e2e99..00000000 --- a/library/src/androidTest/java/com/pchmn/materialchips/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.pchmn.materialchips; - -import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumentation test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("com.pchmn.library.test", appContext.getPackageName()); - } -} diff --git a/library/src/main/java/com/pchmn/materialchips/views/FilterableListView.java b/library/src/main/java/com/pchmn/materialchips/views/FilterableListView.java index 25ff5be0..02a383c9 100644 --- a/library/src/main/java/com/pchmn/materialchips/views/FilterableListView.java +++ b/library/src/main/java/com/pchmn/materialchips/views/FilterableListView.java @@ -91,9 +91,6 @@ public void onGlobalLayout() { layoutParams.bottomMargin = ViewUtil.getNavBarHeight(mContext); } - if (rootView.getParent() != null) { - ((ViewGroup) rootView.getParent()).removeView(rootView); - } // add view rootView.addView(FilterableListView.this, layoutParams); From 3a1d05ec25ba35fa6276991169f4bb536aaaddab Mon Sep 17 00:00:00 2001 From: Emre Hamurcu Date: Wed, 13 May 2020 17:51:59 +0300 Subject: [PATCH 4/6] #Migrate to androidx --- library/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/build.gradle b/library/build.gradle index 773bdceb..fe779069 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -8,8 +8,8 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 29 - versionCode 10 - versionName "1.1.8" + versionCode 11 + versionName "1.2.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From d1a426943fc2faacfd47bf81200b94f5a65f7f5f Mon Sep 17 00:00:00 2001 From: Emre Hamurcu Date: Mon, 25 May 2020 02:38:39 +0300 Subject: [PATCH 5/6] Remove View problem solved with redicilus solution :D --- library/src/main/java/com/pchmn/materialchips/ChipsInput.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/src/main/java/com/pchmn/materialchips/ChipsInput.java b/library/src/main/java/com/pchmn/materialchips/ChipsInput.java index f16ff222..c57d2ac6 100644 --- a/library/src/main/java/com/pchmn/materialchips/ChipsInput.java +++ b/library/src/main/java/com/pchmn/materialchips/ChipsInput.java @@ -346,6 +346,9 @@ public void setFilterableList(List list) { mFilterableListView = new FilterableListView(mContext); mFilterableListView.build(mChipList, this, mFilterableListBackgroundColor, mFilterableListTextColor); mChipsAdapter.setFilterableListView(mFilterableListView); + Chip tag = new Chip(-99, "emrhmrc", "emrhmrc"); + addChip(tag); + removeChipById(-99); } public ChipValidator getChipValidator() { From 4efc3025488f282e3d1c75cf13bbf0bde4948e9c Mon Sep 17 00:00:00 2001 From: Emre Hamurcu Date: Mon, 25 May 2020 02:39:44 +0300 Subject: [PATCH 6/6] Remove View problem solved with redicilus solution :D --- library/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/build.gradle b/library/build.gradle index fe779069..0dad6d29 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -8,8 +8,8 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 29 - versionCode 11 - versionName "1.2.0" + versionCode 12 + versionName "2.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"