<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android仿京東實(shí)現(xiàn)地址選擇功能

          共 24505字,需瀏覽 50分鐘

           ·

          2021-03-07 08:47

          最近在做地址管理的功能,新建地址的時(shí)候,需要根據(jù)后臺(tái)提供的省市區(qū)的數(shù)據(jù),讓用戶進(jìn)行地址的選擇,最近項(xiàng)目比較趕,本來想網(wǎng)上找一個(gè)的,可是找了很久都沒找到我想要的效果,所以就根據(jù)后臺(tái)提供的數(shù)據(jù),弄了一個(gè)。

          實(shí)現(xiàn)流程:

              1、效果圖

              2、自定義收貨地址選擇器

              3、設(shè)置點(diǎn)擊按鈕打開PopWindow進(jìn)行地址選擇

              4、設(shè)置選擇器默認(rèn)數(shù)據(jù)

              5、將獲取的省市區(qū)的數(shù)據(jù)進(jìn)行分類

              6、設(shè)置地址選擇器的布局文件

              7、總結(jié)


          實(shí)現(xiàn)步驟:

          1、效果圖


          本來數(shù)據(jù)是根據(jù)請求后臺(tái)接口返回的數(shù)據(jù),我這里就不請求后臺(tái)數(shù)據(jù)了,直接把請求成功后的數(shù)據(jù)寫死,可是把全國省市區(qū)的數(shù)據(jù)太多,導(dǎo)致報(bào)錯(cuò):字符串?dāng)?shù)據(jù)太長,所以我這里只獲取了北京的數(shù)據(jù)。


          2、自定義收貨地址選擇器

          public class AddressSelector extends LinearLayout implements View.OnClickListener{private int TextSelectedColor = Color.parseColor("#D5A872");private int TextEmptyColor = Color.parseColor("#333333");//頂部的tab集合private ArrayList<Tab> tabs;//列表的適配器private AddressAdapter addressAdapter;private ArrayList<CityInterface> cities;private OnItemClickListener onItemClickListener;private OnTabSelectedListener onTabSelectedListener;private RecyclerView list;//tabs的外層layoutprivate LinearLayout tabs_layout;//會(huì)移動(dòng)的橫線布局private Line line;private Context mContext;//總共tab的數(shù)量private int tabAmount = 3;//當(dāng)前tab的位置private int tabIndex = 0;//分隔線private View grayLine;//列表文字大小private int listTextSize = -1;//列表文字顏色private int listTextNormalColor = Color.parseColor("#333333");//列表文字選中的顏色private int listTextSelectedColor = Color.parseColor("#D5A872");//列表icon資源private int listItemIcon = -1;public AddressSelector(Context context) {super(context);        init(context);    }public AddressSelector(Context context, AttributeSet attrs) {super(context, attrs);        init(context);    }public AddressSelector(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);        init(context);    }private void init(Context context){        removeAllViews();this.mContext = context;        setOrientation(VERTICAL);        tabs_layout = new LinearLayout(mContext);        tabs_layout.setWeightSum(tabAmount);        tabs_layout.setLayoutParams(new LayoutParams(                LayoutParams.MATCH_PARENT,                LayoutParams.WRAP_CONTENT));        tabs_layout.setOrientation(HORIZONTAL);        addView(tabs_layout);        tabs = new ArrayList<>();        Tab tab = newTab("請選擇",true);        tabs_layout.addView(tab);        tabs.add(tab);for(int i = 1;i<tabAmount;i++){            Tab _tab = newTab("",false);            _tab.setIndex(i);            tabs_layout.addView(_tab);            tabs.add(_tab);        }        line = new Line(mContext);        line.setLayoutParams(new LayoutParams(                LayoutParams.MATCH_PARENT,6));        line.setSum(tabAmount);        addView(line);        grayLine = new View(mContext);        grayLine.setLayoutParams(new LayoutParams(                LayoutParams.MATCH_PARENT,2));        grayLine.setBackgroundColor(mContext.getResources().getColor(R.color.line_DDDDDD));        addView(grayLine);        list = new RecyclerView(mContext);        list.setLayoutParams(new ViewGroup.LayoutParams(                LayoutParams.MATCH_PARENT,                LayoutParams.MATCH_PARENT));        list.setLayoutManager(new LinearLayoutManager(mContext));        addView(list);    }/**     * 得到一個(gè)新的tab對象     * */private Tab newTab(CharSequence text, boolean isSelected){        Tab tab = new Tab(mContext);        tab.setLayoutParams(new LayoutParams(0,LayoutParams.WRAP_CONTENT,1));        tab.setGravity(Gravity.CENTER);        tab.setPadding(0,5,0,5);        tab.setSelected(isSelected);        tab.setText(text);        tab.setTextEmptyColor(TextEmptyColor);        tab.setTextSelectedColor(TextSelectedColor);        tab.setOnClickListener(this);return tab;    }/**     * 設(shè)置tab的數(shù)量,默認(rèn)3個(gè),不小于2個(gè)     * @param tabAmount tab的數(shù)量     * */public void setTabAmount(int tabAmount) {if(tabAmount >= 2){this.tabAmount = tabAmount;            init(mContext);        }elsethrow new RuntimeException("AddressSelector tabAmount can not less-than 2 !");    }/**     * 設(shè)置列表的點(diǎn)擊事件回調(diào)接口     * */public void setOnItemClickListener(OnItemClickListener onItemClickListener) {this.onItemClickListener = onItemClickListener;    }/**     * 設(shè)置列表的數(shù)據(jù)源,設(shè)置后立即生效     * */public void setCities(ArrayList cities) {if(cities == null||cities.size() <= 0)return;if(cities.get(0) instanceof CityInterface){this.cities = cities;if(addressAdapter == null){                addressAdapter = new AddressAdapter();                list.setAdapter(addressAdapter);            }            addressAdapter.notifyDataSetChanged();        }else{throw new RuntimeException("AddressSelector cities must implements CityInterface");        }    }/**     * 設(shè)置頂部tab的點(diǎn)擊事件回調(diào)     * */public void setOnTabSelectedListener(OnTabSelectedListener onTabSelectedListener) {this.onTabSelectedListener = onTabSelectedListener;    }@Overridepublic void onClick(View v) {        Tab tab = (Tab) v;//如果點(diǎn)擊的tab大于index則直接跳出if(tab.index > tabIndex)return;        tabIndex = tab.index;if(onTabSelectedListener != null){if(tab.isSelected)                onTabSelectedListener.onTabReselected(AddressSelector.this,tab);else                onTabSelectedListener.onTabSelected(AddressSelector.this,tab);        }        resetAllTabs(tabIndex);        line.setIndex(tabIndex);        tab.setSelected(true);    }private void resetAllTabs(int tabIndex){if(tabs != null)for(int i =0;i<tabs.size();i++){            tabs.get(i).resetState();if(i > tabIndex){                tabs.get(i).setText("");            }        }    }/**     * 設(shè)置Tab文字選中的顏色     * */public void setTextSelectedColor(int textSelectedColor) {        TextSelectedColor = textSelectedColor;    }/**     * 設(shè)置Tab文字默認(rèn)顏色     * */public void setTextEmptyColor(int textEmptyColor) {        TextEmptyColor = textEmptyColor;    }/**     * 設(shè)置Tab橫線的顏色     * */public void setLineColor(int lineColor) {        line.setSelectedColor(lineColor);    }/**     * 設(shè)置tab下方分隔線的顏色     * */public void setGrayLineColor(int grayLineColor) {        grayLine.setBackgroundColor(grayLineColor);    }/**     * 設(shè)置列表文字大小     * */public void setListTextSize(int listTextSize) {this.listTextSize = listTextSize;    }/**     * 設(shè)置列表文字顏色     * */public void setListTextNormalColor(int listTextNormalColor) {this.listTextNormalColor = listTextNormalColor;    }/**     * 設(shè)置列表選中文字顏色     * */public void setListTextSelectedColor(int listTextSelectedColor) {this.listTextSelectedColor = listTextSelectedColor;    }/**     * 設(shè)置列表icon資源     * */public void setListItemIcon(int listItemIcon) {this.listItemIcon = listItemIcon;    }/**     * 標(biāo)簽控件     * */@SuppressLint("AppCompatCustomView")public class Tab extends TextView {private int index = 0;private int TextSelectedColor = Color.parseColor("#D5A872");private int TextEmptyColor = Color.parseColor("#333333");/**         * 是否選中狀態(tài)         * */private boolean isSelected = false;public Tab(Context context) {super(context);            init();        }public Tab(Context context, AttributeSet attrs) {super(context, attrs);            init();        }public Tab(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);            init();        }private void init(){            setTextSize(15);        }@Overridepublic void setText(CharSequence text, BufferType type) {if(isSelected)                setTextColor(TextSelectedColor);else                setTextColor(TextEmptyColor);super.setText(text, type);        }@Overridepublic void setSelected(boolean selected) {            isSelected = selected;            setText(getText());        }public int getIndex() {return index;        }public void setIndex(int index) {this.index = index;        }public void resetState(){            isSelected = false;            setText(getText());        }public void setTextSelectedColor(int textSelectedColor) {            TextSelectedColor = textSelectedColor;        }public void setTextEmptyColor(int textEmptyColor) {            TextEmptyColor = textEmptyColor;        }    }/**     * 橫線控件     * */private class Line extends LinearLayout {private int sum = 3;private int oldIndex = 0;private int nowIndex = 0;private View indicator;private int SelectedColor = Color.parseColor("#D5A872");public Line(Context context) {super(context);            init(context);        }public Line(Context context, AttributeSet attrs) {super(context, attrs);            init(context);        }public Line(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);            init(context);        }private void init(Context context){            setOrientation(HORIZONTAL);            setLayoutParams(new LayoutParams(                    LayoutParams.MATCH_PARENT,6));            setWeightSum(tabAmount);            indicator= new View(context);            indicator.setLayoutParams(new LayoutParams(0,LayoutParams.MATCH_PARENT,1));            indicator.setBackgroundColor(SelectedColor);            addView(indicator);        }public void setIndex(int index){int onceWidth = getWidth()/sum;this.nowIndex = index;            ObjectAnimator animator = ObjectAnimator.ofFloat(indicator, "translationX", indicator.getTranslationX(), (nowIndex-oldIndex)*onceWidth);            animator.setDuration(300);            animator.start();        }public void setSum(int sum) {this.sum = sum;        }public void setSelectedColor(int selectedColor) {            SelectedColor = selectedColor;        }    }private class AddressAdapter extends RecyclerView.Adapter<AddressAdapter.MyViewHolder>{@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {            MyViewHolder viewHolder =new MyViewHolder(LayoutInflater.from(mContext).inflate(                            R.layout.item_address,parent,false));return viewHolder;        }@Overridepublic void onBindViewHolder(MyViewHolder holder, final int position) {if(listItemIcon != -1)                holder.img.setImageResource(listItemIcon);if(listTextSize != -1)                holder.tv.setTextSize(listTextSize);if(TextUtils.equals(tabs.get(tabIndex).getText(),cities.get(position).getCityName())){                holder.img.setVisibility(View.VISIBLE);                holder.tv.setTextColor(listTextSelectedColor);            }else{                holder.img.setVisibility(View.INVISIBLE);                holder.tv.setTextColor(listTextNormalColor);            }            holder.tv.setText(cities.get(position).getCityName());            holder.itemView.setTag(cities.get(position));            holder.itemView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(onItemClickListener != null){                        onItemClickListener.itemClick(AddressSelector.this,(CityInterface) v.getTag(),tabIndex,position);                        tabs.get(tabIndex).setText(((CityInterface) v.getTag()).getCityName());                        tabs.get(tabIndex).setTag(v.getTag());if(tabIndex+1 < tabs.size()){                            tabIndex ++;                            resetAllTabs(tabIndex);                            line.setIndex(tabIndex);                            tabs.get(tabIndex).setText("請選擇");                            tabs.get(tabIndex).setSelected(true);                        }                    }                }            });        }@Overridepublic int getItemCount() {return cities.size();        }class MyViewHolder extends RecyclerView.ViewHolder{public TextView tv;public ImageView img;public View itemView;public MyViewHolder(View itemView) {super(itemView);this.itemView = itemView;                tv = (TextView) itemView.findViewById(R.id.item_address_tv);                img = (ImageView) itemView.findViewById(R.id.item_address_img);            }        }    }public interface OnTabSelectedListener {void onTabSelected(AddressSelector addressSelector, Tab tab);void onTabReselected(AddressSelector addressSelector, Tab tab);    }}


          3、Demo中設(shè)置點(diǎn)擊按鈕打開PopWindow進(jìn)行地址選擇

          /**     * 設(shè)置彈出PopWindow     * @param v     */    private void setAddressSelectorPopup(View v) {        int screenHeigh = getResources().getDisplayMetrics().heightPixels;
          CommonPopWindow.newBuilder() .setView(R.layout.pop_address_selector_bottom) .setAnimationStyle(R.style.AnimUp) .setBackgroundDrawable(new BitmapDrawable()) .setSize(ViewGroup.LayoutParams.MATCH_PARENT, Math.round(screenHeigh * 0.6f)) .setViewOnClickListener(this) .setBackgroundDarkEnable(true) .setBackgroundAlpha(0.7f) .setBackgroundDrawable(new ColorDrawable(999999)) .build(this) .showAsBottom(v); }
          @Override public void getChildView(final PopupWindow mPopupWindow, View view, int mLayoutResId) { switch (mLayoutResId) { case R.layout.pop_address_selector_bottom: ImageView imageBtn = view.findViewById(R.id.img_guanbi); AddressSelector addressSelector = view.findViewById(R.id.address);
          //數(shù)據(jù)解析 AddressSelectorReq addressSelectorReq = new Gson().fromJson(String.valueOf(response), AddressSelectorReq.class); //設(shè)置默認(rèn)選擇數(shù)據(jù) dealWithAddressSelector(addressSelector, addressSelectorReq.getDatas(), mPopupWindow);
          imageBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPopupWindow.dismiss(); } }); break; } }


          4、設(shè)置選擇器默認(rèn)數(shù)據(jù)

           private void dealWithAddressSelector(AddressSelector addressSelector, final List<AddressSelectorReq.DatasBean>             addressSelectorList, final PopupWindow mPopupWindow) {        final String[] sheng = new String[3];
          final ArrayList<ItemAddressReq> itemAddressReqs = getItemAddressSheng(addressSelectorList); addressSelector.setTabAmount(3); //設(shè)置數(shù)據(jù) addressSelector.setCities(itemAddressReqs); //設(shè)置Tab橫線的顏色 addressSelector.setLineColor(Color.parseColor("#D5A872")); //設(shè)置Tab文字默認(rèn)顏色 addressSelector.setTextEmptyColor(Color.parseColor("#000000")); //設(shè)置列表選中文字顏色 addressSelector.setListTextSelectedColor(Color.parseColor("#D5A872")); //設(shè)置Tab文字選中的顏色 addressSelector.setTextSelectedColor(Color.parseColor("#D5A872"));
          //設(shè)置列表的點(diǎn)擊事件回調(diào)接口 addressSelector.setOnItemClickListener(new OnItemClickListener() { @Override public void itemClick(AddressSelector addressSelector, CityInterface city, int tabPosition, int selecePos) { switch (tabPosition) { case 0: //設(shè)置省列表數(shù)據(jù) sheng[0] = city.getCityName(); saveId[0] = addressSelectorList.get(selecePos).getDb_id(); childrenBeanXList = addressSelectorList.get(selecePos).getDb_children(); addressSelector.setCities(getItemAddressShi(childrenBeanXList)); break; case 1: //設(shè)置市列表數(shù)據(jù) sheng[1] = city.getCityName(); saveId[1] = childrenBeanXList.get(selecePos).getCb_id(); childrenBeans = childrenBeanXList.get(selecePos).getCb_children(); addressSelector.setCities(getItemAddressQu(childrenBeans)); break; case 2: //設(shè)置區(qū)列表數(shù)據(jù) sheng[2] = city.getCityName(); saveId[2] = childrenBeans.get(selecePos).getId(); text_suozaidiqu.setText(sheng[0] + sheng[1] + sheng[2]); mPopupWindow.dismiss(); break; } } });

          //設(shè)置頂部tab的點(diǎn)擊事件回調(diào) addressSelector.setOnTabSelectedListener(new AddressSelector.OnTabSelectedListener() { @Override public void onTabSelected(AddressSelector addressSelector, AddressSelector.Tab tab) { switch (tab.getIndex()) { case 0: addressSelector.setCities(itemAddressReqs); break; case 1: addressSelector.setCities(getItemAddressShi(childrenBeanXList)); break; case 2: addressSelector.setCities(getItemAddressQu(childrenBeans)); break; } }
          @Override public void onTabReselected(AddressSelector addressSelector, AddressSelector.Tab tab) {
          } }); }


          5、將獲取的省市區(qū)的數(shù)據(jù)進(jìn)行分類

           /**     * 獲取省的數(shù)據(jù)     *     * @param addressSelectorList     * @return     */    @NonNull    private ArrayList<ItemAddressReq> getItemAddressSheng(List<AddressSelectorReq.DatasBean> addressSelectorList) {        final ArrayList<ItemAddressReq> itemAddressReqs = new ArrayList<>();        for (int i = 0; i < addressSelectorList.size(); i++) {            ItemAddressReq itemAddressReq = new ItemAddressReq();            itemAddressReq.setAreaAbbName(addressSelectorList.get(i).getDb_areaAbbName());            itemAddressReq.setAreaCode(addressSelectorList.get(i).getDb_areaCode());            itemAddressReq.setAreaEnName(addressSelectorList.get(i).getDb_areaEnName());            itemAddressReq.setAreaType(addressSelectorList.get(i).getDb_areaType());            itemAddressReq.setAreaZip(addressSelectorList.get(i).getDb_areaZip());            itemAddressReq.setAreaName(addressSelectorList.get(i).getDb_areaName());            itemAddressReq.setId(addressSelectorList.get(i).getDb_id());            itemAddressReq.setParentId(addressSelectorList.get(i).getDb_parentId());            itemAddressReqs.add(itemAddressReq);        }        return itemAddressReqs;    }

          /** * 獲取市的數(shù)據(jù) * * @return */ @NonNull private ArrayList<ItemAddressReq> getItemAddressShi(List<AddressSelectorReq.DatasBean.ChildrenBeanX> datas) { final ArrayList<ItemAddressReq> itemAddressReqs = new ArrayList<>(); for (int i = 0; i < datas.size(); i++) { ItemAddressReq itemAddressReq = new ItemAddressReq(); itemAddressReq.setAreaAbbName(datas.get(i).getCb_areaAbbName()); itemAddressReq.setAreaCode(datas.get(i).getCb_areaCode()); itemAddressReq.setAreaEnName(datas.get(i).getCb_areaEnName()); itemAddressReq.setAreaType(datas.get(i).getCb_areaType()); itemAddressReq.setAreaZip(datas.get(i).getCb_areaZip()); itemAddressReq.setAreaName(datas.get(i).getCb_areaName()); itemAddressReq.setId(datas.get(i).getCb_id()); itemAddressReq.setParentId(datas.get(i).getCb_parentId()); itemAddressReqs.add(itemAddressReq); } return itemAddressReqs; }
          /** * 獲取區(qū)的數(shù)據(jù) * * @param addressSelectorList * @return */ @NonNull private ArrayList<ItemAddressReq> getItemAddressQu(List<AddressSelectorReq.DatasBean.ChildrenBeanX.ChildrenBean> addressSelectorList) { final ArrayList<ItemAddressReq> itemAddressReqs = new ArrayList<>(); for (int i = 0; i < addressSelectorList.size(); i++) { ItemAddressReq itemAddressReq = new ItemAddressReq(); itemAddressReq.setAreaAbbName(addressSelectorList.get(i).getAreaAbbName()); itemAddressReq.setAreaCode(addressSelectorList.get(i).getAreaCode()); itemAddressReq.setAreaEnName(addressSelectorList.get(i).getAreaEnName()); itemAddressReq.setAreaType(addressSelectorList.get(i).getAreaType()); itemAddressReq.setAreaZip(addressSelectorList.get(i).getAreaZip()); itemAddressReq.setAreaName(addressSelectorList.get(i).getAreaName()); itemAddressReq.setId(addressSelectorList.get(i).getId()); itemAddressReq.setParentId(addressSelectorList.get(i).getParentId()); itemAddressReqs.add(itemAddressReq); } return itemAddressReqs; }


          6、設(shè)置地址選擇器的布局文件

          <?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_alignParentBottom="true"    android:background="#fff"    android:orientation="vertical"    android:padding="1dp">
          <ImageView android:id="@+id/img_guanbi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginTop="15dp" android:layout_marginRight="15dp" android:src="@drawable/guanbi" />
          <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="30dp" android:text="所在區(qū)域" android:textColor="#777777" android:textSize="16sp" />
          <com.showly.ylin.addressselectdemo.addressselector.AddressSelector android:id="@+id/address" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="70dp" /></RelativeLayout>


          7、總結(jié)


          到這里就實(shí)現(xiàn)了地址選擇器的功能,因?yàn)楹笈_(tái)提供的地址數(shù)據(jù)可能不一樣,所以這里就不把全部數(shù)據(jù)拿出來了,需要完整數(shù)據(jù)的也可以Q我。


          需要Demo的童鞋可以在公眾號(hào)回復(fù) “地址選擇器”


          到這里就結(jié)束啦


          點(diǎn)擊這里留言交流哦


          瀏覽 133
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩精品毛片免费视频 | 国产精品后入 | 97色婷婷五月 | 欧美成人一区二区三区 | 婷婷乱伦 |