├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── hicoo │ │ └── areapickerview │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── region.json │ ├── java │ │ └── com │ │ │ └── hicoo │ │ │ └── areapickerview │ │ │ ├── AddressBean.java │ │ │ ├── AreaAdapter.java │ │ │ ├── AreaPickerView.java │ │ │ ├── CityAdapter.java │ │ │ ├── MainActivity.java │ │ │ └── ProvinceAdapter.java │ └── res │ │ ├── anim │ │ ├── push_bottom_in.xml │ │ └── push_bottom_out.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── dialog_area_pickerview.xml │ │ ├── item_address.xml │ │ └── layout_recyclerview.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── close.png │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── close.png │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── close.png │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── close.png │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── close.png │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── values-1024x600 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1024x768 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1184x720 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1196x720 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1280x720 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1280x800 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1334x750 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1776x1080 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1800x1080 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1812x1080 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-1920x1080 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-2560x1440 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-480x320 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-800x480 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-854x480 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ ├── values-960x540 │ │ ├── lay_x.xml │ │ └── lay_y.xml │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── hicoo │ └── areapickerview │ └── ExampleUnitTest.java ├── build.gradle ├── gif └── untitled.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /build/ 3 | .classpath 4 | .project 5 | .classpath 6 | .settings 7 | *.iml 8 | /.gradle 9 | *.ipr 10 | *.iws 11 | .idea/ 12 | .geany 13 | /target 14 | */target 15 | target/ 16 | /reports 17 | */reports 18 | .DS_Store 19 | */tmp 20 | *.war 21 | .gradle/ 22 | /app/release/ 23 | app/*.apk -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 效果图 2 | ![Alt text](https://github.com/androidxiaosongzi/address_pickerview/blob/master/gif/untitled.gif) 3 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "com.hicoo.areapickerview" 7 | minSdkVersion 19 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(dir: 'libs', include: ['*.jar']) 23 | implementation 'com.android.support:appcompat-v7:28.0.0' 24 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 25 | testImplementation 'junit:junit:4.12' 26 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 28 | 29 | //design 30 | implementation 'com.android.support:design:28.0.0' 31 | //recycler-----HELPER 32 | implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30' 33 | //gson 34 | implementation 'com.google.code.gson:gson:2.8.5' 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/hicoo/areapickerview/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.hicoo.areapickerview; 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 | * Instrumented 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() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.hicoo.areapickerview", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/hicoo/areapickerview/AddressBean.java: -------------------------------------------------------------------------------- 1 | package com.hicoo.areapickerview; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by ZhouZi on 2018/9/29. 7 | * time:11:24 8 | * ----------Dragon be here!----------/ 9 | *    ┏┓   ┏┓ 10 | *   ┏┛┻━━━┛┻┓━━━ 11 | *   ┃      ┃ 12 | *   ┃   ━  ┃ 13 | *   ┃ ┳┛ ┗┳ 14 | *   ┃      ┃ 15 | *   ┃   ┻  ┃ 16 | *   ┃     ┃ 17 | *   ┗━┓   ┏━┛Code is far away from bug with the animal protecting 18 | *     ┃   ┃ 神兽保佑,代码无bug 19 | *     ┃   ┃ 20 | *     ┃   ┗━━━┓ 21 | *     ┃      ┣┓ 22 | *     ┃       ┏┛ 23 | *     ┗┓┓┏━┳┓┏┛━━━━━ 24 | *      ┃┫┫ ┃┫┫ 25 | *      ┗┻┛ ┗┻┛ 26 | * ━━━━━━━━━━━神兽出没━━━━━━━━━━━━━━ 27 | */ 28 | public class AddressBean { 29 | 30 | private String label; 31 | private String value; 32 | private boolean status; 33 | private List children; 34 | 35 | public String getLabel() { 36 | return label; 37 | } 38 | 39 | public void setLabel(String label) { 40 | this.label = label; 41 | } 42 | 43 | public String getValue() { 44 | return value; 45 | } 46 | 47 | public void setValue(String value) { 48 | this.value = value; 49 | } 50 | 51 | public boolean isStatus() { 52 | return status; 53 | } 54 | 55 | public void setStatus(boolean status) { 56 | this.status = status; 57 | } 58 | 59 | public List getChildren() { 60 | return children; 61 | } 62 | 63 | public void setChildren(List children) { 64 | this.children = children; 65 | } 66 | 67 | public class CityBean { 68 | private String label; 69 | private String value; 70 | private boolean status; 71 | private List children; 72 | 73 | public String getLabel() { 74 | return label; 75 | } 76 | 77 | public void setLabel(String label) { 78 | this.label = label; 79 | } 80 | 81 | public String getValue() { 82 | return value; 83 | } 84 | 85 | public void setValue(String value) { 86 | this.value = value; 87 | } 88 | 89 | public boolean isStatus() { 90 | return status; 91 | } 92 | 93 | public void setStatus(boolean status) { 94 | this.status = status; 95 | } 96 | 97 | public List getChildren() { 98 | return children; 99 | } 100 | 101 | public void setChildren(List children) { 102 | this.children = children; 103 | } 104 | 105 | public class AreaBean { 106 | private String label; 107 | private String value; 108 | private boolean status; 109 | 110 | public String getLabel() { 111 | return label; 112 | } 113 | 114 | public void setLabel(String label) { 115 | this.label = label; 116 | } 117 | 118 | public String getValue() { 119 | return value; 120 | } 121 | 122 | public void setValue(String value) { 123 | this.value = value; 124 | } 125 | 126 | public boolean isStatus() { 127 | return status; 128 | } 129 | 130 | public void setStatus(boolean status) { 131 | this.status = status; 132 | } 133 | } 134 | 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /app/src/main/java/com/hicoo/areapickerview/AreaAdapter.java: -------------------------------------------------------------------------------- 1 | package com.hicoo.areapickerview; 2 | 3 | import android.graphics.Color; 4 | import android.support.annotation.Nullable; 5 | 6 | import com.chad.library.adapter.base.BaseQuickAdapter; 7 | import com.chad.library.adapter.base.BaseViewHolder; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by ZhouZi on 2018/9/29. 13 | * time:10:35 14 | * ----------Dragon be here!----------/ 15 | *    ┏┓   ┏┓ 16 | *   ┏┛┻━━━┛┻┓━━━ 17 | *   ┃      ┃ 18 | *   ┃   ━  ┃ 19 | *   ┃ ┳┛ ┗┳ 20 | *   ┃      ┃ 21 | *   ┃   ┻  ┃ 22 | *   ┃     ┃ 23 | *   ┗━┓   ┏━┛Code is far away from bug with the animal protecting 24 | *     ┃   ┃ 神兽保佑,代码无bug 25 | *     ┃   ┃ 26 | *     ┃   ┗━━━┓ 27 | *     ┃      ┣┓ 28 | *     ┃       ┏┛ 29 | *     ┗┓┓┏━┳┓┏┛━━━━━ 30 | *      ┃┫┫ ┃┫┫ 31 | *      ┗┻┛ ┗┻┛ 32 | * ━━━━━━━━━━━神兽出没━━━━━━━━━━━━━━ 33 | */ 34 | public class AreaAdapter extends BaseQuickAdapter { 35 | public AreaAdapter(int layoutResId, @Nullable List data) { 36 | super(layoutResId, data); 37 | } 38 | 39 | @Override 40 | protected void convert(BaseViewHolder helper, AddressBean.CityBean.AreaBean item) { 41 | helper.setText(R.id.textview, item.getLabel()); 42 | helper.setTextColor(R.id.textview, item.isStatus() ? Color.parseColor("#65C15C") : Color.parseColor("#444444")); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/hicoo/areapickerview/AreaPickerView.java: -------------------------------------------------------------------------------- 1 | package com.hicoo.areapickerview; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.annotation.Nullable; 8 | import android.support.design.widget.TabLayout; 9 | import android.support.v4.view.PagerAdapter; 10 | import android.support.v4.view.ViewPager; 11 | import android.support.v7.widget.LinearLayoutManager; 12 | import android.support.v7.widget.RecyclerView; 13 | import android.util.Log; 14 | import android.view.Gravity; 15 | import android.view.LayoutInflater; 16 | import android.view.View; 17 | import android.view.ViewGroup; 18 | import android.view.Window; 19 | import android.view.WindowManager; 20 | import android.widget.ImageView; 21 | 22 | import com.chad.library.adapter.base.BaseQuickAdapter; 23 | 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | 27 | /** 28 | * Created by ZhouZi on 2018/9/29. 29 | * time:9:45 30 | * ----------Dragon be here!----------/ 31 | *    ┏┓   ┏┓ 32 | *   ┏┛┻━━━┛┻┓━━━ 33 | *   ┃      ┃ 34 | *   ┃   ━  ┃ 35 | *   ┃ ┳┛ ┗┳ 36 | *   ┃      ┃ 37 | *   ┃   ┻  ┃ 38 | *   ┃     ┃ 39 | *   ┗━┓   ┏━┛Code is far away from bug with the animal protecting 40 | *     ┃   ┃ 神兽保佑,代码无bug 41 | *     ┃   ┃ 42 | *     ┃   ┗━━━┓ 43 | *     ┃      ┣┓ 44 | *     ┃       ┏┛ 45 | *     ┗┓┓┏━┳┓┏┛━━━━━ 46 | *      ┃┫┫ ┃┫┫ 47 | *      ┗┻┛ ┗┻┛ 48 | * ━━━━━━━━━━━神兽出没━━━━━━━━━━━━━━ 49 | */ 50 | public class AreaPickerView extends Dialog { 51 | 52 | private TabLayout tabLayout; 53 | private ViewPager viewPager; 54 | private ImageView ivBtn; 55 | 56 | private AreaPickerViewCallback areaPickerViewCallback; 57 | /** 58 | * View的集合 59 | */ 60 | private List views; 61 | /** 62 | * tab的集合 63 | */ 64 | private List strings; 65 | /** 66 | * 省 67 | */ 68 | private List addressBeans; 69 | /** 70 | * 市 71 | */ 72 | private List cityBeans; 73 | /** 74 | * 区 75 | */ 76 | private List areaBeans; 77 | 78 | private Context context; 79 | 80 | private ViewPagerAdapter viewPagerAdapter; 81 | private ProvinceAdapter provinceAdapter; 82 | private CityAdapter cityAdapter; 83 | private AreaAdapter areaAdapter; 84 | 85 | /** 86 | * 选中的区域下标 默认-1 87 | */ 88 | private int provinceSelected = -1; 89 | private int citySelected = -1; 90 | private int areaSelected = -1; 91 | 92 | /** 93 | * 历史选中的区域下标 默认-1 94 | */ 95 | private int oldProvinceSelected = -1; 96 | private int oldCitySelected = -1; 97 | private int oldAreaSelected = -1; 98 | 99 | private RecyclerView areaRecyclerView; 100 | private RecyclerView cityRecyclerView; 101 | 102 | private boolean isCreate; 103 | 104 | public AreaPickerView(@NonNull Context context, int themeResId, List addressBeans) { 105 | super(context, themeResId); 106 | this.addressBeans = addressBeans; 107 | this.context = context; 108 | } 109 | 110 | @Override 111 | protected void onCreate(Bundle savedInstanceState) { 112 | super.onCreate(savedInstanceState); 113 | setContentView(R.layout.dialog_area_pickerview); 114 | Window window = this.getWindow(); 115 | 116 | isCreate = true; 117 | 118 | /** 119 | * 位于底部 120 | */ 121 | window.setGravity(Gravity.BOTTOM); 122 | WindowManager.LayoutParams params = window.getAttributes(); 123 | params.width = WindowManager.LayoutParams.MATCH_PARENT; 124 | window.setAttributes(params); 125 | /** 126 | * 设置弹出动画 127 | */ 128 | window.setWindowAnimations(R.style.PickerAnim); 129 | 130 | tabLayout = findViewById(R.id.tablayout); 131 | viewPager = findViewById(R.id.viewpager); 132 | ivBtn = findViewById(R.id.iv_btn); 133 | ivBtn.setOnClickListener(new View.OnClickListener() { 134 | @Override 135 | public void onClick(View view) { 136 | dismiss(); 137 | } 138 | }); 139 | 140 | View provinceView = LayoutInflater.from(context) 141 | .inflate(R.layout.layout_recyclerview, null, false); 142 | View cityView = LayoutInflater.from(context) 143 | .inflate(R.layout.layout_recyclerview, null, false); 144 | View areaView = LayoutInflater.from(context) 145 | .inflate(R.layout.layout_recyclerview, null, false); 146 | 147 | final RecyclerView provinceRecyclerView = provinceView.findViewById(R.id.recyclerview); 148 | cityRecyclerView = cityView.findViewById(R.id.recyclerview); 149 | areaRecyclerView = areaView.findViewById(R.id.recyclerview); 150 | 151 | views = new ArrayList<>(); 152 | views.add(provinceView); 153 | views.add(cityView); 154 | views.add(areaView); 155 | 156 | /** 157 | * 配置adapter 158 | */ 159 | viewPagerAdapter = new ViewPagerAdapter(); 160 | viewPager.setAdapter(viewPagerAdapter); 161 | tabLayout.setupWithViewPager(viewPager); 162 | /** 163 | * 这句话设置了过后,假如又3个tab 删除第三个 刷新过后 第二个划第三个会有弹性 164 | * viewPager.setOffscreenPageLimit(2); 165 | */ 166 | 167 | provinceAdapter = new ProvinceAdapter(R.layout.item_address, addressBeans); 168 | provinceRecyclerView.setAdapter(provinceAdapter); 169 | LinearLayoutManager provinceManager = new LinearLayoutManager(context); 170 | provinceRecyclerView.setLayoutManager(provinceManager); 171 | provinceAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { 172 | @Override 173 | public void onItemClick(BaseQuickAdapter adapter, View view, int position) { 174 | Log.e("AreaPickerView", oldProvinceSelected + "~~~" + oldCitySelected + "~~~" + oldAreaSelected); 175 | cityBeans.clear(); 176 | areaBeans.clear(); 177 | addressBeans.get(position).setStatus(true); 178 | provinceSelected = position; 179 | if (oldProvinceSelected != -1 && oldProvinceSelected != provinceSelected) { 180 | addressBeans.get(oldProvinceSelected).setStatus(false); 181 | Log.e("AreaPickerView", "清空"); 182 | } 183 | if (position != oldProvinceSelected) { 184 | if (oldCitySelected != -1) { 185 | addressBeans.get(oldProvinceSelected).getChildren().get(oldCitySelected).setStatus(false); 186 | } 187 | if (oldAreaSelected != -1) { 188 | addressBeans.get(oldProvinceSelected).getChildren().get(oldCitySelected).getChildren().get(oldAreaSelected).setStatus(false); 189 | } 190 | oldCitySelected = -1; 191 | oldAreaSelected = -1; 192 | } 193 | cityBeans.addAll(addressBeans.get(position).getChildren()); 194 | provinceAdapter.notifyDataSetChanged(); 195 | cityAdapter.notifyDataSetChanged(); 196 | areaAdapter.notifyDataSetChanged(); 197 | strings.set(0, addressBeans.get(position).getLabel()); 198 | if (strings.size() == 1) { 199 | strings.add("请选择"); 200 | } else if (strings.size() > 1) { 201 | if (position != oldProvinceSelected) { 202 | strings.set(1, "请选择"); 203 | if (strings.size() == 3) { 204 | strings.remove(2); 205 | } 206 | } 207 | } 208 | tabLayout.setupWithViewPager(viewPager); 209 | viewPagerAdapter.notifyDataSetChanged(); 210 | tabLayout.getTabAt(1).select(); 211 | oldProvinceSelected = provinceSelected; 212 | } 213 | }); 214 | 215 | cityBeans = new ArrayList<>(); 216 | cityAdapter = new CityAdapter(R.layout.item_address, cityBeans); 217 | LinearLayoutManager cityListManager = new LinearLayoutManager(context); 218 | cityRecyclerView.setLayoutManager(cityListManager); 219 | cityRecyclerView.setAdapter(cityAdapter); 220 | cityAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { 221 | @Override 222 | public void onItemClick(BaseQuickAdapter adapter, View view, int position) { 223 | areaBeans.clear(); 224 | cityBeans.get(position).setStatus(true); 225 | citySelected = position; 226 | if (oldCitySelected != -1 && oldCitySelected != citySelected) { 227 | addressBeans.get(oldProvinceSelected).getChildren().get(oldCitySelected).setStatus(false); 228 | } 229 | if (position != oldCitySelected) { 230 | if (oldAreaSelected != -1 && cityBeans.get(position).getChildren() != null) { 231 | addressBeans.get(oldProvinceSelected).getChildren().get(oldCitySelected).getChildren().get(oldAreaSelected).setStatus(false); 232 | } 233 | oldAreaSelected = -1; 234 | } 235 | oldCitySelected = citySelected; 236 | if (cityBeans.get(position).getChildren() != null) { 237 | areaBeans.addAll(cityBeans.get(position).getChildren()); 238 | cityAdapter.notifyDataSetChanged(); 239 | areaAdapter.notifyDataSetChanged(); 240 | strings.set(1, cityBeans.get(position).getLabel()); 241 | if (strings.size() == 2) { 242 | strings.add("请选择"); 243 | } else if (strings.size() == 3) { 244 | strings.set(2, "请选择"); 245 | } 246 | tabLayout.setupWithViewPager(viewPager); 247 | viewPagerAdapter.notifyDataSetChanged(); 248 | tabLayout.getTabAt(2).select(); 249 | } else { 250 | oldAreaSelected = -1; 251 | cityAdapter.notifyDataSetChanged(); 252 | areaAdapter.notifyDataSetChanged(); 253 | strings.set(1, cityBeans.get(position).getLabel()); 254 | tabLayout.setupWithViewPager(viewPager); 255 | viewPagerAdapter.notifyDataSetChanged(); 256 | dismiss(); 257 | areaPickerViewCallback.callback(provinceSelected, citySelected); 258 | } 259 | } 260 | }); 261 | 262 | areaBeans = new ArrayList<>(); 263 | areaAdapter = new AreaAdapter(R.layout.item_address, areaBeans); 264 | LinearLayoutManager areaListManager = new LinearLayoutManager(context); 265 | areaRecyclerView.setLayoutManager(areaListManager); 266 | areaRecyclerView.setAdapter(areaAdapter); 267 | areaAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { 268 | @Override 269 | public void onItemClick(BaseQuickAdapter adapter, View view, int position) { 270 | strings.set(2, areaBeans.get(position).getLabel()); 271 | tabLayout.setupWithViewPager(viewPager); 272 | viewPagerAdapter.notifyDataSetChanged(); 273 | areaBeans.get(position).setStatus(true); 274 | areaSelected = position; 275 | if (oldAreaSelected != -1 && oldAreaSelected != position) { 276 | areaBeans.get(oldAreaSelected).setStatus(false); 277 | } 278 | oldAreaSelected = areaSelected; 279 | areaAdapter.notifyDataSetChanged(); 280 | dismiss(); 281 | areaPickerViewCallback.callback(provinceSelected, citySelected, areaSelected); 282 | } 283 | }); 284 | 285 | viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 286 | @Override 287 | public void onPageScrolled(int i, float v, int i1) { 288 | 289 | } 290 | 291 | @Override 292 | public void onPageSelected(int i) { 293 | switch (i) { 294 | case 0: 295 | provinceRecyclerView.scrollToPosition(oldProvinceSelected == -1 ? 0 : oldProvinceSelected); 296 | break; 297 | case 1: 298 | cityRecyclerView.scrollToPosition(oldCitySelected == -1 ? 0 : oldCitySelected); 299 | break; 300 | case 2: 301 | areaRecyclerView.scrollToPosition(oldAreaSelected == -1 ? 0 : oldAreaSelected); 302 | break; 303 | } 304 | } 305 | 306 | @Override 307 | public void onPageScrollStateChanged(int i) { 308 | 309 | } 310 | }); 311 | 312 | } 313 | 314 | class ViewPagerAdapter extends PagerAdapter { 315 | 316 | @Override 317 | public int getCount() { 318 | return strings.size(); 319 | } 320 | 321 | @Override 322 | public boolean isViewFromObject(@NonNull View view, @NonNull Object o) { 323 | return view == o; 324 | } 325 | 326 | @Nullable 327 | @Override 328 | public CharSequence getPageTitle(int position) { 329 | return strings.get(position); 330 | } 331 | 332 | @NonNull 333 | @Override 334 | public Object instantiateItem(@NonNull ViewGroup container, int position) { 335 | container.addView(views.get(position)); 336 | Log.e("AreaPickView", "------------instantiateItem"); 337 | return views.get(position); 338 | } 339 | 340 | @Override 341 | public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { 342 | container.removeView(views.get(position)); 343 | Log.e("AreaPickView", "------------destroyItem"); 344 | } 345 | 346 | } 347 | 348 | public interface AreaPickerViewCallback { 349 | void callback(int... value); 350 | } 351 | 352 | public void setAreaPickerViewCallback(AreaPickerViewCallback areaPickerViewCallback) { 353 | this.areaPickerViewCallback = areaPickerViewCallback; 354 | } 355 | 356 | public void setSelect(int... value) { 357 | strings = new ArrayList<>(); 358 | if (value == null) { 359 | strings.add("请选择"); 360 | if (isCreate) { 361 | tabLayout.setupWithViewPager(viewPager); 362 | viewPagerAdapter.notifyDataSetChanged(); 363 | tabLayout.getTabAt(0).select(); 364 | if (provinceSelected != -1) 365 | addressBeans.get(provinceSelected).setStatus(false); 366 | if (citySelected != -1) 367 | addressBeans.get(provinceSelected).getChildren().get(citySelected).setStatus(false); 368 | cityBeans.clear(); 369 | areaBeans.clear(); 370 | provinceAdapter.notifyDataSetChanged(); 371 | cityAdapter.notifyDataSetChanged(); 372 | areaAdapter.notifyDataSetChanged(); 373 | } 374 | return; 375 | } 376 | if (value.length == 3) { 377 | strings.add(addressBeans.get(value[0]).getLabel()); 378 | strings.add(addressBeans.get(value[0]).getChildren().get(value[1]).getLabel()); 379 | strings.add(addressBeans.get(value[0]).getChildren().get(value[1]).getChildren().get(value[2]).getLabel()); 380 | tabLayout.setupWithViewPager(viewPager); 381 | viewPagerAdapter.notifyDataSetChanged(); 382 | tabLayout.getTabAt(value.length - 1).select(); 383 | if (provinceSelected != -1) 384 | addressBeans.get(provinceSelected).setStatus(false); 385 | if (citySelected != -1) 386 | addressBeans.get(provinceSelected).getChildren().get(citySelected).setStatus(false); 387 | addressBeans.get(value[0]).setStatus(true); 388 | addressBeans.get(value[0]).getChildren().get(value[1]).setStatus(true); 389 | addressBeans.get(value[0]).getChildren().get(value[1]).getChildren().get(value[2]).setStatus(true); 390 | cityBeans.clear(); 391 | cityBeans.addAll(addressBeans.get(value[0]).getChildren()); 392 | areaBeans.clear(); 393 | areaBeans.addAll(addressBeans.get(value[0]).getChildren().get(value[1]).getChildren()); 394 | provinceAdapter.notifyDataSetChanged(); 395 | cityAdapter.notifyDataSetChanged(); 396 | areaAdapter.notifyDataSetChanged(); 397 | oldProvinceSelected = value[0]; 398 | oldCitySelected = value[1]; 399 | oldAreaSelected = value[2]; 400 | areaRecyclerView.scrollToPosition(oldAreaSelected == -1 ? 0 : oldAreaSelected); 401 | } 402 | 403 | if (value.length == 2) { 404 | strings.add(addressBeans.get(value[0]).getLabel()); 405 | strings.add(addressBeans.get(value[0]).getChildren().get(value[1]).getLabel()); 406 | tabLayout.setupWithViewPager(viewPager); 407 | viewPagerAdapter.notifyDataSetChanged(); 408 | tabLayout.getTabAt(value.length - 1).select(); 409 | addressBeans.get(provinceSelected).setStatus(false); 410 | addressBeans.get(provinceSelected).getChildren().get(citySelected).setStatus(false); 411 | addressBeans.get(value[0]).setStatus(true); 412 | addressBeans.get(value[0]).getChildren().get(value[1]).setStatus(true); 413 | cityBeans.clear(); 414 | cityBeans.addAll(addressBeans.get(value[0]).getChildren()); 415 | provinceAdapter.notifyDataSetChanged(); 416 | cityAdapter.notifyDataSetChanged(); 417 | oldProvinceSelected = value[0]; 418 | oldCitySelected = value[1]; 419 | oldAreaSelected = -1; 420 | cityRecyclerView.scrollToPosition(oldCitySelected == -1 ? 0 : oldCitySelected); 421 | } 422 | 423 | } 424 | 425 | } 426 | -------------------------------------------------------------------------------- /app/src/main/java/com/hicoo/areapickerview/CityAdapter.java: -------------------------------------------------------------------------------- 1 | package com.hicoo.areapickerview; 2 | 3 | import android.graphics.Color; 4 | import android.support.annotation.Nullable; 5 | 6 | import com.chad.library.adapter.base.BaseQuickAdapter; 7 | import com.chad.library.adapter.base.BaseViewHolder; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by ZhouZi on 2018/9/29. 13 | * time:11:39 14 | * ----------Dragon be here!----------/ 15 | *    ┏┓   ┏┓ 16 | *   ┏┛┻━━━┛┻┓━━━ 17 | *   ┃      ┃ 18 | *   ┃   ━  ┃ 19 | *   ┃ ┳┛ ┗┳ 20 | *   ┃      ┃ 21 | *   ┃   ┻  ┃ 22 | *   ┃     ┃ 23 | *   ┗━┓   ┏━┛Code is far away from bug with the animal protecting 24 | *     ┃   ┃ 神兽保佑,代码无bug 25 | *     ┃   ┃ 26 | *     ┃   ┗━━━┓ 27 | *     ┃      ┣┓ 28 | *     ┃       ┏┛ 29 | *     ┗┓┓┏━┳┓┏┛━━━━━ 30 | *      ┃┫┫ ┃┫┫ 31 | *      ┗┻┛ ┗┻┛ 32 | * ━━━━━━━━━━━神兽出没━━━━━━━━━━━━━━ 33 | */ 34 | public class CityAdapter extends BaseQuickAdapter { 35 | public CityAdapter(int layoutResId, @Nullable List data) { 36 | super(layoutResId, data); 37 | } 38 | 39 | @Override 40 | protected void convert(BaseViewHolder helper, AddressBean.CityBean item) { 41 | helper.setText(R.id.textview, item.getLabel()); 42 | helper.setTextColor(R.id.textview, item.isStatus() ? Color.parseColor("#65C15C") : Color.parseColor("#444444")); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/hicoo/areapickerview/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.hicoo.areapickerview; 2 | 3 | import android.content.res.AssetManager; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.Toast; 9 | 10 | import com.google.gson.Gson; 11 | import com.google.gson.reflect.TypeToken; 12 | 13 | import java.io.BufferedReader; 14 | import java.io.IOException; 15 | import java.io.InputStreamReader; 16 | import java.util.List; 17 | 18 | public class MainActivity extends AppCompatActivity { 19 | 20 | private AreaPickerView areaPickerView; 21 | private List addressBeans; 22 | private Button button; 23 | private int[] i; 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_main); 29 | 30 | Gson gson = new Gson(); 31 | addressBeans = gson.fromJson(getCityJson(), new TypeToken>() { 32 | }.getType()); 33 | 34 | areaPickerView = new AreaPickerView(this, R.style.Dialog, addressBeans); 35 | areaPickerView.setAreaPickerViewCallback(new AreaPickerView.AreaPickerViewCallback() { 36 | @Override 37 | public void callback(int... value) { 38 | i=value; 39 | if (value.length == 3) 40 | button.setText(addressBeans.get(value[0]).getLabel() + "-" + addressBeans.get(value[0]).getChildren().get(value[1]).getLabel() + "-" + addressBeans.get(value[0]).getChildren().get(value[1]).getChildren().get(value[2]).getLabel()); 41 | else 42 | button.setText(addressBeans.get(value[0]).getLabel() + "-" + addressBeans.get(value[0]).getChildren().get(value[1]).getLabel()); 43 | } 44 | }); 45 | } 46 | 47 | public void btn(View view) { 48 | button = (Button) view; 49 | areaPickerView.setSelect(i); 50 | areaPickerView.show(); 51 | } 52 | 53 | private String getCityJson() { 54 | StringBuilder stringBuilder = new StringBuilder(); 55 | try { 56 | AssetManager assetManager = this.getAssets(); 57 | BufferedReader bf = new BufferedReader(new InputStreamReader( 58 | assetManager.open("region.json"))); 59 | String line; 60 | while ((line = bf.readLine()) != null) { 61 | stringBuilder.append(line); 62 | } 63 | } catch (IOException e) { 64 | e.printStackTrace(); 65 | } 66 | return stringBuilder.toString(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/hicoo/areapickerview/ProvinceAdapter.java: -------------------------------------------------------------------------------- 1 | package com.hicoo.areapickerview; 2 | 3 | import android.graphics.Color; 4 | import android.support.annotation.Nullable; 5 | 6 | import com.chad.library.adapter.base.BaseQuickAdapter; 7 | import com.chad.library.adapter.base.BaseViewHolder; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by ZhouZi on 2018/9/29. 13 | * time:11:31 14 | * ----------Dragon be here!----------/ 15 | *    ┏┓   ┏┓ 16 | *   ┏┛┻━━━┛┻┓━━━ 17 | *   ┃      ┃ 18 | *   ┃   ━  ┃ 19 | *   ┃ ┳┛ ┗┳ 20 | *   ┃      ┃ 21 | *   ┃   ┻  ┃ 22 | *   ┃     ┃ 23 | *   ┗━┓   ┏━┛Code is far away from bug with the animal protecting 24 | *     ┃   ┃ 神兽保佑,代码无bug 25 | *     ┃   ┃ 26 | *     ┃   ┗━━━┓ 27 | *     ┃      ┣┓ 28 | *     ┃       ┏┛ 29 | *     ┗┓┓┏━┳┓┏┛━━━━━ 30 | *      ┃┫┫ ┃┫┫ 31 | *      ┗┻┛ ┗┻┛ 32 | * ━━━━━━━━━━━神兽出没━━━━━━━━━━━━━━ 33 | */ 34 | public class ProvinceAdapter extends BaseQuickAdapter { 35 | public ProvinceAdapter(int layoutResId, @Nullable List data) { 36 | super(layoutResId, data); 37 | } 38 | 39 | @Override 40 | protected void convert(BaseViewHolder helper, AddressBean item) { 41 | helper.setText(R.id.textview, item.getLabel()); 42 | helper.setTextColor(R.id.textview, item.isStatus() ? Color.parseColor("#65C15C") : Color.parseColor("#444444")); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/res/anim/push_bottom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/anim/push_bottom_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 |