Android 自定义仿京东地址选择器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 自定义仿京东地址选择器相关的知识,希望对你有一定的参考价值。

参考技术A public class AddressPickerViewextends RelativeLayout

// recyclerView 选中Item 的颜色

    private int defaultSelectedColor = Color.parseColor("#3D71FF");

    // recyclerView 未选中Item 的颜色

    private int defaultUnSelectedColor = Color.parseColor("#2c2c2c");

    // 确定字体不可以点击时候的颜色

    private int defaultSureUnClickColor = Color.parseColor("#7F7F7F");

    // 确定字体可以点击时候的颜色

    private int defaultSureCanClickColor = Color.parseColor("#3D71FF");

    private ContextmContext;

    private int defaultTabCount =3; //tab 的数量

    private TabLayoutmTabLayout; // tabLayout

    private RecyclerViewmRvList; // 显示数据的RecyclerView

    private StringdefaultProvince ="省份"; //显示在上面tab中的省份

    private StringdefaultCity ="城市"; //显示在上面tab中的城市

    private StringdefaultDistrict ="区县"; //显示在上面tab中的区县

    private ListmRvData; // 用来在recyclerview显示的数据

    private AddressAdaptermAdapter;  // recyclerview 的adapter

    private YwpAddressBeanmYwpAddressBean; // 总数据

    private YwpAddressBean.AddressItemBeanmSelectProvice; //选中 省份bean

    private YwpAddressBean.AddressItemBeanmSelectCity;//选中 城市bean

    private YwpAddressBean.AddressItemBeanmSelectDistrict;//选中 区县bean

    private int mSelectProvicePosition =0; //选中 省份 位置

    private int mSelectCityPosition =0;//选中 城市  位置

    private int mSelectDistrictPosition =0;//选中 区县  位置

    private OnAddressPickerSureListenermOnAddressPickerSureListener;

    public AddressPickerView(Context context)

super(context);

        init(context);

   

public AddressPickerView(Context context, @Nullable AttributeSet attrs)

super(context, attrs);

        init(context);

   

public AddressPickerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr)

super(context, attrs, defStyleAttr);

        init(context);

   

/**

    * 初始化

    */

    private void init(Context context)

mContext = context;

        mRvData =new ArrayList<>();

        // UI

        View rootView =inflate(mContext, R.layout.address_picker_view, this);

        // tablayout初始化

        mTabLayout = (TabLayout) rootView.findViewById(R.id.tlTabLayout);

        mTabLayout.addTab(mTabLayout.newTab().setText(defaultProvince));

        mTabLayout.addTab(mTabLayout.newTab().setText(defaultCity));

        mTabLayout.addTab(mTabLayout.newTab().setText(defaultDistrict));

        mTabLayout.addOnTabSelectedListener(tabSelectedListener);

        // recyclerview adapter的绑定

        mRvList = (RecyclerView) rootView.findViewById(R.id.rvList);

        mRvList.setLayoutManager(new LinearLayoutManager(context));

        mAdapter =new AddressAdapter();

        mRvList.setAdapter(mAdapter);

        // 初始化默认的本地数据  也提供了方法接收外面数据

        mRvList.post(new Runnable()

@Override

            public void run()

initData();

           

);

   

/**

    * 初始化数据

    * 拿assets下的json文件

    */

    private void initData()

StringBuilder jsonSB =new StringBuilder();

        try

BufferedReader addressJsonStream =new BufferedReader(new InputStreamReader(mContext.getAssets().open("address.json")));

            String line;

            while ((line = addressJsonStream.readLine()) !=null)

jsonSB.append(line);

           

catch (IOException e)

e.printStackTrace();

       

// 将数据转换为对象

        mYwpAddressBean =new Gson().fromJson(jsonSB.toString(), YwpAddressBean.class);

        if (mYwpAddressBean !=null)

mRvData.clear();

            mRvData.addAll(mYwpAddressBean.getProvince());

            mAdapter.notifyDataSetChanged();

       



/**

    * 开放给外部传入数据

    * 暂时就用这个Bean模型,如果数据不一致就需要各自根据数据来生成这个bean了

    */

    public void initData(YwpAddressBean bean)

