Repository: Kaka252/FlexboxUtils
Branch: master
Commit: e3fb54ae490f
Files: 41
Total size: 43.1 KB
Directory structure:
gitextract_7e674wrr/
├── .gitignore
├── .idea/
│ ├── copyright/
│ │ └── profiles_settings.xml
│ ├── gradle.xml
│ └── runConfigurations.xml
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── zhouyou/
│ │ └── flexbox/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── zhouyou/
│ │ │ └── flexbox/
│ │ │ ├── MainActivity.java
│ │ │ ├── StringTagAdapter.java
│ │ │ └── StringTagView.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── bg_flow_divider.xml
│ │ │ ├── bg_flow_selected.xml
│ │ │ └── bg_flow_unselect.xml
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test/
│ └── java/
│ └── com/
│ └── zhouyou/
│ └── flexbox/
│ └── ExampleUnitTest.java
├── build.gradle
├── flexbox/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── zhouyou/
│ │ └── flexbox/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── zhouyou/
│ │ │ └── flexbox/
│ │ │ ├── adapter/
│ │ │ │ └── TagAdapter.java
│ │ │ ├── interfaces/
│ │ │ │ ├── OnFlexboxSubscribeListener.java
│ │ │ │ └── TagWithListener.java
│ │ │ └── widget/
│ │ │ ├── BaseTagView.java
│ │ │ └── TagFlowLayout.java
│ │ └── res/
│ │ └── values/
│ │ ├── attrs.xml
│ │ └── strings.xml
│ └── test/
│ └── java/
│ └── zhouyou/
│ └── flexbox/
│ └── ExampleUnitTest.java
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.idea/misc.xml
.idea/encodings.xml
.idea/modules.xml
.idea/compiler.xml
.idea/vcs.xml
.idea/markdown-navigator
.idea/markdown-navigator.xml
.DS_Store
/build
/captures
.externalNativeBuild
app/libs/
flexbox/libs/
flexbox/src/main/res/drawable/
================================================
FILE: .idea/copyright/profiles_settings.xml
================================================
<component name="CopyrightManager">
<settings default="" />
</component>
================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/flexbox" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
================================================
FILE: README.md
================================================
# FlexboxUtils
Google在之前发布了一个叫做FlexboxLayout的控件,完全能够适配平时我们业务中自定义的布局流控件,而且有过之而无不及。因此在这个基础上我又针对这个控件进行了进一步的封装,基本能够满足平时大部分的业务需求,先上图

