利用ViewPage实现-->三级地址列表展 --><贡献服务端源码>

本文介绍了一个使用ViewPager实现的地址选择器应用,通过懒加载优化界面显示,并实现了指示线跟随页面滑动的功能。提供了完整的实现思路及关键代码。

最近ViewPager写多了。看到某宝的地址选择界面,不由得就有了使用ViewPager展示地址列表的想法来。

  • 完成了基本功能,自己简单封装了HttpUrlConnection进行网络访问,项目运用请使用改用三方工具
  • 自己写的服务器,请求字段的要求参考压缩包文档,(不建议修改字段,否则改动较大,不如自己写)
  • 暂时没有发现严重BUG. 都是用些基础的东西,想要更炫的效果,可以自己包装下

三方资源: LazyViewPager 、GSON

注意:本地资源并不全面,只供展示界面效果。

设计思想:
  1. 当全部地址列表页面展示出来后,再次点击销毁 ‘ 区 ’ 界面,杜绝地址信息不匹配的BUG

  2. 使用LazyViewPager 懒加载功能,解决界面销毁,缓存遗留,滑动可见BUG

效果图:

这里写图片描述


布局比较简单,就不贴源码了。 由于复用了列表展示的page页面,逻辑上处理有些麻烦。解析的bean对象也是复用的,限制了服务端的字段类型。

  • 下面是指示线的位移逻辑,以及页面改变时修改TYPE(地址类型)。
  • 通过ViewPager.OnPageChangeListener 实现。
/**
 * 界面改变事件监听
 *  TYPE: 1=市, 2=区、县, other=省 
 */
private LazyViewPager.OnPageChangeListener dealOnPagerChangeListener = new LazyViewPager.OnPageChangeListener() {
    /** 滑动中 */
    @Override
    public void onPageScrolled(int position, float positionOffset
            , int positionOffsetPixels) {
        float disX = positionOffset * lineWidth;//获取滑动的距离
        float startX = disX + position * lineWidth;//获取指示线起始位置
        indicate_line.setTranslationX(startX);//设置位移动画
    }
    /** 当页面改变后 */
    @Override
    public void onPageSelected(int position) {
        TYPE = position + 1;  //这里更改TYPE的值需要TYPE初值=1.否则将不能触发页面改变监听
        int bule = getResources().getColor(R.color.colorPrimary);
        int accent = getResources().getColor(R.color.colorAccent);
        tv_province.setTextColor(position==0 ? accent : bule); //字体颜色选择
        tv_city.setTextColor(position==1 ? accent : bule);
        tv_area.setTextColor(position==2 ? accent : bule);
    }
    @Override
    public void onPageScrollStateChanged(int state) {}
};
  • 公用的解析方法。这是本地资源的解析方法,网络资源的解析,多加了响应结果字段的判断。 这个代码短些,就贴这个了
  • 本来也想把这部分抽出个公共方法的,无奈,脑细胞有限,尝试了几次并没什么进展,由于复用的bean,page页面。