if (bean !=null)

mSelectDistrict =null;

            mSelectCity =null;

            mSelectProvice =null;

            mTabLayout.getTabAt(0).select();

            mYwpAddressBean = bean;

            mRvData.clear();

            mRvData.addAll(mYwpAddressBean.getProvince());

            mAdapter.notifyDataSetChanged();

       



//点确定

    private void sure()

if (mSelectProvice !=null &&

mSelectCity !=null &&

mSelectDistrict !=null)

//  回调接口

            if (mOnAddressPickerSureListener !=null)

mOnAddressPickerSureListener.onSureClick(mSelectProvice.getN(), mSelectCity.getN(), mSelectDistrict.getN());

           

else

Toast.makeText(mContext, "地址还没有选完整哦", Toast.LENGTH_SHORT).show();

       



@Override

    protected void onDetachedFromWindow()

super.onDetachedFromWindow();

      // mYwpAddressBean = null;

   

/**

    * TabLayout 切换事件

    */

    TabLayout.OnTabSelectedListenertabSelectedListener =new TabLayout.OnTabSelectedListener()

@Override

        public void onTabSelected(TabLayout.Tab tab)

mRvData.clear();

            switch (tab.getPosition())

case 0:

mRvData.addAll(mYwpAddressBean.getProvince());

                    mAdapter.notifyDataSetChanged();

                    // 滚动到这个位置

                    mRvList.smoothScrollToPosition(mSelectProvicePosition);

break;

                case 1:

// 点到城市的时候要判断有没有选择省份

                    if (mSelectProvice !=null)

for (YwpAddressBean.AddressItemBean itemBean :mYwpAddressBean.getCity())

if (itemBean.getP().equals(mSelectProvice.getI()))

mRvData.add(itemBean);

                       

else

Toast.makeText(mContext, "请您先选择省份", Toast.LENGTH_SHORT).show();

                   

mAdapter.notifyDataSetChanged();

                    // 滚动到这个位置

                    mRvList.smoothScrollToPosition(mSelectCityPosition);

break;

                case 2:

// 点到区的时候要判断有没有选择省份与城市

                    if (mSelectProvice !=null &&mSelectCity !=null)

for (YwpAddressBean.AddressItemBean itemBean :mYwpAddressBean.getDistrict())

if (itemBean.getP().equals(mSelectCity.getI()))

mRvData.add(itemBean);

                       

else

Toast.makeText(mContext, "请您先选择省份与城市", Toast.LENGTH_SHORT).show();

                   

mAdapter.notifyDataSetChanged();

                    // 滚动到这个位置

                    mRvList.smoothScrollToPosition(mSelectDistrictPosition);

break;

           



@Override

        public void onTabUnselected(TabLayout.Tab tab)



@Override

        public void onTabReselected(TabLayout.Tab tab)



;

    /**

    * 下面显示数据的adapter

*/

    class AddressAdapterextends RecyclerView.Adapter

@Override

        public ViewHolderonCreateViewHolder(ViewGroup parent, int viewType)

return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_address_text, parent, false));

       

@Override

        public void onBindViewHolder(final ViewHolder holder, final int position)

final int tabSelectPosition =mTabLayout.getSelectedTabPosition();

            holder.mTitle.setText(mRvData.get(position).getN());

            holder.mTitle.setTextColor(defaultUnSelectedColor);

            // 设置选中效果的颜色

            switch (tabSelectPosition)

case 0:

if (mRvData.get(position) !=null &&

mSelectProvice !=null &&

mRvData.get(position).getI().equals(mSelectProvice.getI()))

holder.mTitle.setTextColor(defaultSelectedColor);

                   

break;

                case 1:

if (mRvData.get(position) !=null &&

mSelectCity !=null &&

mRvData.get(position).getI().equals(mSelectCity.getI()))

holder.mTitle.setTextColor(defaultSelectedColor);

                   

break;

                case 2:

if (mRvData.get(position) !=null &&

mSelectDistrict !=null &&

mRvData.get(position).getI().equals(mSelectDistrict.getI()))

