include MaterialChipsInput as subdir lib
This commit is contained in:
parent
c98e835936
commit
053cbdf43e
|
@ -28,7 +28,6 @@ dependencies {
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
compile 'org.sufficientlysecure:html-textview:3.1'
|
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.jpardogo.materialtabstrip:library:1.1.1'
|
||||||
compile 'com.getbase:floatingactionbutton:1.10.1'
|
compile 'com.getbase:floatingactionbutton:1.10.1'
|
||||||
compile 'com.nispok:snackbar:2.11.0'
|
compile 'com.nispok:snackbar:2.11.0'
|
||||||
|
@ -61,6 +60,7 @@ dependencies {
|
||||||
implementation project(':extern:minidns')
|
implementation project(':extern:minidns')
|
||||||
implementation project(':KeybaseLib')
|
implementation project(':KeybaseLib')
|
||||||
implementation project(':safeslinger-exchange')
|
implementation project(':safeslinger-exchange')
|
||||||
|
implementation project(':extern:MaterialChipsInput')
|
||||||
|
|
||||||
implementation "android.arch.work:work-runtime:1.0.0-alpha02"
|
implementation "android.arch.work:work-runtime:1.0.0-alpha02"
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
android:paddingLeft="8dp"
|
android:paddingLeft="8dp"
|
||||||
android:paddingRight="8dp"
|
android:paddingRight="8dp"
|
||||||
app:hint="@string/label_to"
|
app:hint="@string/label_to"
|
||||||
app:chip_hasAvatarIcon="false"
|
|
||||||
app:maxRows="2"
|
app:maxRows="2"
|
||||||
app:chip_detailed_backgroundColor="@color/colorChipViewBackground"
|
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
|
||||||
|
private Context mContext;
|
||||||
|
// list
|
||||||
|
private List<ChipInterface> mOriginalList = new ArrayList<>();
|
||||||
|
private List<ChipInterface> mChipList = new ArrayList<>();
|
||||||
|
private List<ChipInterface> mFilteredList = new ArrayList<>();
|
||||||
|
private ChipFilter mFilter;
|
||||||
|
private ChipsInput mChipsInput;
|
||||||
|
private LetterTileProvider mLetterTileProvider;
|
||||||
|
private ColorStateList mBackgroundColor;
|
||||||
|
private ColorStateList mTextColor;
|
||||||
|
// recycler
|
||||||
|
private RecyclerView mRecyclerView;
|
||||||
|
// sort
|
||||||
|
private Comparator<ChipInterface> mComparator;
|
||||||
|
private Collator mCollator;
|
||||||
|
|
||||||
|
|
||||||
|
public FilterableAdapter(Context context,
|
||||||
|
RecyclerView recyclerView,
|
||||||
|
List<? extends ChipInterface> chipList,
|
||||||
|
ChipsInput chipsInput,
|
||||||
|
ColorStateList backgroundColor,
|
||||||
|
ColorStateList textColor) {
|
||||||
|
mContext = context;
|
||||||
|
mRecyclerView = recyclerView;
|
||||||
|
mCollator = Collator.getInstance(Locale.getDefault());
|
||||||
|
mCollator.setStrength(Collator.PRIMARY);
|
||||||
|
mComparator = new Comparator<ChipInterface>() {
|
||||||
|
@Override
|
||||||
|
public int compare(ChipInterface o1, ChipInterface o2) {
|
||||||
|
return mCollator.compare(o1.getLabel(), o2.getLabel());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// remove chips that do not have label
|
||||||
|
Iterator<? extends ChipInterface> iterator = chipList.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
if (iterator.next().getLabel() == null)
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
sortList(chipList);
|
||||||
|
mOriginalList.addAll(chipList);
|
||||||
|
mChipList.addAll(chipList);
|
||||||
|
mFilteredList.addAll(chipList);
|
||||||
|
mLetterTileProvider = new LetterTileProvider(mContext);
|
||||||
|
mBackgroundColor = backgroundColor;
|
||||||
|
mTextColor = textColor;
|
||||||
|
mChipsInput = chipsInput;
|
||||||
|
|
||||||
|
mChipsInput.addChipsListener(new ChipsInput.ChipsListener() {
|
||||||
|
@Override
|
||||||
|
public void onChipAdded(ChipInterface chip, int newSize) {
|
||||||
|
removeChip(chip);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChipRemoved(ChipInterface chip, int newSize) {
|
||||||
|
addChip(chip);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence text) {
|
||||||
|
mRecyclerView.scrollToPosition(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActionDone(CharSequence text) {
|
||||||
|
mRecyclerView.scrollToPosition(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ItemViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
private TextView mLabel;
|
||||||
|
private TextView mInfo;
|
||||||
|
|
||||||
|
ItemViewHolder(View view) {
|
||||||
|
super(view);
|
||||||
|
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);
|
||||||
|
return new ItemViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||||
|
ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
|
||||||
|
final ChipInterface chip = getItem(position);
|
||||||
|
|
||||||
|
// label
|
||||||
|
itemViewHolder.mLabel.setText(chip.getLabel());
|
||||||
|
|
||||||
|
// info
|
||||||
|
if (chip.getInfo() != null) {
|
||||||
|
itemViewHolder.mInfo.setVisibility(View.VISIBLE);
|
||||||
|
itemViewHolder.mInfo.setText(chip.getInfo());
|
||||||
|
} else {
|
||||||
|
itemViewHolder.mInfo.setVisibility(GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// colors
|
||||||
|
if (mBackgroundColor != null)
|
||||||
|
itemViewHolder.itemView.getBackground().setColorFilter(mBackgroundColor.getDefaultColor(), PorterDuff.Mode.SRC_ATOP);
|
||||||
|
if (mTextColor != null) {
|
||||||
|
itemViewHolder.mLabel.setTextColor(mTextColor);
|
||||||
|
itemViewHolder.mInfo.setTextColor(ColorUtil.alpha(mTextColor.getDefaultColor(), 150));
|
||||||
|
}
|
||||||
|
|
||||||
|
// onclick
|
||||||
|
itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (mChipsInput != null)
|
||||||
|
mChipsInput.addChip(chip);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mFilteredList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChipInterface getItem(int position) {
|
||||||
|
return mFilteredList.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Filter getFilter() {
|
||||||
|
if (mFilter == null)
|
||||||
|
mFilter = new ChipFilter(this, mChipList);
|
||||||
|
return mFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ChipFilter extends Filter {
|
||||||
|
|
||||||
|
private FilterableAdapter adapter;
|
||||||
|
private List<ChipInterface> originalList;
|
||||||
|
private List<ChipInterface> filteredList;
|
||||||
|
|
||||||
|
public ChipFilter(FilterableAdapter adapter, List<ChipInterface> originalList) {
|
||||||
|
super();
|
||||||
|
this.adapter = adapter;
|
||||||
|
this.originalList = originalList;
|
||||||
|
this.filteredList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FilterResults performFiltering(CharSequence constraint) {
|
||||||
|
filteredList.clear();
|
||||||
|
FilterResults results = new FilterResults();
|
||||||
|
if (constraint.length() == 0) {
|
||||||
|
filteredList.addAll(originalList);
|
||||||
|
} else {
|
||||||
|
final String filterPattern = constraint.toString().toLowerCase().trim();
|
||||||
|
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)) {
|
||||||
|
filteredList.add(chip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
results.values = filteredList;
|
||||||
|
results.count = filteredList.size();
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||||
|
mFilteredList.clear();
|
||||||
|
mFilteredList.addAll((ArrayList<ChipInterface>) results.values);
|
||||||
|
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<? extends ChipInterface> list) {
|
||||||
|
Collections.sort(list, mComparator);
|
||||||
|
}
|
||||||
|
}
|
39
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/model/Chip.java
vendored
Normal file
39
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/model/Chip.java
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package com.pchmn.materialchips.model;
|
||||||
|
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
public class Chip implements ChipInterface {
|
||||||
|
|
||||||
|
private Object id;
|
||||||
|
private String label;
|
||||||
|
private String info;
|
||||||
|
|
||||||
|
public Chip(@NonNull Object id, @NonNull String label, @Nullable String info) {
|
||||||
|
this.id = id;
|
||||||
|
this.label = label;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Chip(@NonNull String label, @Nullable String info) {
|
||||||
|
this.label = label;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
12
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/model/ChipInterface.java
vendored
Normal file
12
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/model/ChipInterface.java
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package com.pchmn.materialchips.model;
|
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
public interface ChipInterface {
|
||||||
|
|
||||||
|
Object getId();
|
||||||
|
String getLabel();
|
||||||
|
String getInfo();
|
||||||
|
}
|
20
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/ActivityUtil.java
vendored
Normal file
20
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/ActivityUtil.java
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package com.pchmn.materialchips.util;
|
||||||
|
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.ContextWrapper;
|
||||||
|
|
||||||
|
public class ActivityUtil {
|
||||||
|
|
||||||
|
public static Activity scanForActivity(Context context) {
|
||||||
|
if (context == null)
|
||||||
|
return null;
|
||||||
|
else if (context instanceof Activity)
|
||||||
|
return (Activity)context;
|
||||||
|
else if (context instanceof ContextWrapper)
|
||||||
|
return scanForActivity(((ContextWrapper)context).getBaseContext());
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
38
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/ColorUtil.java
vendored
Normal file
38
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/ColorUtil.java
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package com.pchmn.materialchips.util;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
|
||||||
|
import com.pchmn.materialchips.R;
|
||||||
|
|
||||||
|
public class ColorUtil {
|
||||||
|
|
||||||
|
public static int lighter(int color, float factor) {
|
||||||
|
int red = (int) ((Color.red(color) * (1 - factor) / 255 + factor) * 255);
|
||||||
|
int green = (int) ((Color.green(color) * (1 - factor) / 255 + factor) * 255);
|
||||||
|
int blue = (int) ((Color.blue(color) * (1 - factor) / 255 + factor) * 255);
|
||||||
|
return Color.argb(Color.alpha(color), red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int lighter(ColorStateList color, float factor) {
|
||||||
|
return lighter(color.getDefaultColor(), factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
return darkness >= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getThemeAccentColor (final Context context) {
|
||||||
|
final TypedValue value = new TypedValue ();
|
||||||
|
context.getTheme ().resolveAttribute (R.attr.colorAccent, value, true);
|
||||||
|
return value.data;
|
||||||
|
}
|
||||||
|
}
|
221
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/LetterTileProvider.java
vendored
Normal file
221
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/LetterTileProvider.java
vendored
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
package com.pchmn.materialchips.util;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
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;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.PorterDuffXfermode;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
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 com.pchmn.materialchips.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to create 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
|
||||||
|
*/
|
||||||
|
public class LetterTileProvider {
|
||||||
|
|
||||||
|
/** 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 */
|
||||||
|
private final TextPaint mPaint = new TextPaint();
|
||||||
|
/** The bounds that enclose the letter */
|
||||||
|
private final Rect mBounds = new Rect();
|
||||||
|
/** The {@link Canvas} to draw on */
|
||||||
|
private final Canvas mCanvas = new Canvas();
|
||||||
|
/** The first char of the name being displayed */
|
||||||
|
private final char[] mFirstChar = new char[1];
|
||||||
|
|
||||||
|
/** The background colors of the tile */
|
||||||
|
private final TypedArray mColors;
|
||||||
|
/** The font size used to display the letter */
|
||||||
|
private final int mTileLetterFontSize;
|
||||||
|
/** The default image to display */
|
||||||
|
private final Bitmap mDefaultBitmap;
|
||||||
|
|
||||||
|
/** Width */
|
||||||
|
private final int mWidth;
|
||||||
|
/** Height */
|
||||||
|
private final int mHeight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for <code>LetterTileProvider</code>
|
||||||
|
*
|
||||||
|
* @param context The {@link Context} to use
|
||||||
|
*/
|
||||||
|
public LetterTileProvider(Context context) {
|
||||||
|
final Resources res = context.getResources();
|
||||||
|
|
||||||
|
mPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
|
||||||
|
mPaint.setColor(Color.WHITE);
|
||||||
|
mPaint.setTextAlign(Paint.Align.CENTER);
|
||||||
|
mPaint.setAntiAlias(true);
|
||||||
|
|
||||||
|
mColors = res.obtainTypedArray(R.array.letter_tile_colors);
|
||||||
|
mTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size);
|
||||||
|
|
||||||
|
//mDefaultBitmap = BitmapFactory.decodeResource(res, android.R.drawable.);
|
||||||
|
mDefaultBitmap = drawableToBitmap(ContextCompat.getDrawable(context, R.drawable.ic_person_white_24dp));
|
||||||
|
mWidth = res.getDimensionPixelSize(R.dimen.letter_tile_size);
|
||||||
|
mHeight = res.getDimensionPixelSize(R.dimen.letter_tile_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
public Bitmap getLetterTile(String displayName) {
|
||||||
|
// workaround
|
||||||
|
if(displayName == null || displayName.length() == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
final Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
|
||||||
|
|
||||||
|
final char firstChar = displayName.charAt(0);
|
||||||
|
|
||||||
|
final Canvas c = mCanvas;
|
||||||
|
c.setBitmap(bitmap);
|
||||||
|
c.drawColor(pickColor(displayName));
|
||||||
|
|
||||||
|
if (isLetterOrDigit(firstChar)) {
|
||||||
|
mFirstChar[0] = Character.toUpperCase(firstChar);
|
||||||
|
mPaint.setTextSize(mTileLetterFontSize);
|
||||||
|
mPaint.getTextBounds(mFirstChar, 0, 1, mBounds);
|
||||||
|
c.drawText(mFirstChar, 0, 1, mWidth / 2, mHeight / 2
|
||||||
|
+ (mBounds.bottom - mBounds.top) / 2, mPaint);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// (32 - 24) / 2 = 4
|
||||||
|
c.drawBitmap(mDefaultBitmap, ViewUtil.dpToPx(4), ViewUtil.dpToPx(4), null);
|
||||||
|
}
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
public Bitmap getCircularLetterTile(String displayName) {
|
||||||
|
// workaround
|
||||||
|
if(displayName == null || displayName.length() == 0)
|
||||||
|
displayName = ".";
|
||||||
|
|
||||||
|
final Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
|
||||||
|
final char firstChar = displayName.charAt(0);
|
||||||
|
|
||||||
|
final Canvas c = mCanvas;
|
||||||
|
c.setBitmap(bitmap);
|
||||||
|
c.drawColor(pickColor(displayName));
|
||||||
|
|
||||||
|
if (isLetterOrDigit(firstChar)) {
|
||||||
|
mFirstChar[0] = Character.toUpperCase(firstChar);
|
||||||
|
mPaint.setTextSize(mTileLetterFontSize);
|
||||||
|
mPaint.getTextBounds(mFirstChar, 0, 1, mBounds);
|
||||||
|
c.drawText(mFirstChar, 0, 1, mWidth / 2, mHeight / 2
|
||||||
|
+ (mBounds.bottom - mBounds.top) / 2, mPaint);
|
||||||
|
} else {
|
||||||
|
// (32 - 24) / 2 = 4
|
||||||
|
c.drawBitmap(mDefaultBitmap, ViewUtil.dpToPx(4), ViewUtil.dpToPx(4), null);
|
||||||
|
}
|
||||||
|
return getCircularBitmap(bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param c The char to check
|
||||||
|
* @return True if <code>c</code> 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 <code>key</code> used as the
|
||||||
|
* tile background color
|
||||||
|
*/
|
||||||
|
private int pickColor(String key) {
|
||||||
|
// String.hashCode() is not supposed to change across java versions, so
|
||||||
|
// this should guarantee the same key always maps to the same color
|
||||||
|
final int color = Math.abs(key.hashCode()) % NUM_OF_TILE_COLORS;
|
||||||
|
try {
|
||||||
|
return mColors.getColor(color, Color.BLACK);
|
||||||
|
} finally {
|
||||||
|
// bug with recycler view
|
||||||
|
//mColors.recycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap getCircularBitmap(Bitmap bitmap) {
|
||||||
|
Bitmap output;
|
||||||
|
|
||||||
|
if (bitmap.getWidth() > bitmap.getHeight()) {
|
||||||
|
output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
|
||||||
|
} else {
|
||||||
|
output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
|
||||||
|
}
|
||||||
|
|
||||||
|
Canvas canvas = new Canvas(output);
|
||||||
|
|
||||||
|
final int color = 0xff424242;
|
||||||
|
final Paint paint = new Paint();
|
||||||
|
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||||
|
|
||||||
|
float r = 0;
|
||||||
|
|
||||||
|
if (bitmap.getWidth() > bitmap.getHeight()) {
|
||||||
|
r = bitmap.getHeight() / 2;
|
||||||
|
} else {
|
||||||
|
r = bitmap.getWidth() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
canvas.drawARGB(0, 0, 0, 0);
|
||||||
|
paint.setColor(color);
|
||||||
|
canvas.drawCircle(r, r, r, paint);
|
||||||
|
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||||
|
canvas.drawBitmap(bitmap, rect, rect, paint);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
173
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/MyWindowCallback.java
vendored
Normal file
173
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/MyWindowCallback.java
vendored
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
package com.pchmn.materialchips.util;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.RequiresApi;
|
||||||
|
import android.view.ActionMode;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.SearchEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class MyWindowCallback implements Window.Callback {
|
||||||
|
|
||||||
|
private Window.Callback mLocalCallback;
|
||||||
|
private Activity mActivity;
|
||||||
|
|
||||||
|
public MyWindowCallback(Window.Callback localCallback, Activity activity) {
|
||||||
|
mLocalCallback = localCallback;
|
||||||
|
mActivity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchKeyEvent(KeyEvent keyEvent) {
|
||||||
|
return mLocalCallback.dispatchKeyEvent(keyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchKeyShortcutEvent(KeyEvent keyEvent) {
|
||||||
|
return mLocalCallback.dispatchKeyShortcutEvent(keyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchTouchEvent(MotionEvent motionEvent) {
|
||||||
|
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
|
View v = mActivity.getCurrentFocus();
|
||||||
|
if(v instanceof DetailedChipView) {
|
||||||
|
Rect outRect = new Rect();
|
||||||
|
v.getGlobalVisibleRect(outRect);
|
||||||
|
if (!outRect.contains((int) motionEvent.getRawX(), (int) motionEvent.getRawY())) {
|
||||||
|
((DetailedChipView) v).fadeOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (v instanceof ChipsInputEditText) {
|
||||||
|
Rect outRect = new Rect();
|
||||||
|
v.getGlobalVisibleRect(outRect);
|
||||||
|
if (!outRect.contains((int) motionEvent.getRawX(), (int) motionEvent.getRawY())
|
||||||
|
&& !((ChipsInputEditText) v).isFilterableListVisible()) {
|
||||||
|
InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mLocalCallback.dispatchTouchEvent(motionEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchTrackballEvent(MotionEvent motionEvent) {
|
||||||
|
return mLocalCallback.dispatchTrackballEvent(motionEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchGenericMotionEvent(MotionEvent motionEvent) {
|
||||||
|
return mLocalCallback.dispatchGenericMotionEvent(motionEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
|
||||||
|
return mLocalCallback.dispatchPopulateAccessibilityEvent(accessibilityEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreatePanelView(int i) {
|
||||||
|
return mLocalCallback.onCreatePanelView(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreatePanelMenu(int i, Menu menu) {
|
||||||
|
return mLocalCallback.onCreatePanelMenu(i, menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreparePanel(int i, View view, Menu menu) {
|
||||||
|
return mLocalCallback.onPreparePanel(i, view, menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMenuOpened(int i, Menu menu) {
|
||||||
|
return mLocalCallback.onMenuOpened(i, menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemSelected(int i, MenuItem menuItem) {
|
||||||
|
return mLocalCallback.onMenuItemSelected(i, menuItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWindowAttributesChanged(WindowManager.LayoutParams layoutParams) {
|
||||||
|
mLocalCallback.onWindowAttributesChanged(layoutParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onContentChanged() {
|
||||||
|
mLocalCallback.onContentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWindowFocusChanged(boolean b) {
|
||||||
|
mLocalCallback.onWindowFocusChanged(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachedToWindow() {
|
||||||
|
mLocalCallback.onAttachedToWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachedFromWindow() {
|
||||||
|
mLocalCallback.onDetachedFromWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPanelClosed(int i, Menu menu) {
|
||||||
|
mLocalCallback.onPanelClosed(i, menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSearchRequested() {
|
||||||
|
return mLocalCallback.onSearchRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||||
|
@Override
|
||||||
|
public boolean onSearchRequested(SearchEvent searchEvent) {
|
||||||
|
return mLocalCallback.onSearchRequested(searchEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
|
||||||
|
return mLocalCallback.onWindowStartingActionMode(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int i) {
|
||||||
|
return mLocalCallback.onWindowStartingActionMode(callback, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActionModeStarted(ActionMode actionMode) {
|
||||||
|
mLocalCallback.onActionModeStarted(actionMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActionModeFinished(ActionMode actionMode) {
|
||||||
|
mLocalCallback.onActionModeFinished(actionMode);
|
||||||
|
}
|
||||||
|
}
|
81
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/ViewUtil.java
vendored
Normal file
81
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/util/ViewUtil.java
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package com.pchmn.materialchips.util;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.view.KeyCharacterMap;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.ViewConfiguration;
|
||||||
|
|
||||||
|
public class ViewUtil {
|
||||||
|
|
||||||
|
private static int windowWidthPortrait = 0;
|
||||||
|
private static int windowWidthLandscape = 0;
|
||||||
|
|
||||||
|
public static int dpToPx(int dp) {
|
||||||
|
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int pxToDp(int px) {
|
||||||
|
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getWindowWidth(Context context) {
|
||||||
|
if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
|
||||||
|
return getWindowWidthPortrait(context);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getWindowWidthLandscape(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getWindowWidthPortrait(Context context) {
|
||||||
|
if(windowWidthPortrait == 0) {
|
||||||
|
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
|
||||||
|
windowWidthPortrait = metrics.widthPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
return windowWidthPortrait;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getWindowWidthLandscape(Context context) {
|
||||||
|
if(windowWidthLandscape == 0) {
|
||||||
|
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
|
||||||
|
windowWidthLandscape = metrics.widthPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
return windowWidthLandscape;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getNavBarHeight(Context context) {
|
||||||
|
int result = 0;
|
||||||
|
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
|
||||||
|
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
|
||||||
|
|
||||||
|
if(!hasMenuKey && !hasBackKey) {
|
||||||
|
//The device has a navigation bar
|
||||||
|
Resources resources = context.getResources();
|
||||||
|
|
||||||
|
int orientation = context.getResources().getConfiguration().orientation;
|
||||||
|
int resourceId;
|
||||||
|
if (isTablet(context)){
|
||||||
|
resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape", "dimen", "android");
|
||||||
|
} else {
|
||||||
|
resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_width", "dimen", "android");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resourceId > 0) {
|
||||||
|
return context.getResources().getDimensionPixelSize(resourceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean isTablet(Context context) {
|
||||||
|
return (context.getResources().getConfiguration().screenLayout
|
||||||
|
& Configuration.SCREENLAYOUT_SIZE_MASK)
|
||||||
|
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
|
||||||
|
}
|
||||||
|
}
|
31
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/views/ChipsInputEditText.java
vendored
Normal file
31
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/views/ChipsInputEditText.java
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package com.pchmn.materialchips.views;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class ChipsInputEditText extends android.support.v7.widget.AppCompatEditText {
|
||||||
|
|
||||||
|
private FilterableListView filterableListView;
|
||||||
|
|
||||||
|
public ChipsInputEditText(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChipsInputEditText(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFilterableListVisible() {
|
||||||
|
return filterableListView != null && filterableListView.getVisibility() == VISIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterableListView getFilterableListView() {
|
||||||
|
return filterableListView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilterableListView(FilterableListView filterableListView) {
|
||||||
|
this.filterableListView = filterableListView;
|
||||||
|
}
|
||||||
|
}
|
233
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/views/DetailedChipView.java
vendored
Normal file
233
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/views/DetailedChipView.java
vendored
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
package com.pchmn.materialchips.views;
|
||||||
|
|
||||||
|
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.Drawable;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.AlphaAnimation;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.pchmn.materialchips.R;
|
||||||
|
import com.pchmn.materialchips.model.ChipInterface;
|
||||||
|
import com.pchmn.materialchips.util.ColorUtil;
|
||||||
|
import com.pchmn.materialchips.util.LetterTileProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class DetailedChipView extends LinearLayout {
|
||||||
|
|
||||||
|
private static final String TAG = DetailedChipView.class.toString();
|
||||||
|
// context
|
||||||
|
private Context mContext;
|
||||||
|
// xml elements
|
||||||
|
private LinearLayout mContentLayout;
|
||||||
|
private TextView mNameTextView;
|
||||||
|
private TextView mInfoTextView;
|
||||||
|
private ImageButton mDeleteButton;
|
||||||
|
// letter tile provider
|
||||||
|
private static LetterTileProvider mLetterTileProvider;
|
||||||
|
// attributes
|
||||||
|
private ColorStateList mBackgroundColor;
|
||||||
|
|
||||||
|
public DetailedChipView(Context context) {
|
||||||
|
super(context);
|
||||||
|
mContext = context;
|
||||||
|
init(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DetailedChipView(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.detailed_chip_view, this);
|
||||||
|
|
||||||
|
mContentLayout = (LinearLayout) rootView.findViewById(R.id.content);
|
||||||
|
mNameTextView = (TextView) rootView.findViewById(R.id.name);
|
||||||
|
mInfoTextView = (TextView) rootView.findViewById(R.id.info);
|
||||||
|
mDeleteButton = (ImageButton) rootView.findViewById(R.id.delete_button);
|
||||||
|
|
||||||
|
// letter tile provider
|
||||||
|
mLetterTileProvider = new LetterTileProvider(mContext);
|
||||||
|
|
||||||
|
// hide on first
|
||||||
|
setVisibility(GONE);
|
||||||
|
// hide on touch outside
|
||||||
|
hideOnTouchOutside();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the view on touch outside of it
|
||||||
|
*/
|
||||||
|
private void hideOnTouchOutside() {
|
||||||
|
// set focusable
|
||||||
|
setFocusable(true);
|
||||||
|
setFocusableInTouchMode(true);
|
||||||
|
setClickable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fade in
|
||||||
|
*/
|
||||||
|
public void fadeIn() {
|
||||||
|
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
|
||||||
|
anim.setDuration(200);
|
||||||
|
startAnimation(anim);
|
||||||
|
setVisibility(VISIBLE);
|
||||||
|
// focus on the view
|
||||||
|
requestFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fade out
|
||||||
|
*/
|
||||||
|
public void fadeOut() {
|
||||||
|
AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f);
|
||||||
|
anim.setDuration(200);
|
||||||
|
startAnimation(anim);
|
||||||
|
setVisibility(GONE);
|
||||||
|
// fix onclick issue
|
||||||
|
clearFocus();
|
||||||
|
setClickable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
mNameTextView.setText(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInfo(String info) {
|
||||||
|
if(info != null) {
|
||||||
|
mInfoTextView.setVisibility(VISIBLE);
|
||||||
|
mInfoTextView.setText(info);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mInfoTextView.setVisibility(GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextColor(ColorStateList color) {
|
||||||
|
mNameTextView.setTextColor(color);
|
||||||
|
mInfoTextView.setTextColor(ColorUtil.alpha(color.getDefaultColor(), 150));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackGroundcolor(ColorStateList color) {
|
||||||
|
mBackgroundColor = color;
|
||||||
|
mContentLayout.getBackground().setColorFilter(color.getDefaultColor(), PorterDuff.Mode.SRC_ATOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBackgroundColor() {
|
||||||
|
return mBackgroundColor == null ? ContextCompat.getColor(mContext, R.color.colorAccent) : mBackgroundColor.getDefaultColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleteIconColor(ColorStateList color) {
|
||||||
|
mDeleteButton.getDrawable().mutate().setColorFilter(color.getDefaultColor(), PorterDuff.Mode.SRC_ATOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnDeleteClicked(OnClickListener onClickListener) {
|
||||||
|
mDeleteButton.setOnClickListener(onClickListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void alignLeft() {
|
||||||
|
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mContentLayout.getLayoutParams();
|
||||||
|
params.leftMargin = 0;
|
||||||
|
mContentLayout.setLayoutParams(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void alignRight() {
|
||||||
|
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mContentLayout.getLayoutParams();
|
||||||
|
params.rightMargin = 0;
|
||||||
|
mContentLayout.setLayoutParams(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private Context context;
|
||||||
|
private String name;
|
||||||
|
private String info;
|
||||||
|
private ColorStateList textColor;
|
||||||
|
private ColorStateList backgroundColor;
|
||||||
|
private ColorStateList deleteIconColor;
|
||||||
|
|
||||||
|
public Builder(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder info(String info) {
|
||||||
|
this.info = info;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder chip(ChipInterface chip) {
|
||||||
|
this.name = chip.getLabel();
|
||||||
|
this.info = chip.getInfo();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder textColor(ColorStateList textColor) {
|
||||||
|
this.textColor = textColor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder backgroundColor(ColorStateList backgroundColor) {
|
||||||
|
this.backgroundColor = backgroundColor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder deleteIconColor(ColorStateList deleteIconColor) {
|
||||||
|
this.deleteIconColor = deleteIconColor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DetailedChipView build() {
|
||||||
|
return DetailedChipView.newInstance(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DetailedChipView newInstance(Builder builder) {
|
||||||
|
DetailedChipView detailedChipView = new DetailedChipView(builder.context);
|
||||||
|
// avatar
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
156
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/views/FilterableListView.java
vendored
Normal file
156
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/views/FilterableListView.java
vendored
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
package com.pchmn.materialchips.views;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
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;
|
||||||
|
import android.view.animation.AlphaAnimation;
|
||||||
|
import android.widget.Filter;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
import com.pchmn.materialchips.ChipsInput;
|
||||||
|
import com.pchmn.materialchips.R;
|
||||||
|
import com.pchmn.materialchips.adapter.FilterableAdapter;
|
||||||
|
import com.pchmn.materialchips.model.ChipInterface;
|
||||||
|
import com.pchmn.materialchips.util.ViewUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class FilterableListView extends RelativeLayout {
|
||||||
|
|
||||||
|
private static final String TAG = FilterableListView.class.toString();
|
||||||
|
private FrameLayout frameLayout;
|
||||||
|
private Context mContext;
|
||||||
|
// list
|
||||||
|
private RecyclerView mRecyclerView;
|
||||||
|
private FilterableAdapter mAdapter;
|
||||||
|
private List<? extends ChipInterface> mFilterableList;
|
||||||
|
// others
|
||||||
|
private ChipsInput mChipsInput;
|
||||||
|
private ViewGroup rootView;
|
||||||
|
|
||||||
|
public FilterableListView(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterableListView(Context context, ViewGroup layout) {
|
||||||
|
super(context);
|
||||||
|
this.mContext = context;
|
||||||
|
this.rootView = layout;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
// inflate layout
|
||||||
|
View view = inflate(getContext(), R.layout.list_filterable_view, this);
|
||||||
|
|
||||||
|
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
|
||||||
|
|
||||||
|
// recycler
|
||||||
|
mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false));
|
||||||
|
|
||||||
|
// hide on first
|
||||||
|
setVisibility(GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void build(List<? extends ChipInterface> filterableList, ChipsInput chipsInput, ColorStateList backgroundColor, ColorStateList textColor) {
|
||||||
|
mFilterableList = filterableList;
|
||||||
|
mChipsInput = chipsInput;
|
||||||
|
|
||||||
|
// adapter
|
||||||
|
mAdapter = new FilterableAdapter(mContext, mRecyclerView, filterableList, chipsInput, backgroundColor, textColor);
|
||||||
|
mRecyclerView.setAdapter(mAdapter);
|
||||||
|
if(backgroundColor != null)
|
||||||
|
mRecyclerView.getBackground().setColorFilter(backgroundColor.getDefaultColor(), PorterDuff.Mode.SRC_ATOP);
|
||||||
|
|
||||||
|
// listen to change in the tree
|
||||||
|
mChipsInput.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
|
||||||
|
// position
|
||||||
|
if(rootView == null){
|
||||||
|
rootView = (ViewGroup) mChipsInput.getRootView();
|
||||||
|
}
|
||||||
|
|
||||||
|
// size
|
||||||
|
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
|
||||||
|
ViewUtil.getWindowWidth(mContext),
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
|
||||||
|
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
|
||||||
|
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||||
|
|
||||||
|
if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
|
layoutParams.bottomMargin = ViewUtil.getNavBarHeight(mContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If this child view is already added to the parent rootView, then remove it first
|
||||||
|
ViewGroup parent = (ViewGroup) FilterableListView.this.getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
parent.removeView(FilterableListView.this);
|
||||||
|
}
|
||||||
|
// add view
|
||||||
|
rootView.addView(FilterableListView.this, layoutParams);
|
||||||
|
|
||||||
|
|
||||||
|
// remove the listener:
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
mChipsInput.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||||
|
} else {
|
||||||
|
mChipsInput.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void filterList(CharSequence text) {
|
||||||
|
mAdapter.getFilter().filter(text, new Filter.FilterListener() {
|
||||||
|
@Override
|
||||||
|
public void onFilterComplete(int count) {
|
||||||
|
// show if there are results
|
||||||
|
if(mAdapter.getItemCount() > 0)
|
||||||
|
fadeIn();
|
||||||
|
else
|
||||||
|
fadeOut();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fade in
|
||||||
|
*/
|
||||||
|
public void fadeIn() {
|
||||||
|
if(getVisibility() == VISIBLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
|
||||||
|
anim.setDuration(200);
|
||||||
|
startAnimation(anim);
|
||||||
|
setVisibility(VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fade out
|
||||||
|
*/
|
||||||
|
public void fadeOut() {
|
||||||
|
if(getVisibility() == GONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f);
|
||||||
|
anim.setDuration(200);
|
||||||
|
startAnimation(anim);
|
||||||
|
setVisibility(GONE);
|
||||||
|
}
|
||||||
|
}
|
49
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/views/ScrollViewMaxHeight.java
vendored
Normal file
49
extern/MaterialChipsInput/src/main/java/com/pchmn/materialchips/views/ScrollViewMaxHeight.java
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package com.pchmn.materialchips.views;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.support.v4.widget.NestedScrollView;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import com.pchmn.materialchips.R;
|
||||||
|
import com.pchmn.materialchips.util.ViewUtil;
|
||||||
|
|
||||||
|
public class ScrollViewMaxHeight extends NestedScrollView {
|
||||||
|
|
||||||
|
private int mMaxHeight;
|
||||||
|
private int mWidthMeasureSpec;
|
||||||
|
|
||||||
|
public ScrollViewMaxHeight(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScrollViewMaxHeight(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
|
||||||
|
TypedArray a = context.getTheme().obtainStyledAttributes(
|
||||||
|
attrs,
|
||||||
|
R.styleable.ScrollViewMaxHeight,
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mMaxHeight = a.getDimensionPixelSize(R.styleable.ScrollViewMaxHeight_maxHeight, ViewUtil.dpToPx(300));
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
a.recycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxHeight(int height) {
|
||||||
|
mMaxHeight = height;
|
||||||
|
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxHeight, MeasureSpec.AT_MOST);
|
||||||
|
measure(mWidthMeasureSpec, heightMeasureSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
mWidthMeasureSpec = widthMeasureSpec;
|
||||||
|
heightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxHeight, MeasureSpec.AT_MOST);
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
}
|
||||||
|
}
|
11
extern/MaterialChipsInput/src/main/res/drawable-v21/ripple_chip_view.xml
vendored
Normal file
11
extern/MaterialChipsInput/src/main/res/drawable-v21/ripple_chip_view.xml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:color="?android:attr/colorControlHighlight">
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/white_transparency" />
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:drawable="@drawable/bg_chip_view" />
|
||||||
|
</ripple>
|
10
extern/MaterialChipsInput/src/main/res/drawable/bg_chip_view.xml
vendored
Normal file
10
extern/MaterialChipsInput/src/main/res/drawable/bg_chip_view.xml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@color/colorChipViewBackground"/>
|
||||||
|
<corners android:radius="16dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
10
extern/MaterialChipsInput/src/main/res/drawable/bg_chip_view_opened.xml
vendored
Normal file
10
extern/MaterialChipsInput/src/main/res/drawable/bg_chip_view_opened.xml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@color/colorAccent"/>
|
||||||
|
<corners android:radius="2dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
9
extern/MaterialChipsInput/src/main/res/drawable/ic_cancel_grey_24dp.xml
vendored
Normal file
9
extern/MaterialChipsInput/src/main/res/drawable/ic_cancel_grey_24dp.xml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#A6A6A6"
|
||||||
|
android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
|
||||||
|
</vector>
|
9
extern/MaterialChipsInput/src/main/res/drawable/ic_cancel_white_24dp.xml
vendored
Normal file
9
extern/MaterialChipsInput/src/main/res/drawable/ic_cancel_white_24dp.xml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#fff"
|
||||||
|
android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
|
||||||
|
</vector>
|
9
extern/MaterialChipsInput/src/main/res/drawable/ic_person_outline_white_24dp.xml
vendored
Normal file
9
extern/MaterialChipsInput/src/main/res/drawable/ic_person_outline_white_24dp.xml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#fff"
|
||||||
|
android:pathData="M12,5.9c1.16,0 2.1,0.94 2.1,2.1s-0.94,2.1 -2.1,2.1S9.9,9.16 9.9,8s0.94,-2.1 2.1,-2.1m0,9c2.97,0 6.1,1.46 6.1,2.1v1.1L5.9,18.1L5.9,17c0,-0.64 3.13,-2.1 6.1,-2.1M12,4C9.79,4 8,5.79 8,8s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,13c-2.67,0 -8,1.34 -8,4v3h16v-3c0,-2.66 -5.33,-4 -8,-4z"/>
|
||||||
|
</vector>
|
9
extern/MaterialChipsInput/src/main/res/drawable/ic_person_white_24dp.xml
vendored
Normal file
9
extern/MaterialChipsInput/src/main/res/drawable/ic_person_white_24dp.xml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#aaffffff"
|
||||||
|
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
|
||||||
|
</vector>
|
10
extern/MaterialChipsInput/src/main/res/drawable/ripple_chip_view.xml
vendored
Normal file
10
extern/MaterialChipsInput/src/main/res/drawable/ripple_chip_view.xml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@color/colorChipViewBackground"/>
|
||||||
|
<corners android:radius="16dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
41
extern/MaterialChipsInput/src/main/res/layout/chip_view.xml
vendored
Normal file
41
extern/MaterialChipsInput/src/main/res/layout/chip_view.xml
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_chip_view">
|
||||||
|
|
||||||
|
<!-- content -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:background="@drawable/ripple_chip_view">
|
||||||
|
|
||||||
|
<!-- label -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:text="Paulcito"/>
|
||||||
|
|
||||||
|
<!-- remove button -->
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/delete_button"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:src="@drawable/ic_cancel_grey_24dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:layout_marginRight="4dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
17
extern/MaterialChipsInput/src/main/res/layout/chips_input.xml
vendored
Normal file
17
extern/MaterialChipsInput/src/main/res/layout/chips_input.xml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.pchmn.materialchips.views.ScrollViewMaxHeight xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:scrollbars="vertical"
|
||||||
|
app:maxHeight="150dp" >
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/chips_recycler"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp" />
|
||||||
|
|
||||||
|
</com.pchmn.materialchips.views.ScrollViewMaxHeight>
|
75
extern/MaterialChipsInput/src/main/res/layout/detailed_chip_view.xml
vendored
Normal file
75
extern/MaterialChipsInput/src/main/res/layout/detailed_chip_view.xml
vendored
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true">
|
||||||
|
|
||||||
|
<!-- content -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:layout_marginLeft="12dp"
|
||||||
|
android:layout_marginRight="12dp"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:background="@drawable/bg_chip_view_opened"
|
||||||
|
android:clickable="true"
|
||||||
|
android:elevation="6dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
tools:targetApi="lollipop">
|
||||||
|
|
||||||
|
<!-- info -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/info_layout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginLeft="12dp"
|
||||||
|
android:layout_marginRight="12dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="16dp"
|
||||||
|
android:paddingTop="16dp">
|
||||||
|
|
||||||
|
<!-- name -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:scrollHorizontally="true"
|
||||||
|
android:text="sdfdsfdsfdgs"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<!-- info -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/info"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:scrollHorizontally="true"
|
||||||
|
android:text="paul@gmail.com"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- delete button -->
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/delete_button"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginRight="10dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/ic_cancel_white_24dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
42
extern/MaterialChipsInput/src/main/res/layout/item_list_filterable.xml
vendored
Normal file
42
extern/MaterialChipsInput/src/main/res/layout/item_list_filterable.xml
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clickable="true"
|
||||||
|
android:background="@android:color/white"
|
||||||
|
android:foreground="?attr/selectableItemBackground">
|
||||||
|
|
||||||
|
<!-- info -->
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
android:layout_marginLeft="18dp"
|
||||||
|
android:layout_marginRight="16dp">
|
||||||
|
|
||||||
|
<!-- name -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
android:text="Two line item"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/info"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="2dp"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:text="secondary text"/>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
13
extern/MaterialChipsInput/src/main/res/layout/list_filterable_view.xml
vendored
Normal file
13
extern/MaterialChipsInput/src/main/res/layout/list_filterable_view.xml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scrollbars="vertical"
|
||||||
|
android:background="@android:color/white" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
34
extern/MaterialChipsInput/src/main/res/values/attrs.xml
vendored
Normal file
34
extern/MaterialChipsInput/src/main/res/values/attrs.xml
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<declare-styleable name="ChipView">
|
||||||
|
<attr name="label" format="string" />
|
||||||
|
<attr name="labelColor" format="color" />
|
||||||
|
<attr name="deletable" format="boolean" />
|
||||||
|
<attr name="deleteIcon" format="reference" />
|
||||||
|
<attr name="deleteIconColor" format="color" />
|
||||||
|
<attr name="backgroundColor" format="color" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
<declare-styleable name="ChipsInput">
|
||||||
|
<attr name="hint" format="string" />
|
||||||
|
<attr name="hintColor" format="color" />
|
||||||
|
<attr name="textColor" format="color" />
|
||||||
|
<attr name="maxRows" format="integer" />
|
||||||
|
<attr name="chip_labelColor" format="color" />
|
||||||
|
<attr name="chip_deletable" format="boolean" />
|
||||||
|
<attr name="chip_deleteIcon" format="reference" />
|
||||||
|
<attr name="chip_deleteIconColor" format="color" />
|
||||||
|
<attr name="chip_backgroundColor" format="color" />
|
||||||
|
<attr name="showChipDetailed" format="boolean" />
|
||||||
|
<attr name="chip_detailed_textColor" format="color" />
|
||||||
|
<attr name="chip_detailed_backgroundColor" format="color" />
|
||||||
|
<attr name="chip_detailed_deleteIconColor" format="color" />
|
||||||
|
<attr name="filterable_list_backgroundColor" format="color" />
|
||||||
|
<attr name="filterable_list_textColor" format="color" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
<declare-styleable name="ScrollViewMaxHeight">
|
||||||
|
<attr name="maxHeight" format="dimension" />
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
10
extern/MaterialChipsInput/src/main/res/values/colors.xml
vendored
Normal file
10
extern/MaterialChipsInput/src/main/res/values/colors.xml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<color name="colorChipViewBackground">#E0E0E0</color>
|
||||||
|
<color name="chips_opened_bg">#009688</color>
|
||||||
|
<color name="colorCloseChip">#ababab</color>
|
||||||
|
<color name="white_transparency">#b9ffffff</color>
|
||||||
|
<color name="colorAccent">?attr/colorAccent</color>
|
||||||
|
|
||||||
|
</resources>
|
20
extern/MaterialChipsInput/src/main/res/values/strings.xml
vendored
Normal file
20
extern/MaterialChipsInput/src/main/res/values/strings.xml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<resources>
|
||||||
|
<!-- LetterTileProvider -->
|
||||||
|
<!-- All of the possible tile background colors -->
|
||||||
|
<array name="letter_tile_colors">
|
||||||
|
<item>#f16364</item>
|
||||||
|
<item>#f58559</item>
|
||||||
|
<item>#f9a43e</item>
|
||||||
|
<item>#e4c62e</item>
|
||||||
|
<item>#67bf74</item>
|
||||||
|
<item>#59a2be</item>
|
||||||
|
<item>#2093cd</item>
|
||||||
|
<item>#ad62a7</item>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<!-- The default letter tile text size -->
|
||||||
|
<dimen name="tile_letter_font_size">17sp</dimen>
|
||||||
|
<!-- The deafult tile size -->
|
||||||
|
<dimen name="letter_tile_size">32dp</dimen>
|
||||||
|
<!-- /LetterTileProvider -->
|
||||||
|
</resources>
|
17
extern/MaterialChipsInput/src/test/java/com/pchmn/materialchips/ExampleUnitTest.java
vendored
Normal file
17
extern/MaterialChipsInput/src/test/java/com/pchmn/materialchips/ExampleUnitTest.java
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package com.pchmn.materialchips;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||||
|
*/
|
||||||
|
public class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
public void addition_isCorrect() throws Exception {
|
||||||
|
assertEquals(4, 2 + 2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ include ':extern:bouncycastle:core'
|
||||||
include ':extern:bouncycastle:pg'
|
include ':extern:bouncycastle:pg'
|
||||||
include ':extern:bouncycastle:prov'
|
include ':extern:bouncycastle:prov'
|
||||||
include ':extern:minidns'
|
include ':extern:minidns'
|
||||||
|
include ':extern:MaterialChipsInput:library'
|
||||||
|
|
||||||
// Workaround for Android Gradle Plugin 2.0, as described in http://stackoverflow.com/a/36544850
|
// Workaround for Android Gradle Plugin 2.0, as described in http://stackoverflow.com/a/36544850
|
||||||
//include ':libkeychain'
|
//include ':libkeychain'
|
||||||
|
|
Loading…
Reference in a new issue