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 ================================================ ================================================ FILE: .idea/gradle.xml ================================================ ================================================ FILE: .idea/runConfigurations.xml ================================================ ================================================ FILE: README.md ================================================ # FlexboxUtils Google在之前发布了一个叫做FlexboxLayout的控件,完全能够适配平时我们业务中自定义的布局流控件,而且有过之而无不及。因此在这个基础上我又针对这个控件进行了进一步的封装,基本能够满足平时大部分的业务需求,先上图 ![preview](https://github.com/Kaka252/FlexboxUtils/blob/master/screenshot/device-2017-03-28-181547.png?raw=true) # 继承BaseTagView 定义一个TagView,继承BaseTagView,由于每一个tag的数据类型不确定,因此需要传入一个固定的数据类型满足实际需求 ``` public class StringTagView extends BaseTagView { 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 { StringTagAdapter(Context context, List data) { this(context, data, null); } StringTagAdapter(Context context, List data, List 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中,你可以使用如下配置: ``` // 是否选中高亮 // 默认标签背景 // 选中标签背景 // 默认标签文字颜色 // 选中标签文字颜色 // 单选或者多选 // 默认多选 // 单选 ``` ``` ``` 也可以使用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() { @Override public void onSubscribe(List 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 Testing documentation */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() throws Exception { // Context of the app under test. Context appContext = InstrumentationRegistry.getTargetContext(); assertEquals("com.zhouyou.flexbox", appContext.getPackageName()); } } ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ 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 sourceData; private List 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() { @Override public void onSubscribe(List 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 data = new ArrayList<>(); data.add("客户代表"); data.add("Java工程师"); List 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 { StringTagAdapter(Context context, List data) { this(context, data, null); } StringTagAdapter(Context context, List data, List 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 { 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 ================================================ ================================================ FILE: app/src/main/res/drawable/bg_flow_selected.xml ================================================ ================================================ FILE: app/src/main/res/drawable/bg_flow_unselect.xml ================================================ ================================================ FILE: app/src/main/res/layout/activity_main.xml ================================================