最近项目中有一个户籍地址选择的功能,需求是仿造京东的做出来,然后我就各种百度,各种搜索,然并卵,才明白别人做的永远都是别人做的,你看似简单其实不然
就自己花了点时间写了一个,当然别人的Demo给了我很多启发
先上图
这个的制作使用TabLayout + ViewPager +Fragment +DIalogFragment
DialogFragment就是类似于popWindow
这套组合必须用DialogFragment 不能用PopupWindow 否则会报viewpager 找不到Id 的错误
当然最重要的是数据的来源,我的数据的来源是本地数据库,这就涉及到一个三级联动的效果,Frgment之间的传值也是个问题,我这里采用的传值是接口回调真个Demo所涉及的传值都是接口回调,当然大家可以利用EventBus来传值,高度解耦,灵巧方便。
我写这篇文章主要是想给大大家一个思路,最好自己写出来,不难。
下面就是主类:
在按钮中写触发事件:
new MyDialogFragment().show(getSupportFragmentManager,);
public class MyDialogFragment extends android.support.v4.app.DialogFragment{
private TabLayout tab;
private ViewPager viewPager;
private ImageView imageView;
private MyAdapter adapter;
public static final String[] tabTitle = new String[]{"请选择","",""};
private List<Fragment> fragmentList = new ArrayList<>();
private ProvinceFragment provinceFragment;
private CityFragment cityFragment;
private CountyFragment countyFragment;
private OnPermanentAddress onPermanentAddressListener;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.address_pop,container);
//初始化Fragment
initFragment();
initView(view);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return view;
}
private void initView(View view) {
tab = (TabLayout) view.findViewById(R.id.tab);
imageView = (ImageView) view.findViewById(R.id.imageView_close);
viewPager = (ViewPager) view.findViewById(R.id.viewpager_address);
//默认只会加载一个界面
viewPager.setOffscreenPageLimit(3);
adapter = new MyAdapter(getChildFragmentManager(),fragmentList);
viewPager.setAdapter(adapter);
//viewPager和TabLayout做关联
tab.setupWithViewPager(viewPager);
//设置可以滑动
tab.setTabMode(TabLayout.MODE_SCROLLABLE);
//点击关闭按钮取消DialogFragment
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onPermanentAddressListener.setPermanentAddress(tabTitle);
getDialog().cancel();
tabTitle[0] = "请选择";
tabTitle[1] = "";
tabTitle[2] = "";
}
});
}
private void initFragment() {
provinceFragment = new ProvinceFragment();
cityFragment = new CityFragment();
countyFragment = new CountyFragment();
fragmentList.add(provinceFragment);
fragmentList.add(cityFragment);
fragmentList.add(countyFragment);
provinceFragment.setTabLayoutTitle(new ProvinceFragment.TabLayoutTitle() {
@Override
public void setTitle(String itemTitle) {
tabTitle[0] = itemTitle;
tabTitle[1] = "请选择";
tabTitle[2] = "";
adapter.notifyDataSetChanged();
viewPager.setCurrentItem(1);
Log.i("TAG", "===setTitle: " + itemTitle);
}
});
provinceFragment.setCityAddressList(new ProvinceFragment.CityData() {
@Override
public void setCityData(List<String> cityList, LinkedHashMap<String,String> cityHashMap) {
cityFragment.map = cityHashMap;
cityFragment.adapter.isClear(true,cityList);
cityList.clear();
}
});
cityFragment.setTabLayoutTitle(new CityFragment.TabLayoutTitle() {
@Override
public void setTitle(String itemTitle,int position) {
tabTitle[1] = itemTitle;
tabTitle[2] = "请选择";
adapter.notifyDataSetChanged();
viewPager.setCurrentItem(position + 1);
}
});
cityFragment.setCityAddressList(new CityFragment.TownData() {
@Override
public void setTownData(List<String> cityList) {
Log.i("TAG", "setTownData: " + cityList.size());
countyFragment.adapter.isClear(true,cityList);
cityList.clear();
}
});
countyFragment.setTabLayoutTitle(new CountyFragment.TabLayoutTitle() {
@Override
public void setTitle(String itemTitle) {
tabTitle[2] = itemTitle;
provinceFragment.provinceAddressList.clear();
adapter.notifyDataSetChanged();
onPermanentAddressListener.setPermanentAddress(tabTitle);
getDialog().cancel();
tabTitle[0] = "请选择";
tabTitle[1] = "";
tabTitle[2] = "";
}
});
}
@Override
public void onStart() {
super.onStart();
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics( dm );
getDialog().getWindow().setLayout( dm.widthPixels, 700 );
getDialog().getWindow().setBackgroundDrawable( new ColorDrawable( 0xff000000 ) );
WindowManager.LayoutParams wlp = getDialog().getWindow().getAttributes();
wlp.gravity = Gravity.BOTTOM;
wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
getDialog().getWindow().setAttributes(wlp);
}
public interface OnPermanentAddress{
void setPermanentAddress(String[] address);
}
public void setOnPernamentAddress(OnPermanentAddress onPermanentAddressListener){
this.onPermanentAddressListener = onPermanentAddressListener;
}
}
这是与之对应的布局:address_pop
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:background="#ffff"
android:weightSum="8"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_marginLeft="30dp"
android:layout_weight="6"
android:layout_width="wrap_content"
android:layout_height="80dp"
app:tabIndicatorColor="@color/orange_big"
app:tabSelectedTextColor="@color/orange_big"
app:tabTextAppearance="@style/MyTabLayoutTextAppearanceInverse"
app:tabTextColor="@color/color_333">
</android.support.design.widget.TabLayout>
<ImageView
android:layout_marginRight="26dp"
android:layout_weight="2"
android:layout_marginTop="20dp"
android:id="@+id/imageView_close"
android:layout_width="0dp"
android:layout_height="40dp"
android:background="@mipmap/close"
android:scaleType="centerCrop"
android:clickable="true"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#f0f1f4"
/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager_address"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" />
</LinearLayout>
tabLayout的颜色以及样式
<color name="color_333">#f000</color> <color name="orange_big">#f00</color>
<style name="MyTabLayoutTextAppearanceInverse" parent="TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"> <item name="android:textSize">26sp</item> </style>
下面是省的Fragment,数据的获取要看你自己的数据来源,这里就不写了。。。
public class ProvinceFragment extends Fragment {
private ListView mListView;
private MyListViewAdapter adapter;
public List<String> provinceAddressList = new ArrayList<>();
private List<String> cityAddressList = new ArrayList<>();
public DzxzHelper dzxzHelper;
private TextView textViewAddress;
private TabLayoutTitle lisenter;
private CityData cityDataListener;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_province,container,false);
initView(view);
return view;
}
private void initView(View view) {
mListView = (ListView) view.findViewById(R.id.listView_provinceAddress);
//初始化数据
initProvinceData();
adapter = new MyListViewAdapter(getContext(),provinceAddressList);
mListView.setAdapter(adapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String strProvinceAddress = provinceAddressList.get(position).toString();
Log.i(TAG, "onItemClick1: " + lisenter);
lisenter.setTitle(strProvinceAddress);
//获取选择的cd_id值
String cd_id_p = dzxzHelper.getCodeId(dzxzHelper.map_p, strProvinceAddress);
//初始化市级对象
dzxzHelper.initCityView(cd_id_p);
//得到与省级对应的城市
initCityData();
Log.i(TAG, "onItemClick2: " + cityDataListener);
cityDataListener.setCityData(cityAddressList,dzxzHelper.map_c);
}
});
}
private void initProvinceData() {
dzxzHelper = new DzxzHelper(getContext(),true);
for (int i = 0; i < dzxzHelper.values_p.length ; i++) {
provinceAddressList.add(dzxzHelper.values_p[i]);
}
}
private void initCityData() {
for (int i = 0; i < dzxzHelper.values_c.length ; i++) {
cityAddressList.add(dzxzHelper.values_c[i]);
}
}
public interface TabLayoutTitle{
void setTitle(String itemTitle);
}
public void setTabLayoutTitle(TabLayoutTitle lisenter){
this.lisenter = lisenter;
}
public interface CityData{
void setCityData(List<String> cityList, LinkedHashMap<String, String> cityLinkedHashMap);
}
public void setCityAddressList(CityData cityDataListener){
this.cityDataListener = cityDataListener;
}
下面是市的Fragment:
public class CityFragment extends Fragment {
private ListView mListView;
public MyListViewAdapter adapter;
public List<String> cityDataList = new ArrayList<>();
private List<String> townDataList = new ArrayList<>();
public LinkedHashMap<String,String> map = new LinkedHashMap<>();
private ProvinceFragment provinceFragment;
private TabLayoutTitle lisenter;
private TownData townDataListener;
private DzxzHelper dzxzHelper;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_province,container,false);
initView(view);
return view;
}
private void initView(View view) {
provinceFragment = new ProvinceFragment();
mListView = (ListView) view.findViewById(R.id.listView_provinceAddress);
adapter = new MyListViewAdapter(getContext(),cityDataList);
mListView.setAdapter(adapter);
dzxzHelper = new DzxzHelper(getContext(),true);
//ListView条目点击监听器
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String strItemContent = cityDataList.get(position);
if (strItemContent.equals("")){
Toast.makeText(getContext(),"你当前选择的城市无效",Toast.LENGTH_SHORT).show();
}else {
lisenter.setTitle(strItemContent,position);
Log.i("TAG", "===strItemContent" + strItemContent);
// 获取选择的城市的id
String cd_id_c = dzxzHelper.getCodeId(map,strItemContent);
// 初始化县级对象
dzxzHelper.initTownView(cd_id_c);
// 获取县城的数据集合
initTownData();
Log.i("TAG", "===onItemClick1: " + cd_id_c);
Log.i("TAG", "===onItemClick2: " + map.toString());
for (int i = 0; i < townDataList.size() ; i++) {
Log.i(TAG, "====县城的数据集合: " + townDataList.get(i));
}
townDataListener.setTownData(townDataList);
}
}
});
}
public interface TabLayoutTitle{
void setTitle(String itemTitle, int position);
}
public void setTabLayoutTitle(TabLayoutTitle lisenter){
this.lisenter = lisenter;
}
private void initTownData() {
for (int i = 0; i < dzxzHelper.map_t.size() ; i++) {
townDataList.add(dzxzHelper.values_t[i]);
}
}
public interface TownData{
void setTownData(List<String> cityList);
}
public void setCityAddressList(TownData townDataListener){
this.townDataListener = townDataListener;
}
下面是县的Fragment:
public class CountyFragment extends Fragment {
private ListView mListView;
public MyListViewAdapter adapter;
public TabLayoutTitle lisenter;
public List<String> townAddressList = new ArrayList<>();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_province,container,false);
initView(view);
return view;
}
private void initView(View view) {
mListView = (ListView) view.findViewById(R.id.listView_provinceAddress);
adapter = new MyListViewAdapter(getContext(),townAddressList);
mListView.setAdapter(adapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
lisenter.setTitle(townAddressList.get(position));
}
});
}
public interface TabLayoutTitle{
void setTitle(String itemTitle);
}
public void setTabLayoutTitle(TabLayoutTitle lisenter){
this.lisenter = lisenter;
}
}
public class MyAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments;
private List<String> tabTitle;
public MyAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
public void setTabTitle(List<String> tabTitle) {
this.tabTitle = tabTitle;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return new MyDialogFragment().tabTitle[position];
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
下面是数据集合ListVIew的Adapter:
public class MyListViewAdapter extends BaseAdapter{
private static boolean isClick = false; //选中项
private Context mConext;
private LayoutInflater mInflater;
private List<String> mList = new ArrayList<>();
private int position ;
private boolean isVisiable = false;
public MyListViewAdapter(Context context,List<String> mListView){
mConext = context;
this.mList = mListView;
mInflater = (LayoutInflater) mConext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int i) {
return mList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
MyViewHolder mHolder = null;
if (convertView == null){
convertView = mInflater.inflate(R.layout.item_listview_province,viewGroup,false);
mHolder = new MyViewHolder(convertView);
convertView.setTag(mHolder);
}else {
mHolder = (MyViewHolder) convertView.getTag();
}
mHolder.textViewAddress.setText(mList.get(i).toString());
return convertView;
}
class MyViewHolder{
private TextView textViewAddress;
private ImageView imageViewCheck;
public MyViewHolder(View view){
textViewAddress = (TextView) view.findViewById(R.id.textView_address);
imageViewCheck = (ImageView) view.findViewById(R.id.imageView_check);
}
}
public void isClear(boolean isClear,List<String> list){
if (isClear){
mList.clear();
}
mList.addAll(list);
notifyDataSetChanged();
}
}