Android(安卓)地址选择器仿京东;
16lz
2021-01-26
控件很简单,上方tab是使用LinearLayout动态添加View,下方就是一个RecyclerView;
目前的数据就三级(省市区\县),选择完成或点击确定就回调结果(Json字符串);
点击上方的tab可以回选;
....
很简单,主要是代码和思路吧;看一下代码;
public class AddressSelectView extends RelativeLayout { private LinearLayout tab; private RecyclerView rv; private Context mC; private AddressBean addressBean;//数据源 private List addressDatas; //当前正在选择的数据 private List alreadySelectDatas; //已经选择的数据 public AddressSelectView(Context context) { super(context); init(context); } public AddressSelectView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public AddressSelectView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private View rootView; private void init(Context context) { mC = context; rootView = View.inflate(context, R.layout.activity_address_select, this); tab = rootView.findViewById(R.id.tab); rv = rootView.findViewById(R.id.rv); initList(); initData(); initView(); } private String clickText; //回退时点击的文字 private void initList() { rootView.findViewById(R.id.tvQ).setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { if (onSelectConfirmListEner != null) onSelectConfirmListEner.onConfirm(new Gson().toJson(alreadySelectDatas)); } }); setOnTabClickListEner(new OnTabClickListEner() { @Override public void onTabClick(View view, int position) { if (alreadySelectDatas == null || position == tab.getChildCount() - 1) return; if (alreadySelectDatas.size() > position) clickText = alreadySelectDatas.get(position).getName(); if (position == 0) { //如果点击第一个,就重新开始选择 if (alreadySelectDatas != null) alreadySelectDatas.clear(); tab.removeAllViews(); addRadioButton("选择省"); if (addressBean != null) { addressAdapter.setDatas(addressBean.getProvince()); } } else { //如果点击的不是第一个,则刷新数据 List alreadySelectDatas2 = new ArrayList<>(); if (alreadySelectDatas.size() >= position) { for (int i = 0; i < position; i++) { //只保留点击的这个之前的数据; alreadySelectDatas2.add(alreadySelectDatas.get(i)); } } alreadySelectDatas.clear(); alreadySelectDatas.addAll(alreadySelectDatas2); //使用新的数据重新规划数据源和UI tab.removeAllViews(); for (int j = 0; j < alreadySelectDatas.size(); j++) { addRadioButton(alreadySelectDatas.get(j).getName()); } selectPostion(alreadySelectDatas.get(alreadySelectDatas.size() - 1), false); } } }); } private AddressAdapter addressAdapter; private void initView() { addRadioButton("选择省"); rv.setLayoutManager(new LinearLayoutManager(mC)); addressAdapter = new AddressAdapter(mC, null); rv.setAdapter(addressAdapter); if (addressBean != null) { addressAdapter.setDatas(addressBean.getProvince()); } } /** * 初始化数据 * 拿assets下的json文件 */ private void initData() { StringBuilder jsonSB = new StringBuilder(); try { BufferedReader addressJsonStream = new BufferedReader(new InputStreamReader(mC.getAssets().open("address.json"))); String line; while ((line = addressJsonStream.readLine()) != null) { jsonSB.append(line); } } catch (IOException e) { e.printStackTrace(); } // 将数据转换为对象 addressBean = new Gson().fromJson(jsonSB.toString(), AddressBean.class); } /** * 添加一个Tab * * @param text * @return */ private void addRadioButton(String text) { for (int i = 0; i < tab.getChildCount(); i++) { ((TextView) tab.getChildAt(i)).setTextColor(getResources().getColor(R.color.textmain)); } final TextView textView = new TextView(mC); textView.setTag(tab.getChildCount()); textView.setText(text); textView.setTextSize(16); textView.setPadding(20, 0, 0, 0); textView.setTextColor(getResources().getColor(R.color.textselect)); textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (onTabClickListEner != null) onTabClickListEner.onTabClick(textView, (int) textView.getTag()); } }); tab.addView(textView); } /** * 选择一个位置后 * * @param data */ private void selectPostion(AddressBean.AddressItemBean data, boolean isAddData) { rv.scrollToPosition(0); if (alreadySelectDatas == null) { alreadySelectDatas = new ArrayList<>(); } if (isAddData) alreadySelectDatas.add(data); if (addressDatas == null) { addressDatas = new ArrayList<>(); } else { addressDatas.clear(); } //修改当前选择的名称 ((TextView) tab.getChildAt(tab.getChildCount() - 1)).setText(data.getName()); if (tab.getChildCount() == 1) { addRadioButton("选择市"); for (int i = 0; i < addressBean.getCity().size(); i++) { if (TextUtils.equals(data.getId(), addressBean.getCity().get(i).getAboveId())) { addressDatas.add(addressBean.getCity().get(i)); } } } else if (tab.getChildCount() == 2) { addRadioButton("选择区"); for (int i = 0; i < addressBean.getDistrict().size(); i++) { if (TextUtils.equals(data.getId(), addressBean.getDistrict().get(i).getAboveId())) { addressDatas.add(addressBean.getDistrict().get(i)); } } }else { if (onSelectConfirmListEner != null) onSelectConfirmListEner.onConfirm(new Gson().toJson(alreadySelectDatas)); } addressAdapter.setDatas(addressDatas); } private class AddressAdapter extends RecyclerView.Adapter { private Context context; private List datas; public AddressAdapter(Context context, List datas) { this.context = context; if (datas == null) { this.datas = new ArrayList<>(); } else { this.datas = datas; } } public void setDatas(List datas) { if (datas == null) { this.datas = new ArrayList<>(); } else { this.datas = datas; } notifyDataSetChanged(); } @NonNull @Override public Vh onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new Vh(LayoutInflater.from(context).inflate(R.layout.item_address, parent, false)); } @Override public void onBindViewHolder(@NonNull Vh holder, final int position) { holder.tv.setText(datas.get(position).getName()); holder.tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { selectPostion(datas.get(position), true); } }); //如果用户点击导航条重新选择的话,就标记当前选择过的颜色加深 if (TextUtils.equals(datas.get(position).getName(), clickText)) { holder.tv.setTextColor(context.getResources().getColor(R.color.textselect)); } else { holder.tv.setTextColor(context.getResources().getColor(R.color.textmain)); } } @Override public int getItemCount() { return datas.size(); } class Vh extends RecyclerView.ViewHolder { public TextView tv; public Vh(@NonNull View itemView) { super(itemView); tv = itemView.findViewById(R.id.tv); } } } interface OnTabClickListEner { void onTabClick(View view, int position); } private OnTabClickListEner onTabClickListEner; private void setOnTabClickListEner(OnTabClickListEner onTabClickListEner) { this.onTabClickListEner = onTabClickListEner; } public interface OnSelectConfirmListEner { void onConfirm(String s); } public OnSelectConfirmListEner onSelectConfirmListEner; public void setOnSelectConfirmListEner(OnSelectConfirmListEner onSelectConfirmListEner) { this.onSelectConfirmListEner = onSelectConfirmListEner; }}
项目在这里:https://github.com/CuiChenbo/AddressSelectView
若是想实现类似的效果,推荐把源代码copy下来,按照自己的UI风格和数据源格式改一下就OK啦;
当然什么代码都不动也可以,就是上面的效果;
把控件放在一个PopupWindow或Dialog中弹出来,选择完成后在隐藏掉;
更多相关文章
- 一句话锁定MySQL数据占用元凶
- conversion to dalvik format failed with error 1 错误解决方案
- (未解决)问题记录ionic android 签名之后安装到手机上点击运行出
- Android(安卓)listview适配器
- 第一节.安装Android(安卓)Studio(Ubuntu)
- 在Android上使用微信开源数据库框架WCDB
- smalidea动态调式Android(安卓)smali代码
- android 客户端上传到第三方应用市场
- 【Android(安卓)基础】 序列化 Parcelable 使用