//TODO 本地资源获取,联网可删除
    private void insertAssets(final String fileName){
        new Thread(){
            @Override
            public void run() {
                try {
                    InputStream inputStream = getAssets().open(fileName);
                    final String stringFromStream = StreamUtils.getStringFromStream(inputStream);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            parseAssetsJson(stringFromStream);
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
  /**
     * json解析本地
     * @param json
     *///TODO 本地资源获取,联网可删除
    protected void parseAssetsJson(String json) {
        try {
                Gson gson = new Gson();  //解析
                AreaJsonBean address = gson.fromJson(json, AreaJsonBean.class);
//分割线>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                if(address.province != null){  //加载 省列表Fragment
                    ArrayList<AddressArea> provinces = address.province;
                    Log.e("province====", provinces.toString());
                    if(pagers.size() == 0){
                        pagers.add(mProvince);
                    }else {
                        mProvince = pagers.get(0);
                    }
                    mProvince.setData(provinces);//设置数据
                    initLineWidth();//刷新viewPager适配器
                    mProvince.setOnItemClick(dealOnItemClickLdistener);
                    area_viewpager.setCurrentItem(0);
                }
//分割线>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                if(address.city != null){  //加载市列表Fragment
                    ArrayList<AddressArea> citys = address.city;
                    if(pagers.size() == 1){
                        pagers.add(mCity);
                    }else{
                        mCity = pagers.get(1);
                    }
                    mCity.setData(citys); //设置数据
                    initLineWidth();//刷新viewPager适配器
                    mCity.setOnItemClick(dealOnItemClickLdistener);
                    area_viewpager.setCurrentItem(1);
                }
//分割线>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                if(address.area != null){
                    ArrayList<AreaJsonBean.AddressArea> aeras = address.area;
                    if(pagers.size() == 2){
                        pagers.add(mArea);
                    }else{
                        mArea = pagers.get(2);
                    }
                    mArea.setData(aeras); //填充数据
                    initLineWidth();//刷新viewPager适配器
                    mArea.setOnItemClick(dealOnItemClickLdistener);
                    area_viewpager.setCurrentItem(2);
                }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • 自己重定义的OnItemClickLestener 方便获取条目信息,记录信息是根据请求类型分别记录 省 市 区
    /**
     * 处理地址列表条目点击事件
     */
    private AreaPager.DealOnItemClickListener dealOnItemClickLdistener = new AreaPager.DealOnItemClickListener() {
        @Override
        public void dealOnItemClickListener(List areaList, int position) {
            AddressArea addressArea = (AddressArea) areaList.get(position);
            switchRecord(addressArea); //选择记录地址信息
//            requestNet(addressArea.areaID);  //开启子线程,获取网络数据 //TODO 联网开启
            /** TYPE: 1=市, 2=区、县, other=省 */
        }
    };
为什么这个页面按f5会出现确认重新提交表单?<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/LkmTemplate.jsf"> <ui:param name="pageTitle" value="转序效率分析"/> <ui:define name="head"> <h:outputScript name="js/highchart3.6/event-highcharts.js" target="body"/> <h:outputScript name="js/event-exporting.js" target="body"/> </ui:define> <ui:define name="content-introduction"> <h1>转序效率分析</h1> </ui:define> <ui:define name="content"> <div class="ui-fluid"> <div id="contentId"> <div style="display: flex; justify-content: flex-start; align-items: flex-start;"> <!-- 左侧查询条件区域 --> <div style="margin-right: 20px;"> <p:panel> <div class="ui-inputgroup" style="display:inline-block;"> <span class="ui-inputgroup-addon" style="width:55px">组织</span> <p:selectOneMenu id="org" value="#{zhuanXuReportBean.org}" style="width:80px"> <f:selectItem itemLabel="河源" itemValue="河源"/> <f:selectItem itemLabel="杭州" itemValue="杭州"/> </p:selectOneMenu> </div> <p:spacer width="10px"/> <div class="ui-inputgroup" style="display:inline-block;"> <span class="ui-inputgroup-addon" style="width:55px;">类型</span> <p:selectOneMenu id="eventType" value="#{zhuanXuReportBean.eventType}" style="width:110px;" panelStyle="width:180px;"> <f:selectItem itemLabel="转序" itemValue="转序"/> <f:selectItems value="#{zhuanXuReportBean.typeList}"/> </p:selectOneMenu> </div> <p:spacer width="10px"/> <div class="ui-inputgroup" style="display:inline-block;"> <span class="ui-inputgroup-addon" style="width:55px">厂房</span> <p:selectOneMenu id="selectFactory" value="#{zhuanXuReportBean.selectFactory}" style="width:80px"> <f:selectItem itemLabel="选择厂房"/> <f:selectItem itemLabel="1#厂" itemValue="1#厂"/> <f:selectItem itemLabel="5#厂" itemValue="5#厂"/> <f:selectItem itemLabel="6#厂" itemValue="6#厂"/> <f:selectItem itemLabel="7#厂" itemValue="7#厂"/> <f:selectItem itemLabel="8#厂" itemValue="8#厂"/> <f:selectItem itemLabel="12#厂" itemValue="12#厂"/> <f:selectItem itemLabel="20#厂" itemValue="20#厂"/> </p:selectOneMenu> </div> <p:spacer width="5px" height="10px"/> <div class="ui-inputgroup" style="display:inline-block;"> <span class="ui-inputgroup-addon">统计始 </span> <p:calendar id="startDate" pattern="yyyy-MM-dd" value="#{zhuanXuReportBean.startDate}" inputStyle="width:90px"></p:calendar> </div> <p:spacer width="5px" height="10px"/> <div class="ui-inputgroup" style="display:inline-block;"> <span class="ui-inputgroup-addon">统计止 </span> <p:calendar id="endDate" pattern="yyyy-MM-dd" value="#{zhuanXuReportBean.endDate}" inputStyle="width:90px"></p:calendar> </div> <p:spacer width="5px" height="10px"/> <h:commandButton id="searchBtn" class="searchBtn" actionListener="#{zhuanXuReportBean.doSearch}" oncomplete="updateChart()" icon="fa fa-search" value="查询" update="dataTableId" style="width:80px;height:33px;background-color:#007ad9;border: 1px solid #007ad9;color: #ffffff;"/> </p:panel> </div> </div> </div> </div> <div style="display: flex; align-items: flex-start;"> <div id="chartData" class="chartData" style="height:400px;width: 50%;"> <h:outputScript> document.addEventListener('DOMContentLoaded', function () { var chart1; var categories = #{zhuanXuReportBean.categoriesStr}; var salesData = #{zhuanXuReportBean.salesDataStr}; var eventType = '#{zhuanXuReportBean.eventType!=""?zhuanXuReportBean.eventType:"转序效率"}'; chart1 = new Highcharts.Chart({ chart: { renderTo: 'chartData', type: 'column' }, title: { text: eventType + '分析(件数)', x: -20 //center }, xAxis: { categories: eval(categories) }, yAxis: { title: { text: eventType + '分析(件数)', }, min: 0, plotLines: [{ value: 0, width: 1, color: '#808080' }] }, tooltip: { crosshairs: true, valueSuffix: '', shared: true }, plotOptions: { column: { pointPadding: 0.2, borderWidth: 0 } }, series: eval(salesData) }); // 更新图表数据 function updateChart() { var newCategories = #{engWojiaBean.categoriesStr}; var salesData = #{engWojiaBean.salesDataStr}; chart1.xAxis[0].setCategories(newCategories); chart1.series[0].setData(salesData); var series = chart1.series; series[1].hide(); series[2].hide(); series[5].hide(); } }); </h:outputScript> </div> <!-- 右侧表格区域 --> <div style="width: 27%;margin-left: 20px; margin-top: 0;"> <p:dataTable id="dataTableId" widgetVar="dataTableId" emptyMessage="没有找到相关记录" value="#{zhuanXuReportBean.lazyEventDataList}" var="zx" styleClass="data-table fixed-layout-table" style="width:100%;" paginator="true" rows="10" paginatorPosition="bottom" rowsPerPageTemplate="10,20,30" lazy="true" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"> <p:columnGroup type="header"> <!-- 第一行表头 --> <p:row> <!-- 姓名列,跨两行 --> <p:column rowspan="2" headerText="操作员" style="text-align:center;width:30px"/> <!-- 时间跨度列,跨两行 --> <p:column rowspan="2" headerText="时间跨度" style="text-align:center;width:25px"/> <!-- 转序数量列,跨两列(即合并后面的两个列),只占一行 --> <p:column colspan="2" headerText="转序数量" style="text-align:center; width:20px;"/> <!-- 操作列,跨两行 --> <p:column rowspan="2" headerText="操作" style="text-align:center;width:10px"/> </p:row> <!-- 第二行表头:只需要显示转序数量下面的两个子列 --> <p:row> <!-- 正常列 --> <p:column headerText="正常" style="text-align:center; width:10px;"/> <!-- 超时列 --> <p:column headerText="超时" style="text-align:center; width:10px;"/> </p:row> </p:columnGroup> <!-- 数据列部分:注意顺序必须与表头中列的顺序一致,且数量对应 --> <!-- 姓名工号列 --> <p:column style="text-align:center;width:30px"> <h:outputText value="#{zx.name}" styleClass="ellipsis-text"/> </p:column> <!-- 时间跨度列 --> <p:column style="text-align:center;width:30px"> <h:outputText value="#{zhuanXuReportBean.searchDate}" styleClass="ellipsis-text"/> </p:column> <!-- 正常列(属于转序数量下) --> <p:column style="text-align:center; width:10px;"> <h:outputText value="#{zx.normalCount}" styleClass="ellipsis-text"/> </p:column> <!-- 超时列(属于转序数量下) --> <p:column style="text-align:center; width:10px;"> <h:outputText value="#{zx.timeOutCount}" styleClass="ellipsis-text"/> </p:column> <!-- 操作列 --> <p:column style="text-align:center;width:10px"> <p:commandLink value="查看明细" actionListener="#{zhuanXuReportBean.openEventDataDialog(zx)}" oncomplete="PF('zhuanXuDetail').show();" update="@(.detail-style)" styleClass="centered-link"/> </p:column> </p:dataTable> </div> </div> </ui:define> </ui:composition>
最新发布
08-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值