holder.mTitle.setTextColor(defaultSelectedColor);

                   

break;

           

// 设置点击之后的事件

            holder.mTitle.setOnClickListener(new OnClickListener()

@Override

                public void onClick(View v)

// 点击 分类别

                    switch (tabSelectPosition)

case 0:

mSelectProvice =mRvData.get(position);

                            // 清空后面两个的数据

                            mSelectCity =null;

                            mSelectDistrict =null;

                            mSelectCityPosition =0;

                            mSelectDistrictPosition =0;

                            mTabLayout.getTabAt(1).setText(defaultCity);

                            mTabLayout.getTabAt(2).setText(defaultDistrict);

                            // 设置这个对应的标题

                            mTabLayout.getTabAt(0).setText(mSelectProvice.getN());

                            // 跳到下一个选择

                            mTabLayout.getTabAt(1).select();

                            mSelectProvicePosition =position;

break;

                        case 1:

mSelectCity =mRvData.get(position);

                            // 清空后面一个的数据

                            mSelectDistrict =null;

                            mSelectDistrictPosition =0;

                            mTabLayout.getTabAt(2).setText(defaultDistrict);

                            // 设置这个对应的标题

                            mTabLayout.getTabAt(1).setText(mSelectCity.getN());

                            // 跳到下一个选择

                            mTabLayout.getTabAt(2).select();

                            mSelectCityPosition =position;

break;

                        case 2:

mSelectDistrict =mRvData.get(position);

                            // 没了,选完了,这个时候可以点确定了

                            mTabLayout.getTabAt(2).setText(mSelectDistrict.getN());

                            notifyDataSetChanged();

                            mSelectDistrictPosition =position;

                            sure();

break;

                   



);

       

@Override

        public int getItemCount()

return mRvData.size();

       

class ViewHolderextends RecyclerView.ViewHolder

TextViewmTitle;

            ViewHolder(View itemView)

super(itemView);

                mTitle = (TextView) itemView.findViewById(R.id.itemTvTitle);

           





/**

    * 点确定回调这个接口

    */

    public interface OnAddressPickerSureListener

void onSureClick(String proviceName,String cityName,String earaName);

   

public void setOnAddressPickerSure(OnAddressPickerSureListener listener)

this.mOnAddressPickerSureListener = listener;

   

MUI仿京东App地址选择器

才学JS不久,刚好项目需要一个京东地址选择器,所以尝试着写了一个,dom获取较为复杂,纯粹使用自己了解到的东西

技术图片

依赖

//css是用rem写的
<script src="js/app.js" type="text/javascript" charset="utf-8"></script>
<script src="js/mui.min.js" type="text/javascript" charset="utf-8"></script>
//mui提供的城市js
<script src="js/city.data-3.js" type="text/javascript" charset="utf-8"></script>

HTML

<div id="addSelect" class="mui-popover mui-popover-bottom mui-popover-action">
    <div id="slider" class="mui-slider">
        <div id="sliderSegmentedControl" class="mui-slider-indicator mui-segmented-control mui-segmented-control-inverted">
            <div class="select-head">
                <ul class="select-nav mui-clearfix" id="selectNav">
                    <li>请选择</li>
                    <li class="mui-hidden">请选择</li>
                    <li class="mui-hidden">请选择</li>
                </ul>
                <a id="addressBtn">确定</a>
            </div>
        </div>
        <div class="mui-slider-group select-con" id="selectCon">
            <div id="item1" class="mui-slider-item mui-control-content mui-active">
                <div id="scroll1" class="mui-scroll-wrapper">
                    <div class="mui-scroll">
                        <ul id="select-con-1">
                        </ul>
                    </div>
                </div>
            </div>
            <div id="item2" class="mui-slider-item mui-control-content">
                <div id="scroll2" class="mui-scroll-wrapper">
                    <div class="mui-scroll">
                        <ul id="select-con-2">
                        </ul>
                    </div>
                </div>
            </div>
            <div id="item3" class="mui-slider-item mui-control-content">
                <div id="scroll3" class="mui-scroll-wrapper">
                    <div class="mui-scroll">
                        <ul id="select-con-3">
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>


