include MaterialChipsInput as subdir lib
This commit is contained in:
parent
c98e835936
commit
053cbdf43e
40 changed files with 2963 additions and 2 deletions
|
@ -28,7 +28,6 @@ dependencies {
|
|||
|
||||
// UI
|
||||
compile 'org.sufficientlysecure:html-textview:3.1'
|
||||
compile 'com.github.sikeeoh:MaterialChipsInput:1.1.1'
|
||||
compile 'com.jpardogo.materialtabstrip:library:1.1.1'
|
||||
compile 'com.getbase:floatingactionbutton:1.10.1'
|
||||
compile 'com.nispok:snackbar:2.11.0'
|
||||
|
@ -61,6 +60,7 @@ dependencies {
|
|||
implementation project(':extern:minidns')
|
||||
implementation project(':KeybaseLib')
|
||||
implementation project(':safeslinger-exchange')
|
||||
implementation project(':extern:MaterialChipsInput')
|
||||
|
||||
implementation "android.arch.work:work-runtime:1.0.0-alpha02"
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
app:hint="@string/label_to"
|
||||
app:chip_hasAvatarIcon="false"
|
||||
app:maxRows="2"
|
||||
app:chip_detailed_backgroundColor="@color/colorChipViewBackground"
|
||||
/>
|
||||
|
|
8
extern/MaterialChipsInput/.gitignore
vendored
Normal file
8
extern/MaterialChipsInput/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
36
extern/MaterialChipsInput/build.gradle
vendored
Normal file
36
extern/MaterialChipsInput/build.gradle
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion "27.0.3"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 27
|
||||
versionCode 114
|
||||
versionName "1.1.4"
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
})
|
||||
compile 'com.android.support:appcompat-v7:27.1.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
|
||||
// recycler
|
||||
compile 'com.android.support:recyclerview-v7:27.1.0'
|
||||
compile 'com.beloo.widget:ChipsLayoutManager:0.3.7@aar'
|
||||
}
|
||||
|
25
extern/MaterialChipsInput/proguard-rules.pro
vendored
Normal file
25
extern/MaterialChipsInput/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Users/couleurwhatever/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
|
@ -0,0 +1,26 @@
|
|||
package com.pchmn.materialchips;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.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 <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@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());
|
||||
}
|
||||
}
|
4
extern/MaterialChipsInput/src/main/AndroidManifest.xml
vendored
Normal file
4
extern/MaterialChipsInput/src/main/AndroidManifest.xml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
package="com.pchmn.materialchips">
|
||||
</manifest>
|
399
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/ChipView.java
vendored
Normal file
399
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/ChipView.java
vendored
Normal file
|
@ -0,0 +1,399 @@
|
|||
package com.pchmn.materialchips;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.AttributeSet;
|
||||
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.ChipInterface;
|
||||
import com.pchmn.materialchips.util.LetterTileProvider;
|
||||
import com.pchmn.materialchips.util.ViewUtil;
|
||||
|
||||
public class ChipView extends RelativeLayout {
|
||||
|
||||
private static final String TAG = ChipView.class.toString();
|
||||
// context
|
||||
private Context mContext;
|
||||
// xml elements
|
||||
private LinearLayout mContentLayout;
|
||||
private TextView mLabelTextView;
|
||||
private ImageButton mDeleteButton;
|
||||
// attributes
|
||||
private static final int NONE = -1;
|
||||
private String mLabel;
|
||||
private ColorStateList mLabelColor;
|
||||
private boolean mDeletable = false;
|
||||
private Drawable mDeleteIcon;
|
||||
private ColorStateList mDeleteIconColor;
|
||||
private ColorStateList mBackgroundColor;
|
||||
// letter tile provider
|
||||
private LetterTileProvider mLetterTileProvider;
|
||||
// chip
|
||||
private ChipInterface mChip;
|
||||
|
||||
public ChipView(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
init(null);
|
||||
}
|
||||
|
||||
public ChipView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflate the view according to attributes
|
||||
*
|
||||
* @param attrs the attributes
|
||||
*/
|
||||
private void init(AttributeSet attrs) {
|
||||
// inflate layout
|
||||
View rootView = inflate(getContext(), R.layout.chip_view, this);
|
||||
|
||||
mContentLayout = (LinearLayout) rootView.findViewById(R.id.content);
|
||||
mLabelTextView = (TextView) rootView.findViewById(R.id.label);
|
||||
mDeleteButton = (ImageButton) rootView.findViewById(R.id.delete_button);
|
||||
|
||||
// letter tile provider
|
||||
mLetterTileProvider = new LetterTileProvider(mContext);
|
||||
|
||||
// attributes
|
||||
if (attrs != null) {
|
||||
TypedArray a = mContext.getTheme().obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.ChipView,
|
||||
0, 0);
|
||||
|
||||
try {
|
||||
// label
|
||||
mLabel = a.getString(R.styleable.ChipView_label);
|
||||
mLabelColor = a.getColorStateList(R.styleable.ChipView_labelColor);
|
||||
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);
|
||||
// background color
|
||||
mBackgroundColor = a.getColorStateList(R.styleable.ChipView_backgroundColor);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
// inflate
|
||||
inflateWithAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflate the view
|
||||
*/
|
||||
private void inflateWithAttributes() {
|
||||
// label
|
||||
setLabel(mLabel);
|
||||
if (mLabelColor != null)
|
||||
setLabelColor(mLabelColor);
|
||||
|
||||
// delete button
|
||||
setDeletable(mDeletable);
|
||||
|
||||
// background color
|
||||
if (mBackgroundColor != null)
|
||||
setChipBackgroundColor(mBackgroundColor);
|
||||
}
|
||||
|
||||
public void inflate(ChipInterface chip) {
|
||||
mChip = chip;
|
||||
// label
|
||||
mLabel = mChip.getLabel();
|
||||
// inflate
|
||||
inflateWithAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get label
|
||||
*
|
||||
* @return the label
|
||||
*/
|
||||
public String getLabel() {
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set label
|
||||
*
|
||||
* @param label the label to set
|
||||
*/
|
||||
public void setLabel(String label) {
|
||||
mLabel = label;
|
||||
mLabelTextView.setText(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set label color
|
||||
*
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setLabelColor(ColorStateList color) {
|
||||
mLabelColor = color;
|
||||
mLabelTextView.setTextColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set label color
|
||||
*
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setLabelColor(@ColorInt int color) {
|
||||
mLabelColor = ColorStateList.valueOf(color);
|
||||
mLabelTextView.setTextColor(color);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Show or hide avatar icon
|
||||
// *
|
||||
// * @param hasAvatarIcon true to show, false to hide
|
||||
// */
|
||||
// public void setHasAvatarIcon(boolean hasAvatarIcon) {
|
||||
// mHasAvatarIcon = hasAvatarIcon;
|
||||
//
|
||||
// if(!mHasAvatarIcon) {
|
||||
// // hide icon
|
||||
// mAvatarIconImageView.setVisibility(GONE);
|
||||
// // adjust padding
|
||||
// if(mDeleteButton.getVisibility() == VISIBLE)
|
||||
// mLabelTextView.setPadding(ViewUtil.dpToPx(12), 0, 0, 0);
|
||||
// else
|
||||
// mLabelTextView.setPadding(ViewUtil.dpToPx(12), 0, ViewUtil.dpToPx(12), 0);
|
||||
//
|
||||
// }
|
||||
// else {
|
||||
// // show icon
|
||||
// mAvatarIconImageView.setVisibility(VISIBLE);
|
||||
// // adjust padding
|
||||
// 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)
|
||||
// mAvatarIconImageView.setImageURI(mAvatarIconUri);
|
||||
// else if(mAvatarIconDrawable != null)
|
||||
// mAvatarIconImageView.setImageDrawable(mAvatarIconDrawable);
|
||||
// else
|
||||
// mAvatarIconImageView.setImageBitmap(mLetterTileProvider.getLetterTile(getLabel()));
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Set avatar icon
|
||||
// *
|
||||
// * @param avatarIcon the icon to set
|
||||
// */
|
||||
// public void setAvatarIcon(Drawable avatarIcon) {
|
||||
// mAvatarIconDrawable = avatarIcon;
|
||||
// mHasAvatarIcon = true;
|
||||
// inflateWithAttributes();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Set avatar icon
|
||||
// *
|
||||
// * @param avatarUri the uri of the icon to set
|
||||
// */
|
||||
// public void setAvatarIcon(Uri avatarUri) {
|
||||
// mAvatarIconUri = avatarUri;
|
||||
// mHasAvatarIcon = true;
|
||||
// inflateWithAttributes();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Show or hide delte button
|
||||
*
|
||||
* @param deletable true to show, false to hide
|
||||
*/
|
||||
public void setDeletable(boolean deletable) {
|
||||
mDeletable = deletable;
|
||||
if (!mDeletable) {
|
||||
// hide delete icon
|
||||
mDeleteButton.setVisibility(GONE);
|
||||
// adjust padding
|
||||
mLabelTextView.setPadding(ViewUtil.dpToPx(12), 0, ViewUtil.dpToPx(12), 0);
|
||||
} else {
|
||||
// show icon
|
||||
mDeleteButton.setVisibility(VISIBLE);
|
||||
// adjust padding
|
||||
mLabelTextView.setPadding(ViewUtil.dpToPx(12), 0, 0, 0);
|
||||
|
||||
// set icon
|
||||
if (mDeleteIcon != null)
|
||||
mDeleteButton.setImageDrawable(mDeleteIcon);
|
||||
if (mDeleteIconColor != null)
|
||||
mDeleteButton.getDrawable().mutate().setColorFilter(mDeleteIconColor.getDefaultColor(), PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set delete icon color
|
||||
*
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setDeleteIconColor(ColorStateList color) {
|
||||
mDeleteIconColor = color;
|
||||
mDeletable = true;
|
||||
inflateWithAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set delete icon color
|
||||
*
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setDeleteIconColor(@ColorInt int color) {
|
||||
mDeleteIconColor = ColorStateList.valueOf(color);
|
||||
mDeletable = true;
|
||||
inflateWithAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set delete icon
|
||||
*
|
||||
* @param deleteIcon the icon to set
|
||||
*/
|
||||
public void setDeleteIcon(Drawable deleteIcon) {
|
||||
mDeleteIcon = deleteIcon;
|
||||
mDeletable = true;
|
||||
inflateWithAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set background color
|
||||
*
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setChipBackgroundColor(ColorStateList color) {
|
||||
mBackgroundColor = color;
|
||||
setChipBackgroundColor(color.getDefaultColor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set background color
|
||||
*
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setChipBackgroundColor(@ColorInt int color) {
|
||||
mBackgroundColor = ColorStateList.valueOf(color);
|
||||
mContentLayout.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the chip object
|
||||
*
|
||||
* @param chip the chip
|
||||
*/
|
||||
public void setChip(ChipInterface chip) {
|
||||
mChip = chip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set OnClickListener on the delete button
|
||||
*
|
||||
* @param onClickListener the OnClickListener
|
||||
*/
|
||||
public void setOnDeleteClicked(OnClickListener onClickListener) {
|
||||
mDeleteButton.setOnClickListener(onClickListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set OnclickListener on the entire chip
|
||||
*
|
||||
* @param onClickListener the OnClickListener
|
||||
*/
|
||||
public void setOnChipClicked(OnClickListener onClickListener) {
|
||||
mContentLayout.setOnClickListener(onClickListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class
|
||||
*/
|
||||
public static class Builder {
|
||||
private Context context;
|
||||
private String label;
|
||||
private ColorStateList labelColor;
|
||||
private boolean deletable = false;
|
||||
private Drawable deleteIcon;
|
||||
private ColorStateList deleteIconColor;
|
||||
private ColorStateList backgroundColor;
|
||||
private ChipInterface chip;
|
||||
|
||||
public Builder(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public Builder label(String label) {
|
||||
this.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder labelColor(ColorStateList labelColor) {
|
||||
this.labelColor = labelColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder deletable(boolean deletable) {
|
||||
this.deletable = deletable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder deleteIcon(Drawable deleteIcon) {
|
||||
this.deleteIcon = deleteIcon;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder deleteIconColor(ColorStateList deleteIconColor) {
|
||||
this.deleteIconColor = deleteIconColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder backgroundColor(ColorStateList backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder chip(ChipInterface chip) {
|
||||
this.chip = chip;
|
||||
this.label = chip.getLabel();
|
||||
return this;
|
||||
}
|
||||
|
||||
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.mDeletable = builder.deletable;
|
||||
chipView.mDeleteIcon = builder.deleteIcon;
|
||||
chipView.mDeleteIconColor = builder.deleteIconColor;
|
||||
chipView.mBackgroundColor = builder.backgroundColor;
|
||||
chipView.mChip = builder.chip;
|
||||
chipView.inflateWithAttributes();
|
||||
|
||||
return chipView;
|
||||
}
|
||||
}
|
427
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/ChipsInput.java
vendored
Normal file
427
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/ChipsInput.java
vendored
Normal file
|
@ -0,0 +1,427 @@
|
|||
package com.pchmn.materialchips;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
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.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.beloo.widget.chipslayoutmanager.ChipsLayoutManager;
|
||||
import com.pchmn.materialchips.adapter.ChipsAdapter;
|
||||
import com.pchmn.materialchips.model.Chip;
|
||||
import com.pchmn.materialchips.model.ChipInterface;
|
||||
import com.pchmn.materialchips.util.ActivityUtil;
|
||||
import com.pchmn.materialchips.util.MyWindowCallback;
|
||||
import com.pchmn.materialchips.util.ViewUtil;
|
||||
import com.pchmn.materialchips.views.ChipsInputEditText;
|
||||
import com.pchmn.materialchips.views.DetailedChipView;
|
||||
import com.pchmn.materialchips.views.FilterableListView;
|
||||
import com.pchmn.materialchips.views.ScrollViewMaxHeight;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ChipsInput extends ScrollViewMaxHeight {
|
||||
|
||||
private static final String TAG = ChipsInput.class.toString();
|
||||
// context
|
||||
private Context mContext;
|
||||
// xml element
|
||||
private RecyclerView mRecyclerView;
|
||||
// adapter
|
||||
private ChipsAdapter mChipsAdapter;
|
||||
// attributes
|
||||
private static final int NONE = -1;
|
||||
private String mHint;
|
||||
private ColorStateList mHintColor;
|
||||
private ColorStateList mTextColor;
|
||||
private int mMaxRows = 2;
|
||||
private ColorStateList mChipLabelColor;
|
||||
private boolean mChipDeletable = false;
|
||||
private Drawable mChipDeleteIcon;
|
||||
private ColorStateList mChipDeleteIconColor;
|
||||
private ColorStateList mChipBackgroundColor;
|
||||
private boolean mShowChipDetailed = true;
|
||||
private ColorStateList mChipDetailedTextColor;
|
||||
private ColorStateList mChipDetailedDeleteIconColor;
|
||||
private ColorStateList mChipDetailedBackgroundColor;
|
||||
private ColorStateList mFilterableListBackgroundColor;
|
||||
private ColorStateList mFilterableListTextColor;
|
||||
// chips listener
|
||||
private List<ChipsListener> mChipsListenerList = new ArrayList<>();
|
||||
private ChipsListener mChipsListener;
|
||||
// chip list
|
||||
private List<? extends ChipInterface> mFilterableChipList;
|
||||
private FilterableListView mFilterableListView;
|
||||
// chip validator
|
||||
private ChipValidator mChipValidator;
|
||||
private ViewGroup filterableListLayout;
|
||||
private ChipsInputEditText mEditText;
|
||||
|
||||
public ChipsInput(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
init(null);
|
||||
}
|
||||
|
||||
public ChipsInput(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflate the view according to attributes
|
||||
*
|
||||
* @param attrs the attributes
|
||||
*/
|
||||
private void init(AttributeSet attrs) {
|
||||
// inflate filterableListLayout
|
||||
View rootView = inflate(getContext(), R.layout.chips_input, this);
|
||||
|
||||
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.chips_recycler);
|
||||
|
||||
initEditText();
|
||||
|
||||
// attributes
|
||||
if (attrs != null) {
|
||||
TypedArray a = mContext.getTheme().obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.ChipsInput,
|
||||
0, 0);
|
||||
|
||||
try {
|
||||
// hint
|
||||
mHint = a.getString(R.styleable.ChipsInput_hint);
|
||||
mHintColor = a.getColorStateList(R.styleable.ChipsInput_hintColor);
|
||||
mTextColor = a.getColorStateList(R.styleable.ChipsInput_textColor);
|
||||
mMaxRows = a.getInteger(R.styleable.ChipsInput_maxRows, 2);
|
||||
setMaxHeight(ViewUtil.dpToPx((40 * mMaxRows) + 8));
|
||||
//setVerticalScrollBarEnabled(true);
|
||||
// chip label color
|
||||
mChipLabelColor = a.getColorStateList(R.styleable.ChipsInput_chip_labelColor);
|
||||
// chip delete icon
|
||||
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);
|
||||
// chip background color
|
||||
mChipBackgroundColor = a.getColorStateList(R.styleable.ChipsInput_chip_backgroundColor);
|
||||
// show chip detailed
|
||||
mShowChipDetailed = a.getBoolean(R.styleable.ChipsInput_showChipDetailed, true);
|
||||
// chip detailed text color
|
||||
mChipDetailedTextColor = a.getColorStateList(R.styleable.ChipsInput_chip_detailed_textColor);
|
||||
mChipDetailedBackgroundColor = a.getColorStateList(R.styleable.ChipsInput_chip_detailed_backgroundColor);
|
||||
mChipDetailedDeleteIconColor = a.getColorStateList(R.styleable.ChipsInput_chip_detailed_deleteIconColor);
|
||||
// filterable list
|
||||
mFilterableListBackgroundColor = a.getColorStateList(R.styleable.ChipsInput_filterable_list_backgroundColor);
|
||||
mFilterableListTextColor = a.getColorStateList(R.styleable.ChipsInput_filterable_list_textColor);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
// adapter
|
||||
mChipsAdapter = new ChipsAdapter(mContext, this, mEditText, mRecyclerView);
|
||||
ChipsLayoutManager chipsLayoutManager = ChipsLayoutManager.newBuilder(mContext)
|
||||
.setOrientation(ChipsLayoutManager.HORIZONTAL)
|
||||
.build();
|
||||
mRecyclerView.setLayoutManager(chipsLayoutManager);
|
||||
mRecyclerView.setNestedScrollingEnabled(false);
|
||||
mRecyclerView.setAdapter(mChipsAdapter);
|
||||
|
||||
// set window callback
|
||||
// will hide DetailedOpenView and hide keyboard on touch outside
|
||||
Activity activity = ActivityUtil.scanForActivity(mContext);
|
||||
if (activity == null)
|
||||
throw new ClassCastException("android.view.Context cannot be cast to android.app.Activity");
|
||||
|
||||
android.view.Window.Callback mCallBack = (activity).getWindow().getCallback();
|
||||
activity.getWindow().setCallback(new MyWindowCallback(mCallBack, activity));
|
||||
}
|
||||
|
||||
private void initEditText() {
|
||||
mEditText = new ChipsInputEditText(mContext);
|
||||
if (mHintColor != null)
|
||||
mEditText.setHintTextColor(mHintColor);
|
||||
if (mTextColor != null)
|
||||
mEditText.setTextColor(mTextColor);
|
||||
|
||||
mEditText.setLayoutParams(new RelativeLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
mEditText.setHint(mHint);
|
||||
mEditText.setBackgroundResource(android.R.color.transparent);
|
||||
// prevent fullscreen on landscape
|
||||
mEditText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE);
|
||||
mEditText.setPrivateImeOptions("nm");
|
||||
// no suggestion
|
||||
mEditText.setInputType(InputType.TYPE_TEXT_VARIATION_FILTER | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||
|
||||
// handle back space
|
||||
mEditText.setOnKeyListener(new View.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
// backspace
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN
|
||||
&& event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
|
||||
// remove last chip
|
||||
if (mEditText.getText().toString().length() == 0)
|
||||
mChipsAdapter.removeLastChip();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if ((actionId == EditorInfo.IME_ACTION_DONE) || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
|
||||
ChipsInput.this.onActionDone(mEditText.getText().toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// text changed
|
||||
mEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
ChipsInput.this.onTextChanged(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addChips(List<ChipInterface> chipList) {
|
||||
mChipsAdapter.addChipsProgrammatically(chipList);
|
||||
}
|
||||
|
||||
public void addChip(ChipInterface chip) {
|
||||
mChipsAdapter.addChip(chip);
|
||||
}
|
||||
|
||||
public void addChip(Object id, String label, String info) {
|
||||
Chip chip = new Chip(id, label, info);
|
||||
mChipsAdapter.addChip(chip);
|
||||
}
|
||||
|
||||
public void addChip(String label, String info) {
|
||||
Chip chip = new Chip(label, info);
|
||||
mChipsAdapter.addChip(chip);
|
||||
}
|
||||
|
||||
public void removeChip(ChipInterface chip) {
|
||||
mChipsAdapter.removeChip(chip);
|
||||
}
|
||||
|
||||
public void removeChipById(Object id) {
|
||||
mChipsAdapter.removeChipById(id);
|
||||
}
|
||||
|
||||
public void removeChipByLabel(String label) {
|
||||
mChipsAdapter.removeChipByLabel(label);
|
||||
}
|
||||
|
||||
public void removeChipByInfo(String info) {
|
||||
mChipsAdapter.removeChipByInfo(info);
|
||||
}
|
||||
|
||||
public ChipView getChipView() {
|
||||
int padding = ViewUtil.dpToPx(4);
|
||||
ChipView chipView = new ChipView.Builder(mContext)
|
||||
.labelColor(mChipLabelColor)
|
||||
.deletable(mChipDeletable)
|
||||
.deleteIcon(mChipDeleteIcon)
|
||||
.deleteIconColor(mChipDeleteIconColor)
|
||||
.backgroundColor(mChipBackgroundColor)
|
||||
.build();
|
||||
|
||||
chipView.setPadding(padding, padding, padding, padding);
|
||||
|
||||
return chipView;
|
||||
}
|
||||
|
||||
public ChipsInputEditText getEditText() {
|
||||
return mChipsAdapter.getmEditText();
|
||||
}
|
||||
|
||||
public DetailedChipView getDetailedChipView(ChipInterface chip) {
|
||||
return new DetailedChipView.Builder(mContext)
|
||||
.chip(chip)
|
||||
.textColor(mChipDetailedTextColor)
|
||||
.backgroundColor(mChipDetailedBackgroundColor)
|
||||
.deleteIconColor(mChipDetailedDeleteIconColor)
|
||||
.build();
|
||||
}
|
||||
|
||||
public void addChipsListener(ChipsListener chipsListener) {
|
||||
mChipsListenerList.add(chipsListener);
|
||||
mChipsListener = chipsListener;
|
||||
}
|
||||
|
||||
public void onChipAdded(ChipInterface chip, int size) {
|
||||
for (ChipsListener chipsListener : mChipsListenerList) {
|
||||
chipsListener.onChipAdded(chip, size);
|
||||
}
|
||||
}
|
||||
|
||||
public void onChipRemoved(ChipInterface chip, int size) {
|
||||
for (ChipsListener chipsListener : mChipsListenerList) {
|
||||
chipsListener.onChipRemoved(chip, size);
|
||||
}
|
||||
}
|
||||
|
||||
public void onTextChanged(CharSequence text) {
|
||||
if (mChipsListener != null) {
|
||||
for (ChipsListener chipsListener : mChipsListenerList) {
|
||||
chipsListener.onTextChanged(text);
|
||||
}
|
||||
// show filterable list
|
||||
if (mFilterableListView != null) {
|
||||
if (text.length() > 0)
|
||||
mFilterableListView.filterList(text);
|
||||
else
|
||||
mFilterableListView.fadeOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onActionDone(CharSequence text) {
|
||||
if (mChipsListener != null) {
|
||||
for (ChipsListener chipsListener : mChipsListenerList) {
|
||||
chipsListener.onActionDone(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<? extends ChipInterface> getSelectedChipList() {
|
||||
return mChipsAdapter.getChipList();
|
||||
}
|
||||
|
||||
public String getHint() {
|
||||
return mHint;
|
||||
}
|
||||
|
||||
public void setHint(String mHint) {
|
||||
this.mHint = mHint;
|
||||
}
|
||||
|
||||
public void setHintColor(ColorStateList mHintColor) {
|
||||
this.mHintColor = mHintColor;
|
||||
}
|
||||
|
||||
public void setTextColor(ColorStateList mTextColor) {
|
||||
this.mTextColor = mTextColor;
|
||||
}
|
||||
|
||||
public ChipsInput setMaxRows(int mMaxRows) {
|
||||
this.mMaxRows = mMaxRows;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setChipLabelColor(ColorStateList mLabelColor) {
|
||||
this.mChipLabelColor = mLabelColor;
|
||||
}
|
||||
|
||||
public void setChipDeletable(boolean mDeletable) {
|
||||
this.mChipDeletable = mDeletable;
|
||||
}
|
||||
|
||||
public void setChipDeleteIcon(Drawable mDeleteIcon) {
|
||||
this.mChipDeleteIcon = mDeleteIcon;
|
||||
}
|
||||
|
||||
public void setChipDeleteIconColor(ColorStateList mDeleteIconColor) {
|
||||
this.mChipDeleteIconColor = mDeleteIconColor;
|
||||
}
|
||||
|
||||
public void setChipBackgroundColor(ColorStateList mBackgroundColor) {
|
||||
this.mChipBackgroundColor = mBackgroundColor;
|
||||
}
|
||||
|
||||
public ChipsInput setShowChipDetailed(boolean mShowChipDetailed) {
|
||||
this.mShowChipDetailed = mShowChipDetailed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isShowChipDetailed() {
|
||||
return mShowChipDetailed;
|
||||
}
|
||||
|
||||
public void setChipDetailedTextColor(ColorStateList mChipDetailedTextColor) {
|
||||
this.mChipDetailedTextColor = mChipDetailedTextColor;
|
||||
}
|
||||
|
||||
public void setChipDetailedDeleteIconColor(ColorStateList mChipDetailedDeleteIconColor) {
|
||||
this.mChipDetailedDeleteIconColor = mChipDetailedDeleteIconColor;
|
||||
}
|
||||
|
||||
public void setChipDetailedBackgroundColor(ColorStateList mChipDetailedBackgroundColor) {
|
||||
this.mChipDetailedBackgroundColor = mChipDetailedBackgroundColor;
|
||||
}
|
||||
|
||||
public void setFilterableListLayout(ViewGroup layout) {
|
||||
this.filterableListLayout = layout;
|
||||
}
|
||||
|
||||
public void setFilterableList(List<? extends ChipInterface> list) {
|
||||
mFilterableChipList = list;
|
||||
if (filterableListLayout != null) {
|
||||
mFilterableListView = new FilterableListView(mContext, filterableListLayout);
|
||||
} else {
|
||||
mFilterableListView = new FilterableListView(mContext);
|
||||
}
|
||||
mFilterableListView.build(mFilterableChipList, this, mFilterableListBackgroundColor, mFilterableListTextColor);
|
||||
mChipsAdapter.setFilterableListView(mFilterableListView);
|
||||
}
|
||||
|
||||
public List<? extends ChipInterface> getFilterableList() {
|
||||
return mFilterableChipList;
|
||||
}
|
||||
|
||||
public ChipValidator getChipValidator() {
|
||||
return mChipValidator;
|
||||
}
|
||||
|
||||
public void setChipValidator(ChipValidator mChipValidator) {
|
||||
this.mChipValidator = mChipValidator;
|
||||
}
|
||||
|
||||
public interface ChipsListener {
|
||||
void onChipAdded(ChipInterface chip, int newSize);
|
||||
|
||||
void onChipRemoved(ChipInterface chip, int newSize);
|
||||
|
||||
void onTextChanged(CharSequence text);
|
||||
|
||||
void onActionDone(CharSequence text);
|
||||
}
|
||||
|
||||
public interface ChipValidator {
|
||||
boolean areEquals(ChipInterface chip1, ChipInterface chip2);
|
||||
}
|
||||
}
|
384
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/adapter/ChipsAdapter.java
vendored
Normal file
384
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/adapter/ChipsAdapter.java
vendored
Normal file
|
@ -0,0 +1,384 @@
|
|||
package com.pchmn.materialchips.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
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.views.FilterableListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ChipsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private static final int TYPE_EDIT_TEXT = 0;
|
||||
private static final int TYPE_ITEM = 1;
|
||||
private Context mContext;
|
||||
private ChipsInput mChipsInput;
|
||||
private List<ChipInterface> mChipList = new ArrayList<>();
|
||||
private String mHintLabel;
|
||||
|
||||
private ChipsInputEditText mEditText;
|
||||
|
||||
private RecyclerView mRecycler;
|
||||
|
||||
public ChipsAdapter(Context context, ChipsInput chipsInput, RecyclerView recycler) {
|
||||
mContext = context;
|
||||
mChipsInput = chipsInput;
|
||||
mRecycler = recycler;
|
||||
mHintLabel = mChipsInput.getHint();
|
||||
}
|
||||
|
||||
public ChipsAdapter(Context mContext, ChipsInput chipsInput, ChipsInputEditText mEditText, RecyclerView mRecyclerView) {
|
||||
this(mContext, chipsInput, mRecyclerView);
|
||||
this.mEditText = mEditText;
|
||||
}
|
||||
|
||||
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) {
|
||||
return new EditTextViewHolder(mEditText);
|
||||
} else {
|
||||
return new ItemViewHolder(mChipsInput.getChipView());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
|
||||
// edit text
|
||||
if (position == mChipList.size()) {
|
||||
if (mChipList.size() == 0) {
|
||||
mEditText.setHint(mHintLabel);
|
||||
}
|
||||
|
||||
// auto fit edit text
|
||||
autofitEditText();
|
||||
}
|
||||
// chip
|
||||
else if (getItemCount() > 1) {
|
||||
ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
|
||||
itemViewHolder.chipView.inflate(getItem(position));
|
||||
// handle click
|
||||
handleClickOnEditText(itemViewHolder.chipView, position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mChipList.size() + 1;
|
||||
}
|
||||
|
||||
private ChipInterface getItem(int position) {
|
||||
return mChipList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == mChipList.size()) {
|
||||
return TYPE_EDIT_TEXT;
|
||||
}
|
||||
|
||||
return TYPE_ITEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return mChipList.get(position).hashCode();
|
||||
}
|
||||
|
||||
private void autofitEditText() {
|
||||
// min width of edit text = 50 dp
|
||||
ViewGroup.LayoutParams params = mEditText.getLayoutParams();
|
||||
params.width = ViewUtil.dpToPx(50);
|
||||
mEditText.setLayoutParams(params);
|
||||
|
||||
// listen to change in the tree
|
||||
mEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
// get right of recycler and left of edit text
|
||||
int right = mRecycler.getRight();
|
||||
int left = mEditText.getLeft();
|
||||
|
||||
// edit text will fill the space
|
||||
ViewGroup.LayoutParams params = mEditText.getLayoutParams();
|
||||
params.width = right - left - ViewUtil.dpToPx(8);
|
||||
mEditText.setLayoutParams(params);
|
||||
|
||||
// request focus
|
||||
mEditText.requestFocus();
|
||||
|
||||
// remove the listener:
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
mEditText.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||
} else {
|
||||
mEditText.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void handleClickOnEditText(ChipView chipView, final int position) {
|
||||
// delete chip
|
||||
chipView.setOnDeleteClicked(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
removeChip(position);
|
||||
}
|
||||
});
|
||||
|
||||
// show detailed chip
|
||||
if (mChipsInput.isShowChipDetailed()) {
|
||||
chipView.setOnChipClicked(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// get chip position
|
||||
int[] coord = new int[2];
|
||||
v.getLocationInWindow(coord);
|
||||
|
||||
final DetailedChipView detailedChipView = mChipsInput.getDetailedChipView(getItem(position));
|
||||
setDetailedChipViewPosition(detailedChipView, coord);
|
||||
|
||||
// delete button
|
||||
detailedChipView.setOnDeleteClicked(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
removeChip(position);
|
||||
detailedChipView.fadeOut();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setDetailedChipViewPosition(DetailedChipView detailedChipView, int[] coord) {
|
||||
// window width
|
||||
ViewGroup rootView = (ViewGroup) mRecycler.getRootView();
|
||||
int windowWidth = ViewUtil.getWindowWidth(mContext);
|
||||
|
||||
// chip size
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
|
||||
ViewUtil.dpToPx(300),
|
||||
ViewUtil.dpToPx(100));
|
||||
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||
|
||||
// align left window
|
||||
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)) {
|
||||
layoutParams.leftMargin = windowWidth - ViewUtil.dpToPx(300);
|
||||
layoutParams.topMargin = coord[1] - ViewUtil.dpToPx(13);
|
||||
detailedChipView.alignRight();
|
||||
}
|
||||
// same position as chip
|
||||
else {
|
||||
layoutParams.leftMargin = coord[0] - ViewUtil.dpToPx(13);
|
||||
layoutParams.topMargin = coord[1] - ViewUtil.dpToPx(13);
|
||||
}
|
||||
|
||||
// show view
|
||||
rootView.addView(detailedChipView, layoutParams);
|
||||
detailedChipView.fadeIn();
|
||||
}
|
||||
|
||||
public void setFilterableListView(FilterableListView filterableListView) {
|
||||
if (mEditText != null) {
|
||||
mEditText.setFilterableListView(filterableListView);
|
||||
}
|
||||
}
|
||||
|
||||
public void addChipsProgrammatically(List<ChipInterface> chipList) {
|
||||
if (chipList != null) {
|
||||
if (chipList.size() > 0) {
|
||||
int chipsBeforeAdding = getItemCount();
|
||||
for (ChipInterface chip : chipList) {
|
||||
mChipList.add(chip);
|
||||
mChipsInput.onChipAdded(chip, getItemCount());
|
||||
}
|
||||
|
||||
// hide hint
|
||||
mEditText.setHint(null);
|
||||
// reset text
|
||||
mEditText.setText(null);
|
||||
|
||||
notifyItemRangeChanged(chipsBeforeAdding, chipList.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addChip(ChipInterface chip) {
|
||||
if (!listContains(mChipList, chip)) {
|
||||
mChipList.add(chip);
|
||||
// notify listener
|
||||
mChipsInput.onChipAdded(chip, mChipList.size());
|
||||
// hide hint
|
||||
mEditText.setHint(null);
|
||||
// reset text
|
||||
mEditText.setText(null);
|
||||
// refresh data
|
||||
notifyItemInserted(mChipList.size());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeChip(ChipInterface chip) {
|
||||
int position = mChipList.indexOf(chip);
|
||||
mChipList.remove(position);
|
||||
// notify listener
|
||||
notifyItemRangeChanged(position, getItemCount());
|
||||
mChipsInput.onChipRemoved(chip, mChipList.size());
|
||||
// if 0 chip
|
||||
if (mChipList.size() == 0) {
|
||||
mEditText.setHint(mHintLabel);
|
||||
}
|
||||
// refresh data
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void removeChip(int position) {
|
||||
ChipInterface chip = mChipList.get(position);
|
||||
// remove contact
|
||||
mChipList.remove(position);
|
||||
// notify listener
|
||||
mChipsInput.onChipRemoved(chip, mChipList.size());
|
||||
// if 0 chip
|
||||
if (mChipList.size() == 0) {
|
||||
mEditText.setHint(mHintLabel);
|
||||
}
|
||||
// refresh data
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void removeChipById(Object id) {
|
||||
for (Iterator<ChipInterface> iter = mChipList.listIterator(); iter.hasNext(); ) {
|
||||
ChipInterface chip = iter.next();
|
||||
if (chip.getId() != null && chip.getId().equals(id)) {
|
||||
// remove chip
|
||||
iter.remove();
|
||||
// notify listener
|
||||
mChipsInput.onChipRemoved(chip, mChipList.size());
|
||||
}
|
||||
}
|
||||
// if 0 chip
|
||||
if (mChipList.size() == 0) {
|
||||
mEditText.setHint(mHintLabel);
|
||||
}
|
||||
// refresh data
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void removeChipByLabel(String label) {
|
||||
for (Iterator<ChipInterface> iter = mChipList.listIterator(); iter.hasNext(); ) {
|
||||
ChipInterface chip = iter.next();
|
||||
if (chip.getLabel().equals(label)) {
|
||||
// remove chip
|
||||
iter.remove();
|
||||
// notify listener
|
||||
mChipsInput.onChipRemoved(chip, mChipList.size());
|
||||
}
|
||||
}
|
||||
// if 0 chip
|
||||
if (mChipList.size() == 0) {
|
||||
mEditText.setHint(mHintLabel);
|
||||
}
|
||||
// refresh data
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void removeChipByInfo(String info) {
|
||||
for (Iterator<ChipInterface> iter = mChipList.listIterator(); iter.hasNext(); ) {
|
||||
ChipInterface chip = iter.next();
|
||||
if (chip.getInfo() != null && chip.getInfo().equals(info)) {
|
||||
// remove chip
|
||||
iter.remove();
|
||||
// notify listener
|
||||
mChipsInput.onChipRemoved(chip, mChipList.size());
|
||||
}
|
||||
}
|
||||
// if 0 chip
|
||||
if (mChipList.size() == 0) {
|
||||
mEditText.setHint(mHintLabel);
|
||||
}
|
||||
// refresh data
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void removeLastChip() {
|
||||
if (mChipList.size() > 0) {
|
||||
removeChip(mChipList.get(mChipList.size() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
public List<ChipInterface> getChipList() {
|
||||
return mChipList;
|
||||
}
|
||||
|
||||
private boolean listContains(List<ChipInterface> contactList, ChipInterface 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())) {
|
||||
return true;
|
||||
}
|
||||
if (chip.getLabel().equals(item.getLabel())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ChipsInputEditText getmEditText() {
|
||||
return mEditText;
|
||||
}
|
||||
}
|
253
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/adapter/FilterableAdapter.java
vendored
Normal file
253
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/adapter/FilterableAdapter.java
vendored
Normal file
|
@ -0,0 +1,253 @@
|
|||
package com.pchmn.materialchips.adapter;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
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 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 java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
|
||||
public class FilterableAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
|
||||
|
||||
private static final String TAG = FilterableAdapter.class.toString();
|
||||
// context
|
||||