# 继承BaseTagView
定义一个TagView,继承BaseTagView,由于每一个tag的数据类型不确定,因此需要传入一个固定的数据类型满足实际需求
```
public class StringTagView extends BaseTagView<String> {
public StringTagView(Context context) {
this(context, null);
}
public StringTagView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs, 0);
}
public StringTagView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setItem(String item) {
super.setItem(item);
textView.setText(item);
}
}
```
# 继承TagAdapter
定义一个Adapter,继承TagAdapter,并实现相应的方法
```
public class StringTagAdapter extends TagAdapter<StringTagView, String> {
StringTagAdapter(Context context, List<String> data) {
this(context, data, null);
}
StringTagAdapter(Context context, List<String> data, List<String> selectItems) {
super(context, data, selectItems);
}
/**
* 检查item和所选item是否一样
*
* @param view
* @param item
* @return
*/
@Override
protected boolean checkIsItemSame(StringTagView view, String item) {
return TextUtils.equals(view.getItem(), item);
}
/**
* 检查item是否是空指针
*
* @return
*/
@Override
protected boolean checkIsItemNull(String item) {
return TextUtils.isEmpty(item);
}
/**
* 添加标签
*
* @param item
* @return
*/
@Override
protected StringTagView addTag(String item) {
StringTagView tagView = new StringTagView(getContext());
tagView.setPadding(20, 20, 20, 20);
TextView textView = tagView.getTextView();
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setGravity(Gravity.CENTER);
tagView.setItemDefaultDrawable(itemDefaultDrawable);
tagView.setItemSelectDrawable(itemSelectDrawable);
tagView.setItemDefaultTextColor(itemDefaultTextColor);
tagView.setItemSelectTextColor(itemSelectTextColor);
tagView.setItem(item);
return tagView;
}
}
```
# 使用
在xml中,你可以使用如下配置:
```
<resources>
<declare-styleable name="TagFlowLayout">
<attr name="showHighlight" format="boolean" /> // 是否选中高亮
<attr name="defaultDrawable" format="reference" /> // 默认标签背景
<attr name="selectDrawable" format="reference" /> // 选中标签背景
<attr name="defaultTextColor" format="color|reference"/> // 默认标签文字颜色
<attr name="selectTextColor" format="color|reference" /> // 选中标签文字颜色
<attr name="mode"> // 单选或者多选
<enum name="MULTI" value="0" /> // 默认多选
<enum name="SINGLE" value="1"/> // 单选
</attr>
</declare-styleable>
</resources>
```
```
<zhouyou.flexbox.widget.TagFlowLayout
android:id="@+id/flow_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:alignContent="flex_start"
app:alignItems="center"
app:dividerDrawable="@drawable/bg_flow_divider"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="flex_start"
app:showDivider="beginning|middle|end"
app:selectDrawable="@drawable/bg_flow_selected"
app:defaultDrawable="@drawable/bg_flow_unselect"
app:selectTextColor="@android:color/white"
app:defaultTextColor="@color/app_green"
app:mode="SINGLE"/>
```
也可以使用Java代码进行属性配置
```
TagFlowLayout flowLayout = (TagFlowLayout) findViewById(R.id.flow_layout);
flowLayout.setShowHighlight(false);
flowLayout.setItemDefaultDrawable(R.drawable.bg_flow_unselect);
flowLayout.setItemSelectDrawable(R.drawable.bg_flow_selected);
flowLayout.setItemDefaultTextColor(ContextCompat.getColor(this, R.color.app_green));
flowLayout.setItemSelectTextColor(Color.WHITE);
flowLayout.setMode(TagFlowLayout.MODE_SINGLE_SELECT);
```
# 回调
可以使用如下回调来获取最终所选择的项目列表
```
...
adapter.setOnSubscribeListener(new OnFlexboxSubscribeListener<String>() {
@Override
public void onSubscribe(List<String> selectedItem) {
}
});
```
# 操作模式
可以通过设置模式来控制标签的单选与多选操作
```
...
flowLayout.setMode(TagFlowLayout.MODE_SINGLE_SELECT);
```
# 选中高亮效果
可以设置是否选中高亮,默认为选中高亮
```
...
flowLayout.setShowHighlight(false);
```
# 绑定数据到控件
通过声明TagFlowLayout,并且调用setAdapter()方法来接收之前定义好的adapter即可
```
...
flowLayout.setAdapter(adapter);
```
# 切换、刷新数据
在声明的adapter基础上,重新设置数据源和已选项,notifyDataSetChanged()方法即可完成数据刷新操作
```
...
adapter.setSource(data);
adapter.setSelectItems(selectItems);
adapter.notifyDataSetChanged();
```
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.zhouyou.flexbox"
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
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:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'
testCompile 'junit:junit:4.12'
compile project(path: ':flexbox')
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\DESKTOP\AppData\Local\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
================================================
FILE: app/src/androidTest/java/com/zhouyou/flexbox/ExampleInstrumentedTest.java
================================================
package com.zhouyou.flexbox;
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.zhouyou.flexbox", appContext.getPackageName());
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zhouyou.flexbox" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: app/src/main/java/com/zhouyou/flexbox/MainActivity.java
================================================
package com.zhouyou.flexbox;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
import zhouyou.flexbox.interfaces.OnFlexboxSubscribeListener;
import zhouyou.flexbox.widget.TagFlowLayout;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btnCount;
private StringTagAdapter adapter;
private List<String> sourceData;
private List<String> selectItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initViews();
}
private void initData() {
sourceData = new ArrayList<>();
sourceData.add("程序员");
sourceData.add("设计师");
sourceData.add("产品经理");
sourceData.add("运营");
sourceData.add("商务");
sourceData.add("人事经理");
sourceData.add("项目经理");
sourceData.add("客户代表");
sourceData.add("技术主管");
sourceData.add("测试工程师");
sourceData.add("前端工程师");
sourceData.add("Java工程师");
sourceData.add("Android工程师");
sourceData.add("iOS工程师");
selectItems = new ArrayList<>();
selectItems.add("客户代表");
selectItems.add("Java工程师");
}
private void initViews() {
TagFlowLayout flowLayout = (TagFlowLayout) findViewById(R.id.flow_layout);
btnCount = (Button) findViewById(R.id.btn_get_count);
adapter = new StringTagAdapter(this, sourceData, selectItems);
adapter.setOnSubscribeListener(new OnFlexboxSubscribeListener<String>() {
@Override
public void onSubscribe(List<String> selectedItem) {
btnCount.setText("已选择" + selectedItem.size() + "个");
}
});
flowLayout.setAdapter(adapter);
btnCount.setText("已选择" + adapter.getSelectedList().size() + "个");
findViewById(R.id.btn_switch_data).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_switch_data:
List<String> data = new ArrayList<>();
data.add("客户代表");
data.add("Java工程师");
List<String> selectList = new ArrayList<>();
selectList.add("客户代表");
adapter.setSource(data);
adapter.setSelectItems(selectList);
adapter.notifyDataSetChanged();
break;
default:
break;
}
}
}
================================================
FILE: app/src/main/java/com/zhouyou/flexbox/StringTagAdapter.java
================================================
package com.zhouyou.flexbox;
import android.content.Context;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.TextView;
import java.util.List;
import zhouyou.flexbox.adapter.TagAdapter;
/**
* 作者:ZhouYou
* 日期:2017/3/27
*/
public class StringTagAdapter extends TagAdapter<StringTagView, String> {
StringTagAdapter(Context context, List<String> data) {
this(context, data, null);
}
StringTagAdapter(Context context, List<String> data, List<String> selectItems) {
super(context, data, selectItems);
}
/**
* 检查item和所选item是否一样
*
* @param view
* @param item
* @return
*/
@Override
protected boolean checkIsItemSame(StringTagView view, String item) {
return TextUtils.equals(view.getItem(), item);
}
/**
* 检查item是否是空指针
*
* @return
*/
@Override
protected boolean checkIsItemNull(String item) {
return TextUtils.isEmpty(item);
}
/**
* 添加标签
*
* @param item
* @return
*/
@Override
protected StringTagView addTag(String item) {
StringTagView tagView = new StringTagView(getContext());
tagView.setPadding(20, 20, 20, 20);
TextView textView = tagView.getTextView();
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setGravity(Gravity.CENTER);
tagView.setItemDefaultDrawable(itemDefaultDrawable);
tagView.setItemSelectDrawable(itemSelectDrawable);
tagView.setItemDefaultTextColor(itemDefaultTextColor);
tagView.setItemSelectTextColor(itemSelectTextColor);
tagView.setItem(item);
return tagView;
}
}
================================================
FILE: app/src/main/java/com/zhouyou/flexbox/StringTagView.java
================================================
package com.zhouyou.flexbox;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import zhouyou.flexbox.widget.BaseTagView;
/**
* 作者:ZhouYou
* 日期:2017/3/25.
*/
public class StringTagView extends BaseTagView<String> {
public StringTagView(Context context) {
this(context, null);
}
public StringTagView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs, 0);
}
public StringTagView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setItem(String item) {
super.setItem(item);
textView.setText(item);
}
}
================================================
FILE: app/src/main/res/drawable/bg_flow_divider.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/transparent" />
<size
android:width="10dip"
android:height="10dip" />
</shape>
================================================
FILE: app/src/main/res/drawable/bg_flow_selected.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/app_green" />
<corners android:radius="4dip" />
</shape>
================================================
FILE: app/src/main/res/drawable/bg_flow_unselect.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="0.5dip"
android:color="@color/app_green" />
<solid android:color="@android:color/transparent" />
<corners android:radius="4dip" />
</shape>
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.zhouyou.flexbox.MainActivity">
<zhouyou.flexbox.widget.TagFlowLayout
android:id="@+id/flow_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:alignContent="flex_start"
app:alignItems="center"
app:dividerDrawable="@drawable/bg_flow_divider"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="flex_start"
app:showDivider="beginning|middle|end"
app:selectDrawable="@drawable/bg_flow_selected"
app:defaultDrawable="@drawable/bg_flow_unselect"
app:selectTextColor="@android:color/white"
app:defaultTextColor="@color/app_green"
app:mode="MULTI"/>
<Button
android:id="@+id/btn_get_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="请选择" />
<Button
android:id="@+id/btn_switch_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="切换数据" />
</LinearLayout>
================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="app_green">#53CAC3</color>
</resources>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">FlexboxDemo</string>
</resources>
================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
================================================
FILE: app/src/test/java/com/zhouyou/flexbox/ExampleUnitTest.java
================================================
package com.zhouyou.flexbox;
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);
}
}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: flexbox/.gitignore
================================================
/build
================================================
FILE: flexbox/build.gradle
================================================
apply plugin: 'com.android.library'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
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:25.3.1'
testCompile 'junit:junit:4.12'
compile 'com.google.android:flexbox:0.2.6'
}
================================================
FILE: flexbox/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\DESKTOP\AppData\Local\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
================================================
FILE: flexbox/src/androidTest/java/zhouyou/flexbox/ExampleInstrumentedTest.java
================================================
package zhouyou.flexbox;
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("zhouyou.flexbox.test", appContext.getPackageName());
}
}
================================================
FILE: flexbox/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="zhouyou.flexbox">
<application android:allowBackup="true" android:label="@string/app_name"
android:supportsRtl="true">
</application>
</manifest>
================================================
FILE: flexbox/src/main/java/zhouyou/flexbox/adapter/TagAdapter.java
================================================
package zhouyou.flexbox.adapter;
import android.content.Context;
import android.support.v4.util.ArrayMap;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import zhouyou.flexbox.widget.BaseTagView;
import zhouyou.flexbox.interfaces.OnFlexboxSubscribeListener;
import zhouyou.flexbox.widget.TagFlowLayout;
import zhouyou.flexbox.interfaces.TagWithListener;
/**
* 作者:ZhouYou
* 日期:2017/3/27.
*/
public abstract class TagAdapter<V extends BaseTagView<T>, T> {
private Context context;
/**
* 根布局
*/
private TagFlowLayout rootView;
/**
* 数据源
*/
private List<T> source;
/**
* 已选项目
*/
private List<T> selectItems;
/*view和tag的对应关系*/
private Map<V, T> viewMap;
/*标签选择操作的订阅接口*/
private OnFlexboxSubscribeListener<T> onSubscribeListener;
/*是否展示选中效果*/
private boolean isShowHighlight = true;
/*可选标签的最大数量*/
private int maxSelection;
/*默认和已选的背景*/
protected int itemDefaultDrawable;
protected int itemSelectDrawable;
/*默认和已选的文字颜色*/
protected int itemDefaultTextColor;
protected int itemSelectTextColor;
/*操作模式 0 - 多选 | 1 - 单选*/
private int mode;
public void setOnSubscribeListener(OnFlexboxSubscribeListener<T> onSubscribeListener) {
this.onSubscribeListener = onSubscribeListener;
}
public void setSource(List<T> source) {
this.source = source;
}
public void setSelectItems(List<T> selectItems) {
this.selectItems = selectItems;
}
public List<T> getSelectItems() {
return selectItems;
}
public TagAdapter(Context context, List<T> source) {
this.context = context;
this.source = source;
viewMap = new ArrayMap<>();
}
public TagAdapter(Context context, List<T> source, List<T> selectItems) {
this.context = context;
this.source = source;
this.selectItems = selectItems;
viewMap = new ArrayMap<>();
}
public Context getContext() {
return context;
}
public List<T> getData() {
return source;
}
/**
* 绑定控件
*
* @param rootView
*/
public void bindView(TagFlowLayout rootView) {
if (rootView == null) {
throw new NullPointerException("未初始化TagFlowLayout");
}
this.rootView = rootView;
isShowHighlight = rootView.isShowHighlight();
itemDefaultDrawable = rootView.getItemDefaultDrawable();
itemSelectDrawable = rootView.getItemSelectDrawable();
itemDefaultTextColor = rootView.getItemDefaultTextColor();
itemSelectTextColor = rootView.getItemSelectTextColor();
maxSelection = rootView.getMaxSelection();
mode = rootView.getMode();
}
/**
* 设置标签组
*/
public void addTags() {
if (source == null || source.size() <= 0) return;
rootView.removeAllViews();
for (T item : source) {
if (item == null) continue;
final BaseTagView<T> view = addTag(item);
initSelectedViews((V) view);
// 单个item的点击监控
view.setListener(new TagWithListener<T>() {
@Override
public void onItemSelect(T item) {
if (mode == TagFlowLayout.MODE_SINGLE_SELECT) {
if (isShowHighlight) view.selectItemChangeColorState();
singleSelectMode(item);
} else {
List<T> selectList = getSelectedList();
if ((maxSelection <= selectList.size() && maxSelection > 0) && !view.isItemSelected()) {
Toast.makeText(getContext(), "最多选择" + maxSelection + "个标签", Toast.LENGTH_SHORT).show();
return;
}
if (isShowHighlight) view.selectItemChangeColorState();
}
if (onSubscribeListener != null) {
onSubscribeListener.onSubscribe(getSelectedList());
}
}
});
viewMap.put((V) view, item);
rootView.addView(view);
}
}
/**
* 设置在初始化时所选中的View
*
* @param view
*/
private void initSelectedViews(V view) {
if (!isShowHighlight) return;
if (selectItems == null || selectItems.size() <= 0) return;
for (T select : selectItems) {
if (checkIsItemNull(select)) continue;
if (checkIsItemSame(view, select)) {
view.setItemSelected(true);
break;
}
}
}
/**
* 单选操作模式
*/
private void singleSelectMode(T item) {
if (!isShowHighlight) return;
for (BaseTagView<T> view : viewMap.keySet()) {
if (checkIsItemSame((V) view, item)) {
view.setItemSelected(true);
} else {
view.setItemSelected(false);
}
}
}
/**
* 刷新数据
*/
public void notifyDataSetChanged() {
addTags();
}
/**
* 对于相同item的判断条件
*
* @param view
* @param item
* @return
*/
protected abstract boolean checkIsItemSame(V view, T item);
/**
* 检查item是否是空指针
*
* @param item
* @return
*/
protected abstract boolean checkIsItemNull(T item);
/**
* 添加单个标签
*
* @param item
* @return
*/
protected abstract BaseTagView<T> addTag(T item);
/**
* 获取所有item的数量
*/
protected int getCount() {
if (source == null) return 0;
return source.size();
}
/**
* 得到已选项目的列表
*
* @return
*/
@SuppressWarnings("SuspiciousMethodCalls")
public List<T> getSelectedList() {
List<T> selectedList = new ArrayList<>();
for (BaseTagView<T> view : viewMap.keySet()) {
if (view.isItemSelected()) {
T item = viewMap.get(view);
selectedList.add(item);
}
}
return selectedList;
}
}
================================================
FILE: flexbox/src/main/java/zhouyou/flexbox/interfaces/OnFlexboxSubscribeListener.java
================================================
package zhouyou.flexbox.interfaces;
import java.util.List;
/**
* 作者:ZhouYou
* 日期:2017/3/27.
*/
public interface OnFlexboxSubscribeListener<T> {
/**
* @param selectedItem 已选中的标签
*/
void onSubscribe(List<T> selectedItem);
}
================================================
FILE: flexbox/src/main/java/zhouyou/flexbox/interfaces/TagWithListener.java
================================================
package zhouyou.flexbox.interfaces;
/**
* 作者:ZhouYou
* 日期:2017/3/25.
*/
public interface TagWithListener<T> {
void onItemSelect(T item);
}
================================================
FILE: flexbox/src/main/java/zhouyou/flexbox/widget/BaseTagView.java
================================================
package zhouyou.flexbox.widget;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import zhouyou.flexbox.interfaces.TagWithListener;
/**
* 作者:ZhouYou
* 日期:2017/3/25.
*/
public class BaseTagView<T> extends FrameLayout implements View.OnClickListener {
private int itemDefaultDrawable;
private int itemSelectDrawable;
private int itemDefaultTextColor;
private int itemSelectTextColor;
private T item;
public TextView textView;
private TagWithListener<T> listener;
private boolean isItemSelected;
public void setListener(TagWithListener<T> listener) {
this.listener = listener;
}
public BaseTagView(Context context) {
this(context, null);
}
public BaseTagView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BaseTagView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
textView = new TextView(getContext());
textView.setGravity(Gravity.CENTER);
addView(textView);
setOnClickListener(this);
}
/**
* 设置标签
*
* @param item
*/
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
@Override
public void onClick(View v) {
if (listener == null) return;
listener.onItemSelect(item);
}
public void selectItemChangeColorState() {
if (isItemSelected) {
setBackgroundResource(itemDefaultDrawable);
textView.setTextColor(itemDefaultTextColor);
isItemSelected = false;
} else {
setBackgroundResource(itemSelectDrawable);
textView.setTextColor(itemSelectTextColor);
isItemSelected = true;
}
}
public boolean isItemSelected() {
return isItemSelected;
}
public void setItemSelected(boolean itemSelected) {
isItemSelected = itemSelected;
if (itemSelected) {
setBackgroundResource(itemSelectDrawable);
textView.setTextColor(itemSelectTextColor);
} else {
setBackgroundResource(itemDefaultDrawable);
textView.setTextColor(itemDefaultTextColor);
}
}
public void setItemDefaultDrawable(int itemDefaultDrawable) {
this.itemDefaultDrawable = itemDefaultDrawable;
setBackgroundResource(itemDefaultDrawable);
}
public void setItemSelectDrawable(int itemSelectDrawable) {
this.itemSelectDrawable = itemSelectDrawable;
}
public void setItemDefaultTextColor(int itemDefaultTextColor) {
this.itemDefaultTextColor = itemDefaultTextColor;
textView.setTextColor(itemDefaultTextColor);
}
public void setItemSelectTextColor(int itemSelectTextColor) {
this.itemSelectTextColor = itemSelectTextColor;
}
public TextView getTextView() {
return textView;
}
}
================================================
FILE: flexbox/src/main/java/zhouyou/flexbox/widget/TagFlowLayout.java
================================================
package zhouyou.flexbox.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import com.google.android.flexbox.FlexboxLayout;
import zhouyou.flexbox.R;
import zhouyou.flexbox.adapter.TagAdapter;
/**
* 作者:ZhouYou
* 日期:2017/3/28.
*/
public class TagFlowLayout extends FlexboxLayout {
/*是否展示选中效果*/
private boolean isShowHighlight = true;
/*默认和已选的背景*/
private int itemDefaultDrawable;
private int itemSelectDrawable;
/*默认和已选的文字颜色*/
private int itemDefaultTextColor;
private int itemSelectTextColor;
/*操作模式 0 - 多选 | 1 - 单选*/
private int mode = MODE_MULTI_SELECT;
/*可选标签的最大数量*/
private int maxSelection;
public static final int MODE_MULTI_SELECT = 0;
public static final int MODE_SINGLE_SELECT = 1;
public TagFlowLayout(Context context) {
this(context, null);
}
public TagFlowLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TagFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TagFlowLayout);
isShowHighlight = ta.getBoolean(R.styleable.TagFlowLayout_showHighlight, true);
itemDefaultDrawable = ta.getResourceId(R.styleable.TagFlowLayout_defaultDrawable, 0);
itemSelectDrawable = ta.getResourceId(R.styleable.TagFlowLayout_selectDrawable, 0);
itemDefaultTextColor = ta.getColor(R.styleable.TagFlowLayout_defaultTextColor, 0);
itemSelectTextColor = ta.getColor(R.styleable.TagFlowLayout_selectTextColor, 0);
mode = ta.getInt(R.styleable.TagFlowLayout_mode, MODE_MULTI_SELECT);
maxSelection = ta.getInt(R.styleable.TagFlowLayout_maxSelectionCount, 0);
ta.recycle();
}
public void setAdapter(TagAdapter adapter) {
if (adapter == null) {
removeAllViews();
return;
}
adapter.bindView(this);
adapter.addTags();
}
public boolean isShowHighlight() {
return isShowHighlight;
}
public void setShowHighlight(boolean showHighlight) {
isShowHighlight = showHighlight;
}
public int getItemDefaultDrawable() {
return itemDefaultDrawable;
}
public void setItemDefaultDrawable(int itemDefaultDrawable) {
this.itemDefaultDrawable = itemDefaultDrawable;
}
public int getItemSelectDrawable() {
return itemSelectDrawable;
}
public void setItemSelectDrawable(int itemSelectDrawable) {
this.itemSelectDrawable = itemSelectDrawable;
}
public int getItemDefaultTextColor() {
return itemDefaultTextColor;
}
public void setItemDefaultTextColor(int itemDefaultTextColor) {
this.itemDefaultTextColor = itemDefaultTextColor;
}
public int getItemSelectTextColor() {
return itemSelectTextColor;
}
public void setItemSelectTextColor(int itemSelectTextColor) {
this.itemSelectTextColor = itemSelectTextColor;
}
public int getMode() {
return mode;
}
public void setMode(int mode) {
this.mode = mode;
}
public int getMaxSelection() {
return maxSelection;
}
public void setMaxSelection(int maxSelection) {
this.maxSelection = maxSelection;
}
}
================================================
FILE: flexbox/src/main/res/values/attrs.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TagFlowLayout">
<attr name="showHighlight" format="boolean" />
<attr name="defaultDrawable" format="reference" />
<attr name="selectDrawable" format="reference" />
<attr name="defaultTextColor" format="color|reference"/>
<attr name="selectTextColor" format="color|reference" />
<attr name="mode">
<enum name="MULTI" value="0" />
<enum name="SINGLE" value="1"/>
</attr>
<attr name="maxSelectionCount" format="integer"/>
</declare-styleable>
</resources>
================================================
FILE: flexbox/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">FlexboxUtils</string>
</resources>
================================================
FILE: flexbox/src/test/java/zhouyou/flexbox/ExampleUnitTest.java
================================================
package zhouyou.flexbox;
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);
}
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Sat Mar 25 17:41:19 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: settings.gradle
================================================
include ':app', ':flexbox'
gitextract_7e674wrr/ ├── .gitignore ├── .idea/ │ ├── copyright/ │ │ └── profiles_settings.xml │ ├── gradle.xml │ └── runConfigurations.xml ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── zhouyou/ │ │ └── flexbox/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── zhouyou/ │ │ │ └── flexbox/ │ │ │ ├── MainActivity.java │ │ │ ├── StringTagAdapter.java │ │ │ └── StringTagView.java │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── bg_flow_divider.xml │ │ │ ├── bg_flow_selected.xml │ │ │ └── bg_flow_unselect.xml │ │ ├── layout/ │ │ │ └── activity_main.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test/ │ └── java/ │ └── com/ │ └── zhouyou/ │ └── flexbox/ │ └── ExampleUnitTest.java ├── build.gradle ├── flexbox/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── zhouyou/ │ │ └── flexbox/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── zhouyou/ │ │ │ └── flexbox/ │ │ │ ├── adapter/ │ │ │ │ └── TagAdapter.java │ │ │ ├── interfaces/ │ │ │ │ ├── OnFlexboxSubscribeListener.java │ │ │ │ └── TagWithListener.java │ │ │ └── widget/ │ │ │ ├── BaseTagView.java │ │ │ └── TagFlowLayout.java │ │ └── res/ │ │ └── values/ │ │ ├── attrs.xml │ │ └── strings.xml │ └── test/ │ └── java/ │ └── zhouyou/ │ └── flexbox/ │ └── ExampleUnitTest.java ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle
SYMBOL INDEX (83 symbols across 12 files)
FILE: app/src/androidTest/java/com/zhouyou/flexbox/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: app/src/main/java/com/zhouyou/flexbox/MainActivity.java
class MainActivity (line 14) | public class MainActivity extends AppCompatActivity implements View.OnCl...
method onCreate (line 22) | @Override
method initData (line 30) | private void initData() {
method initViews (line 52) | private void initViews() {
method onClick (line 67) | @Override
FILE: app/src/main/java/com/zhouyou/flexbox/StringTagAdapter.java
class StringTagAdapter (line 17) | public class StringTagAdapter extends TagAdapter<StringTagView, String> {
method StringTagAdapter (line 19) | StringTagAdapter(Context context, List<String> data) {
method StringTagAdapter (line 23) | StringTagAdapter(Context context, List<String> data, List<String> sele...
method checkIsItemSame (line 34) | @Override
method checkIsItemNull (line 44) | @Override
method addTag (line 55) | @Override
FILE: app/src/main/java/com/zhouyou/flexbox/StringTagView.java
class StringTagView (line 13) | public class StringTagView extends BaseTagView<String> {
method StringTagView (line 15) | public StringTagView(Context context) {
method StringTagView (line 19) | public StringTagView(Context context, @Nullable AttributeSet attrs) {
method StringTagView (line 23) | public StringTagView(Context context, @Nullable AttributeSet attrs, in...
method setItem (line 27) | @Override
FILE: app/src/test/java/com/zhouyou/flexbox/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
FILE: flexbox/src/androidTest/java/zhouyou/flexbox/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: flexbox/src/main/java/zhouyou/flexbox/adapter/TagAdapter.java
class TagAdapter (line 20) | public abstract class TagAdapter<V extends BaseTagView<T>, T> {
method setOnSubscribeListener (line 54) | public void setOnSubscribeListener(OnFlexboxSubscribeListener<T> onSub...
method setSource (line 58) | public void setSource(List<T> source) {
method setSelectItems (line 62) | public void setSelectItems(List<T> selectItems) {
method getSelectItems (line 66) | public List<T> getSelectItems() {
method TagAdapter (line 70) | public TagAdapter(Context context, List<T> source) {
method TagAdapter (line 76) | public TagAdapter(Context context, List<T> source, List<T> selectItems) {
method getContext (line 83) | public Context getContext() {
method getData (line 87) | public List<T> getData() {
method bindView (line 96) | public void bindView(TagFlowLayout rootView) {
method addTags (line 113) | public void addTags() {
method initSelectedViews (line 150) | private void initSelectedViews(V view) {
method singleSelectMode (line 165) | private void singleSelectMode(T item) {
method notifyDataSetChanged (line 180) | public void notifyDataSetChanged() {
method checkIsItemSame (line 191) | protected abstract boolean checkIsItemSame(V view, T item);
method checkIsItemNull (line 199) | protected abstract boolean checkIsItemNull(T item);
method addTag (line 207) | protected abstract BaseTagView<T> addTag(T item);
method getCount (line 212) | protected int getCount() {
method getSelectedList (line 222) | @SuppressWarnings("SuspiciousMethodCalls")
FILE: flexbox/src/main/java/zhouyou/flexbox/interfaces/OnFlexboxSubscribeListener.java
type OnFlexboxSubscribeListener (line 9) | public interface OnFlexboxSubscribeListener<T> {
method onSubscribe (line 14) | void onSubscribe(List<T> selectedItem);
FILE: flexbox/src/main/java/zhouyou/flexbox/interfaces/TagWithListener.java
type TagWithListener (line 7) | public interface TagWithListener<T> {
method onItemSelect (line 9) | void onItemSelect(T item);
FILE: flexbox/src/main/java/zhouyou/flexbox/widget/BaseTagView.java
class BaseTagView (line 17) | public class BaseTagView<T> extends FrameLayout implements View.OnClickL...
method setListener (line 33) | public void setListener(TagWithListener<T> listener) {
method BaseTagView (line 37) | public BaseTagView(Context context) {
method BaseTagView (line 41) | public BaseTagView(Context context, @Nullable AttributeSet attrs) {
method BaseTagView (line 45) | public BaseTagView(Context context, @Nullable AttributeSet attrs, int ...
method init (line 50) | private void init() {
method setItem (line 62) | public void setItem(T item) {
method getItem (line 66) | public T getItem() {
method onClick (line 70) | @Override
method selectItemChangeColorState (line 76) | public void selectItemChangeColorState() {
method isItemSelected (line 88) | public boolean isItemSelected() {
method setItemSelected (line 92) | public void setItemSelected(boolean itemSelected) {
method setItemDefaultDrawable (line 103) | public void setItemDefaultDrawable(int itemDefaultDrawable) {
method setItemSelectDrawable (line 108) | public void setItemSelectDrawable(int itemSelectDrawable) {
method setItemDefaultTextColor (line 112) | public void setItemDefaultTextColor(int itemDefaultTextColor) {
method setItemSelectTextColor (line 117) | public void setItemSelectTextColor(int itemSelectTextColor) {
method getTextView (line 121) | public TextView getTextView() {
FILE: flexbox/src/main/java/zhouyou/flexbox/widget/TagFlowLayout.java
class TagFlowLayout (line 16) | public class TagFlowLayout extends FlexboxLayout {
method TagFlowLayout (line 33) | public TagFlowLayout(Context context) {
method TagFlowLayout (line 37) | public TagFlowLayout(Context context, AttributeSet attrs) {
method TagFlowLayout (line 41) | public TagFlowLayout(Context context, AttributeSet attrs, int defStyle...
method setAdapter (line 54) | public void setAdapter(TagAdapter adapter) {
method isShowHighlight (line 63) | public boolean isShowHighlight() {
method setShowHighlight (line 67) | public void setShowHighlight(boolean showHighlight) {
method getItemDefaultDrawable (line 71) | public int getItemDefaultDrawable() {
method setItemDefaultDrawable (line 75) | public void setItemDefaultDrawable(int itemDefaultDrawable) {
method getItemSelectDrawable (line 79) | public int getItemSelectDrawable() {
method setItemSelectDrawable (line 83) | public void setItemSelectDrawable(int itemSelectDrawable) {
method getItemDefaultTextColor (line 87) | public int getItemDefaultTextColor() {
method setItemDefaultTextColor (line 91) | public void setItemDefaultTextColor(int itemDefaultTextColor) {
method getItemSelectTextColor (line 95) | public int getItemSelectTextColor() {
method setItemSelectTextColor (line 99) | public void setItemSelectTextColor(int itemSelectTextColor) {
method getMode (line 103) | public int getMode() {
method setMode (line 107) | public void setMode(int mode) {
method getMaxSelection (line 111) | public int getMaxSelection() {
method setMaxSelection (line 115) | public void setMaxSelection(int maxSelection) {
FILE: flexbox/src/test/java/zhouyou/flexbox/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
Condensed preview — 41 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (51K chars).
[
{
"path": ".gitignore",
"chars": 313,
"preview": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.idea/misc.xml\n.idea/encodings.xml\n.idea/modules.x"
},
{
"path": ".idea/copyright/profiles_settings.xml",
"chars": 74,
"preview": "<component name=\"CopyrightManager\">\n <settings default=\"\" />\n</component>"
},
{
"path": ".idea/gradle.xml",
"chars": 679,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"GradleSettings\">\n <option name=\"linke"
},
{
"path": ".idea/runConfigurations.xml",
"chars": 564,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"RunConfigurationProducerService\">\n <o"
},
{
"path": "README.md",
"chars": 4873,
"preview": "# FlexboxUtils\nGoogle在之前发布了一个叫做FlexboxLayout的控件,完全能够适配平时我们业务中自定义的布局流控件,而且有过之而无不及。因此在这个基础上我又针对这个控件进行了进一步的封装,基本能够满足平时大部分的业"
},
{
"path": "app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "app/build.gradle",
"chars": 981,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion 25\n buildToolsVersion \"25.0.2\"\n defaultCo"
},
{
"path": "app/proguard-rules.pro",
"chars": 944,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in C:"
},
{
"path": "app/src/androidTest/java/com/zhouyou/flexbox/ExampleInstrumentedTest.java",
"chars": 742,
"preview": "package com.zhouyou.flexbox;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimpor"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 716,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "app/src/main/java/com/zhouyou/flexbox/MainActivity.java",
"chars": 2678,
"preview": "package com.zhouyou.flexbox;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android."
},
{
"path": "app/src/main/java/com/zhouyou/flexbox/StringTagAdapter.java",
"chars": 1736,
"preview": "package com.zhouyou.flexbox;\n\nimport android.content.Context;\nimport android.text.TextUtils;\nimport android.util.TypedVa"
},
{
"path": "app/src/main/java/com/zhouyou/flexbox/StringTagView.java",
"chars": 743,
"preview": "package com.zhouyou.flexbox;\n\nimport android.content.Context;\nimport android.support.annotation.Nullable;\nimport android"
},
{
"path": "app/src/main/res/drawable/bg_flow_divider.xml",
"chars": 247,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <solid an"
},
{
"path": "app/src/main/res/drawable/bg_flow_selected.xml",
"chars": 200,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <solid and"
},
{
"path": "app/src/main/res/drawable/bg_flow_unselect.xml",
"chars": 299,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <stroke\n "
},
{
"path": "app/src/main/res/layout/activity_main.xml",
"chars": 1435,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "app/src/main/res/values/colors.xml",
"chars": 253,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#3F51B5</color>\n <color name=\"color"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 74,
"preview": "<resources>\n <string name=\"app_name\">FlexboxDemo</string>\n</resources>\n"
},
{
"path": "app/src/main/res/values/styles.xml",
"chars": 383,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
},
{
"path": "app/src/test/java/com/zhouyou/flexbox/ExampleUnitTest.java",
"chars": 397,
"preview": "package com.zhouyou.flexbox;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test,"
},
{
"path": "build.gradle",
"chars": 498,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n r"
},
{
"path": "flexbox/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "flexbox/build.gradle",
"chars": 869,
"preview": "apply plugin: 'com.android.library'\n\nandroid {\n compileSdkVersion 25\n buildToolsVersion \"25.0.2\"\n\n defaultConfi"
},
{
"path": "flexbox/proguard-rules.pro",
"chars": 944,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in C:"
},
{
"path": "flexbox/src/androidTest/java/zhouyou/flexbox/ExampleInstrumentedTest.java",
"chars": 739,
"preview": "package zhouyou.flexbox;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport an"
},
{
"path": "flexbox/src/main/AndroidManifest.xml",
"chars": 248,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\n package=\"zhouyou.flexbox\">\n\n <application a"
},
{
"path": "flexbox/src/main/java/zhouyou/flexbox/adapter/TagAdapter.java",
"chars": 6137,
"preview": "package zhouyou.flexbox.adapter;\n\nimport android.content.Context;\nimport android.support.v4.util.ArrayMap;\nimport androi"
},
{
"path": "flexbox/src/main/java/zhouyou/flexbox/interfaces/OnFlexboxSubscribeListener.java",
"chars": 246,
"preview": "package zhouyou.flexbox.interfaces;\n\nimport java.util.List;\n\n/**\n * 作者:ZhouYou\n * 日期:2017/3/27.\n */\npublic interface OnF"
},
{
"path": "flexbox/src/main/java/zhouyou/flexbox/interfaces/TagWithListener.java",
"chars": 148,
"preview": "package zhouyou.flexbox.interfaces;\n\n/**\n * 作者:ZhouYou\n * 日期:2017/3/25.\n */\npublic interface TagWithListener<T> {\n\n v"
},
{
"path": "flexbox/src/main/java/zhouyou/flexbox/widget/BaseTagView.java",
"chars": 3212,
"preview": "package zhouyou.flexbox.widget;\n\nimport android.content.Context;\nimport android.support.annotation.Nullable;\nimport andr"
},
{
"path": "flexbox/src/main/java/zhouyou/flexbox/widget/TagFlowLayout.java",
"chars": 3404,
"preview": "package zhouyou.flexbox.widget;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.u"
},
{
"path": "flexbox/src/main/res/values/attrs.xml",
"chars": 624,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <declare-styleable name=\"TagFlowLayout\">\n <attr name=\"show"
},
{
"path": "flexbox/src/main/res/values/strings.xml",
"chars": 75,
"preview": "<resources>\n <string name=\"app_name\">FlexboxUtils</string>\n</resources>\n"
},
{
"path": "flexbox/src/test/java/zhouyou/flexbox/ExampleUnitTest.java",
"chars": 393,
"preview": "package zhouyou.flexbox;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, whi"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 233,
"preview": "#Sat Mar 25 17:41:19 CST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gradle.properties",
"chars": 730,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "gradlew",
"chars": 4971,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "gradlew.bat",
"chars": 2314,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
},
{
"path": "settings.gradle",
"chars": 27,
"preview": "include ':app', ':flexbox'\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the Kaka252/FlexboxUtils GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 41 files (43.1 KB), approximately 12.5k tokens, and a symbol index with 83 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.