<div class="mui-content">
    <div class="box" style="margin: 30px 20px;">
           <a id="address">地址</a>
        </div>
</div>

页面内JS

mui.init();
mui(‘.mui-scroll-wrapper‘).scroll({
    scrollY: true, //是否竖向滚动
    bounce: true //是否启用回弹
});


var p = ‘‘;  //文字
var num = ‘‘;  //value值

var address = document.getElementById(‘address‘)
address.addEventListener(‘tap‘,function(){
    mui(‘#addSelect‘).popover(‘show‘);
    addS();
})
function giveValue(){
    address.innerHTML = p;
    mui(‘#addSelect‘).popover(‘hide‘);
    console.log(p);
    console.log(num);
}

调用函数

function addS(){
    
    
    var slider = mui(‘#slider‘).slider();
    var selectNav = document.getElementById(‘selectNav‘);
    var selectNavLi = selectNav.getElementsByTagName(‘li‘);
    var oneUl = document.getElementById(‘select-con-1‘);
    var twoUl = document.getElementById(‘select-con-2‘);
    var threeUl = document.getElementById(‘select-con-3‘);
    var item1 = document.getElementById(‘item1‘);
    var item2 = document.getElementById(‘item2‘);
    var item3 = document.getElementById(‘item3‘);
    var index1 , index2 , index3;
    for( i=0 ; i<cityData3.length ; i++){
        var li = document.createElement("li");
        li.setAttribute(‘value‘,cityData3[i].value);
        li.innerHTML = cityData3[i].text;
        oneUl.appendChild(li)
    }
    
    var OneLi = oneUl.getElementsByTagName(‘li‘);
    for( i=0 ; i<OneLi.length ; i++){
        var a = OneLi[i];
        a.index = i;
        a.addEventListener(‘tap‘,function(){
            //清空第二个ul
            twoUl.innerHTML = ‘‘;
            selectNavLi[1].innerText = ‘请选择‘;
            selectNavLi[2].classList.add(‘mui-hidden‘);
            //获取下标和切换显示
            index1 = this.index;
            for(var i = 0; i < OneLi.length ; i++){
                OneLi[i].classList.remove(‘active‘);
            }
            this.classList.add(‘active‘);
            selectNavLi[0].innerText = this.innerText;
            selectNavLi[0].classList.add(‘active‘);
            selectNavLi[1].classList.remove(‘mui-hidden‘);
            //创建li并向第二个ul赋值
            var children = cityData3[index1].children;
            for( i=0 ; i<children.length ; i++){
                var li = document.createElement("li");
                li.setAttribute(‘value‘,children[i].value);
                li.innerHTML = children[i].text;
                twoUl.appendChild(li);
            }
            //显示第二个
            item2.classList.remove(‘mui-hidden‘);
            selectNavLi[1].classList.remove(‘active‘);
            slider.gotoItem(1,300);
            slider.stopped = false; //开启滑动切换
            
            var twoLi = twoUl.getElementsByTagName(‘li‘);
            for( i=0 ; i<twoLi.length ; i++){
                var a = twoLi[i];
                a.index = i;
                a.addEventListener(‘tap‘,function(){
                    //清空第二个ul
                    threeUl.innerHTML = ‘‘;
                    //获取下标和切换显示
                    index2 = this.index;
                    for(var i = 0; i < twoLi.length ; i++){
                        twoLi[i].classList.remove(‘active‘);
                    }
                    this.classList.add(‘active‘);
                    selectNavLi[1].innerText = this.innerText;
                    selectNavLi[1].classList.add(‘active‘);
                    selectNavLi[2].classList.remove(‘mui-hidden‘);
                    //创建li并向第二个ul赋值
                    var children = cityData3[index1].children[index2].children;
                    for( i=0 ; i<children.length ; i++){
                        var li = document.createElement("li");
                        li.setAttribute(‘value‘,children[i].value);
                        li.innerHTML = children[i].text;
                        threeUl.appendChild(li);
                    }
                    //显示第三个
                    item3.classList.remove(‘mui-hidden‘);
                    slider.gotoItem(2,300);
                    
                    var threeLi = threeUl.getElementsByTagName(‘li‘);
                    for( i=0 ; i<threeLi.length ; i++){
                        var a = threeLi[i];
                        a.index = i;
                        a.addEventListener(‘tap‘,function(){
                            for(var i = 0; i < threeLi.length ; i++){
                                threeLi[i].classList.remove(‘active‘);
                            }
                            this.classList.add(‘active‘);
                        })
                    }
                })
            }
        })
    }
    
    
    //导航点击事件
    selectNavLi[0].addEventListener(‘tap‘,function(){
        slider.gotoItem(0,300);
    })
    selectNavLi[1].addEventListener(‘tap‘,function(){
        slider.gotoItem(1,300);
    })
    selectNavLi[2].addEventListener(‘tap‘,function(){
        slider.gotoItem(2,300);
    })
    
    //提交
    document.getElementById(‘addressBtn‘).addEventListener(‘tap‘,function(){
        p = ‘‘;
        num = ‘‘;
        var active = document.getElementsByClassName(‘select-con‘)[0].getElementsByClassName(‘active‘);
        if(active.length == 0){
            return;
        }else{
            var threeLi = threeUl.getElementsByClassName(‘active‘).length;
            for(i=0 ; i<active.length ; i++){
                var value = active[i].getAttribute(‘value‘);
                var text = active[i].innerText;
                if(i==0){
                    num += value;
                }else{
                    num += ‘,‘+value;
                }
                if(threeLi>1){
                    p = active[0].innerText + active[1].innerText + ‘多个区域‘;
                }else{
                    p += text;
                }
            }
        }
        
        
//        赋值
        giveValue();
    })
}

css

ul,li{
    margin: 0;
    padding: 0;
    list-style: none;
}

.mui-popover{
    height: 5rem;
    background-color: #fff !important;
}
.mui-slider-group{
    height: 4.42rem !important;
}
.mui-slider-item{
    border: none !important;
}
.select-head{
    position: relative;
    display: flex;
    justify-content: space-between;
    padding: 0 0.26rem;
    width: 100%;
    height: 0.58rem;
}
.select-head:after{
    content: ‘‘;
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 1px;
    background-color: #e5e5e5;
    transform: scaleY(.5);
}
.select-head ul{
    flex: 1;
}
.select-head ul li{
    position: relative;
    float: left;
    margin-right: 0.24rem;
    font-size: 0.186rem;
    color: #333;
    line-height: 0.58rem;
    color: #CE3D3A;
}
.select-head ul li.active{
    color: #333;
}
.select-head ul li.active:after{
    height: 0;
}
.select-head ul li:after{
    content: ‘‘;
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 2px;
    background-color: #CE3D3A;
}
.select-head a{
    float: right;
    border: none;
    font-size: 0.186rem;
    line-height: 0.58rem;
}
.select-con{
    position: relative;
}
.select-con .mui-scroll-wrapper{
    margin: 0;
    height: 4.42rem;
}
.select-con .mui-scroll-wrapper ul{
    padding: 0.1rem 0;
}
.select-con .mui-scroll-wrapper li{
    padding: 0 0.26rem;
    line-height: 0.58rem;
    font-size: 0.186rem;
    color: #333;
}
.select-con .mui-scroll-wrapper li.active{
    color: #CE3D3A;
}

本文转载于:猿2048https://www.mk2048.com/blog/blog.php?id=h1bhi2i1kab

以上是关于Android 自定义仿京东地址选择器的主要内容,如果未能解决你的问题,请参考以下文章

Android之仿京东淘宝的自动无限轮播控件

flowable设计器自定义自己的人员选择器

LayUI laydate日期选择器自定义 快捷选中今天昨天 本周本月等等

LayUI laydate日期选择器自定义 快捷选中今天昨天 本周本月等等

Xamarin Forms Shell 如何使用自定义渲染器自定义选项卡

iOS个人中心渐变动画微信对话框标签选择器自定义导航栏短信验证输入框等源码