├── .gitignore ├── README.md ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── example │ └── sky │ └── checkboxdemo │ └── ExampleInstrumentedTest.java ├── main ├── AndroidManifest.xml ├── java │ ├── bean │ │ ├── LevelOne.java │ │ ├── LevelThree.java │ │ ├── LevelThreeBean.java │ │ └── LevelTwo.java │ └── com │ │ └── example │ │ └── sky │ │ └── checkboxdemo │ │ ├── MainActivity.java │ │ └── MyAdapter.java └── res │ ├── layout │ ├── activity_main.xml │ ├── level_one.xml │ ├── level_three.xml │ └── level_two.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── test └── java └── com └── example └── sky └── checkboxdemo └── ExampleUnitTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About_BRVAH 2 | 使用 BRVAH 实现三级伸缩,并解决多选框的复用。 3 | 4 | 另外大家如果有快速开发框架的话可查看本人另一个项目: https://github.com/Sky0202/AppModel 5 | 此框架封装了最新的 retrofit、 最简单的屏幕适配库、自行封装了Log类,简洁明了。 欢迎 star 并使用 6 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.example.sky.checkboxdemo" 8 | minSdkVersion 16 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | compile 'com.android.support:appcompat-v7:25.3.0' 25 | testCompile 'junit:junit:4.12' 26 | compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.2' 27 | compile 'com.android.support:design:25.3.0' 28 | } 29 | -------------------------------------------------------------------------------- /proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\SDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /src/androidTest/java/com/example/sky/checkboxdemo/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.sky.checkboxdemo; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.example.sky.checkboxdemo", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/java/bean/LevelOne.java: -------------------------------------------------------------------------------- 1 | package bean; 2 | 3 | import com.chad.library.adapter.base.entity.AbstractExpandableItem; 4 | import com.chad.library.adapter.base.entity.MultiItemEntity; 5 | import com.example.sky.checkboxdemo.MyAdapter; 6 | 7 | /** 8 | * Created by SKY on 2017-4-22. 9 | */ 10 | 11 | public class LevelOne extends AbstractExpandableItem implements MultiItemEntity{ 12 | 13 | public String title; 14 | 15 | public LevelOne(String title) { 16 | this.title = title; 17 | } 18 | 19 | @Override 20 | public int getItemType() { 21 | return 0; 22 | } 23 | 24 | @Override 25 | public int getLevel() { 26 | return MyAdapter.LEVEL_ONE; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/bean/LevelThree.java: -------------------------------------------------------------------------------- 1 | package bean; 2 | 3 | import com.chad.library.adapter.base.entity.MultiItemEntity; 4 | 5 | /** 6 | * Created by SKY on 2017-4-22. 7 | */ 8 | 9 | public class LevelThree implements MultiItemEntity{ 10 | 11 | private String title; 12 | private String desc; 13 | public Boolean isChecked = false; 14 | 15 | public LevelThree(String title, String desc) { 16 | this.title = title; 17 | this.desc = desc; 18 | } 19 | 20 | public String getTitle() { 21 | return title; 22 | } 23 | 24 | public void setTitle(String title) { 25 | this.title = title; 26 | } 27 | 28 | public String getDesc() { 29 | return desc; 30 | } 31 | 32 | public void setDesc(String desc) { 33 | this.desc = desc; 34 | } 35 | 36 | @Override 37 | public int getItemType() { 38 | return 2; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/bean/LevelThreeBean.java: -------------------------------------------------------------------------------- 1 | package bean; 2 | 3 | /** 4 | * Created by SKY on 2017-4-22. 5 | */ 6 | 7 | public class LevelThreeBean { 8 | 9 | private String title; 10 | private String desc; 11 | public Boolean isChecked = false; 12 | 13 | public LevelThreeBean(String title, String desc) { 14 | this.title = title; 15 | this.desc = desc; 16 | } 17 | 18 | public String getTitle() { 19 | return title; 20 | } 21 | 22 | public void setTitle(String title) { 23 | this.title = title; 24 | } 25 | 26 | public String getDesc() { 27 | return desc; 28 | } 29 | 30 | public void setDesc(String desc) { 31 | this.desc = desc; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/bean/LevelTwo.java: -------------------------------------------------------------------------------- 1 | package bean; 2 | 3 | import com.chad.library.adapter.base.entity.AbstractExpandableItem; 4 | import com.chad.library.adapter.base.entity.MultiItemEntity; 5 | import com.example.sky.checkboxdemo.MyAdapter; 6 | 7 | /** 8 | * Created by SKY on 2017-4-22. 9 | */ 10 | 11 | public class LevelTwo extends AbstractExpandableItem implements MultiItemEntity{ 12 | 13 | public String title; 14 | 15 | public LevelTwo(String title) { 16 | this.title = title; 17 | } 18 | 19 | @Override 20 | public int getItemType() { 21 | return 1; 22 | } 23 | 24 | @Override 25 | public int getLevel() { 26 | return MyAdapter.LEVEL_TWO; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/example/sky/checkboxdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.sky.checkboxdemo; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | 9 | import com.chad.library.adapter.base.entity.MultiItemEntity; 10 | 11 | import java.util.ArrayList; 12 | 13 | import bean.LevelOne; 14 | import bean.LevelThree; 15 | import bean.LevelTwo; 16 | 17 | public class MainActivity extends AppCompatActivity { 18 | 19 | private Context mContext; 20 | private RecyclerView rvMain; 21 | private ArrayList multiList = new ArrayList<>(); 22 | private MyAdapter adapter; 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.activity_main); 28 | mContext = this; 29 | 30 | initView(); 31 | initData(); 32 | 33 | } 34 | 35 | private void initView() { 36 | 37 | rvMain = (RecyclerView) findViewById(R.id.rv_main); 38 | 39 | } 40 | 41 | private void initData() { 42 | 43 | multiList = generateData(); 44 | 45 | LinearLayoutManager manager = new LinearLayoutManager(this); 46 | adapter = new MyAdapter(this, multiList); 47 | rvMain.setLayoutManager(manager); 48 | rvMain.setAdapter(adapter); 49 | 50 | // 使一级列表默认展开 51 | for (int i = multiList.size() - 1; i >= 0; i--) { 52 | adapter.expand(i, false, false); 53 | } 54 | 55 | } 56 | 57 | 58 | private ArrayList generateData() { 59 | 60 | int levelOne = 10; 61 | int levelTwo = 3; 62 | 63 | ArrayList res = new ArrayList<>(); 64 | 65 | for (int i = 0; i < levelOne; i++) { 66 | 67 | LevelOne lv1 = new LevelOne("一级列表" + i); 68 | 69 | for (int j = 0; j < levelTwo; j++) { 70 | 71 | LevelTwo lv2 = new LevelTwo("二级列表:" + j); 72 | 73 | lv2.addSubItem(new LevelThree("三级列表" + j, "德玛西亚:" + j 74 | )); 75 | 76 | lv1.addSubItem(lv2); 77 | } 78 | res.add(lv1); 79 | } 80 | return res; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/example/sky/checkboxdemo/MyAdapter.java: -------------------------------------------------------------------------------- 1 | package com.example.sky.checkboxdemo; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | import android.view.View; 6 | 7 | import com.chad.library.adapter.base.BaseMultiItemQuickAdapter; 8 | import com.chad.library.adapter.base.BaseViewHolder; 9 | import com.chad.library.adapter.base.entity.MultiItemEntity; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import bean.LevelOne; 15 | import bean.LevelThree; 16 | import bean.LevelThreeBean; 17 | import bean.LevelTwo; 18 | 19 | public class MyAdapter extends BaseMultiItemQuickAdapter { 20 | 21 | private Context mContext; 22 | public static final int LEVEL_ONE = 0; 23 | public static final int LEVEL_TWO = 1; 24 | public static final int LEVEL_THREE = 2; 25 | 26 | public MyAdapter(Context context, List data) { 27 | super(data); 28 | this.mContext = context; 29 | addItemType(LEVEL_ONE, R.layout.level_one); 30 | addItemType(LEVEL_TWO, R.layout.level_two); 31 | addItemType(LEVEL_THREE, R.layout.level_three); 32 | } 33 | 34 | @Override 35 | protected void convert(final BaseViewHolder helper, MultiItemEntity item) { 36 | 37 | switch (item.getItemType()){ 38 | 39 | case LEVEL_ONE: 40 | 41 | LevelOne one = (LevelOne) item; 42 | helper.setText(R.id.tv_level_one, one.title); 43 | 44 | break; 45 | 46 | case LEVEL_TWO: 47 | 48 | final LevelTwo levelTwo = (LevelTwo) item; 49 | helper.setText(R.id.tv_level_two, levelTwo.title); 50 | 51 | helper.getView(R.id.ll_level_two).setOnClickListener(new View.OnClickListener() { 52 | @Override 53 | public void onClick(View v) { 54 | int pos = helper.getAdapterPosition(); 55 | if (levelTwo.isExpanded()) { 56 | collapse(pos, true); 57 | } else { 58 | expand(pos, true); 59 | } 60 | } 61 | }); 62 | 63 | break; 64 | 65 | case LEVEL_THREE: 66 | 67 | final LevelThree three = (LevelThree) item; 68 | helper.setText(R.id.tv_level_three, three.getTitle()); 69 | helper.setText(R.id.tv_level_three_desc, three.getDesc()); 70 | 71 | // 判断 记住的状态 72 | if (three.isChecked){ 73 | helper.setChecked(R.id.cb_three, true); 74 | } else { 75 | helper.setChecked(R.id.cb_three, false); 76 | } 77 | 78 | // 设置复选框的点击事件 79 | helper.getView(R.id.cb_three).setOnClickListener(new View.OnClickListener() { 80 | @Override 81 | public void onClick(View v) { 82 | 83 | three.isChecked = !three.isChecked; 84 | if (three.isChecked){ 85 | // list.add(bean); 86 | Log.e("isChecked","开启了"); 87 | } else { 88 | // list.remove(bean); 89 | Log.e("isChecked","取消了"); 90 | } 91 | 92 | // 使用此句可能会造成item 无法伸缩,并有可能造成出现多个 item 93 | // getData().set(helper.getLayoutPosition(), (MultiItemEntity) three); 94 | 95 | } 96 | }); 97 | 98 | break; 99 | 100 | } 101 | 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/res/layout/level_one.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 21 | 22 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/res/layout/level_three.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 22 | 23 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/main/res/layout/level_two.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sky0202/About_BRVAH/6098e4d7f186848594a7db5d4c5d4e60664c2d33/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sky0202/About_BRVAH/6098e4d7f186848594a7db5d4c5d4e60664c2d33/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sky0202/About_BRVAH/6098e4d7f186848594a7db5d4c5d4e60664c2d33/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sky0202/About_BRVAH/6098e4d7f186848594a7db5d4c5d4e60664c2d33/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sky0202/About_BRVAH/6098e4d7f186848594a7db5d4c5d4e60664c2d33/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | CheckBoxDemo 3 | 4 | -------------------------------------------------------------------------------- /src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/test/java/com/example/sky/checkboxdemo/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.example.sky.checkboxdemo; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } --------------------------------------------------------------------------------