效果动图:

(后面补上)

总体布局:

<?xml version="1.0" encoding="utf-8"?>                        

Fragment中实现:

listCitylist = (ListView) mView.findViewById(R.id.list_citylist);listCitylist.addHeaderView(headerView);listCitylist.setOnScrollListener(onScrollListener);
/** * 城市列表适配 */    private void setCityListAdapter() {        if (null == cityListAdapter) {            cityListAdapter = new CityListAdapter(getActivity(), cityListDatas);            listCitylist.setAdapter(cityListAdapter);        }else {            //第二次进入城市列表的时候,list和adapter实例还在,但是list和adapter失去关联,所以要重新绑定            listCitylist.setAdapter(cityListAdapter);            cityListAdapter.updateData(cityListDatas);        }        cityListAdapter.setOnCityListClickListener(onCityListItemClickListener);        zMIndex = cityListAdapter.getzMIndexs();        letter.bringToFront();    }
/** * 城市列表点击事件 */    private CityListAdapter.OnCityListItemClickListener onCityListItemClickListener = new CityListAdapter.OnCityListItemClickListener() {        @Override        public void onCityListClickListener(View v) {            CityInfo c = (CityInfo) v.getTag();            ((CommunityManagerActivityNew)getActivity()).formCityListToSelectComm(c.name, c.code);        }    };
 /**     * 城市列表滑动监听,控制字母吸顶     */    AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {        @Override        public void onScrollStateChanged(AbsListView view, int scrollState) {            switch (scrollState) {                case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL://拖动                case AbsListView.OnScrollListener.SCROLL_STATE_FLING://惯性滑动                    // 显示滑动时屏幕可见条目中离标题栏最近的第一行                    int position = listCitylist.getFirstVisiblePosition();                    //由于listview添加了一个header,所以position=0代表的是header                    //这里获取到的position和下面onscroll方法里的firstVisibleItem值一致                    break;                case AbsListView.OnScrollListener.SCROLL_STATE_IDLE://手指离开或者惯性滑动停止                    break;            }        }        @Override        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {            if (firstVisibleItem > 0) {                topTitle.setVisibility(View.VISIBLE);                topTitle.bringToFront();                if(firstVisibleItem >= zMIndex[25] + 1 && zMIndex[25] != 0) {                    topTitle.setText(letters[25]);                }else if(firstVisibleItem >= zMIndex[24] + 1 && zMIndex[24] != 0) {                    topTitle.setText(letters[24]);                }else if(firstVisibleItem >= zMIndex[23] + 1 && zMIndex[23] != 0) {                    topTitle.setText(letters[23]);                }else if(firstVisibleItem >= zMIndex[22] + 1 && zMIndex[22] != 0) {                    topTitle.setText(letters[22]);                }else if(firstVisibleItem >= zMIndex[21] + 1 && zMIndex[21] != 0) {                    topTitle.setText(letters[21]);                }else if(firstVisibleItem >= zMIndex[20] + 1 && zMIndex[20] != 0) {                    topTitle.setText(letters[20]);                }else if(firstVisibleItem >= zMIndex[19] + 1 && zMIndex[19] != 0) {                    topTitle.setText(letters[19]);                }else if(firstVisibleItem >= zMIndex[18] + 1 && zMIndex[18] != 0) {                    topTitle.setText(letters[18]);                }else if(firstVisibleItem >= zMIndex[17] + 1 && zMIndex[17] != 0) {                    topTitle.setText(letters[17]);                }else if(firstVisibleItem >= zMIndex[16] + 1 && zMIndex[16] != 0) {                    topTitle.setText(letters[16]);                }else if(firstVisibleItem >= zMIndex[15] + 1 && zMIndex[15] != 0) {                    topTitle.setText(letters[15]);                }else if(firstVisibleItem >= zMIndex[14] + 1 && zMIndex[14] != 0) {                    topTitle.setText(letters[14]);                }else if(firstVisibleItem >= zMIndex[13] + 1 && zMIndex[13] != 0) {                    topTitle.setText(letters[13]);                }else if(firstVisibleItem >= zMIndex[12] + 1 && zMIndex[12] != 0) {                    topTitle.setText(letters[12]);                }else if(firstVisibleItem >= zMIndex[11] + 1 && zMIndex[11] != 0) {                    topTitle.setText(letters[11]);                }else if(firstVisibleItem >= zMIndex[10] + 1 && zMIndex[10] != 0) {                    topTitle.setText(letters[10]);                }else if(firstVisibleItem >= zMIndex[9] + 1 && zMIndex[9] != 0) {                    topTitle.setText(letters[9]);                }else if(firstVisibleItem >= zMIndex[8] + 1 && zMIndex[8] != 0) {                    topTitle.setText(letters[8]);                }else if(firstVisibleItem >= zMIndex[7] + 1 && zMIndex[7] != 0) {                    topTitle.setText(letters[7]);                }else if(firstVisibleItem >= zMIndex[6] + 1 && zMIndex[6] != 0) {                    topTitle.setText(letters[6]);                }else if(firstVisibleItem >= zMIndex[5] + 1 && zMIndex[5] != 0) {                    topTitle.setText(letters[5]);                }else if(firstVisibleItem >= zMIndex[4] + 1 && zMIndex[4] != 0) {                    topTitle.setText(letters[4]);                }else if(firstVisibleItem >= zMIndex[3] + 1 && zMIndex[3] != 0) {                    topTitle.setText(letters[3]);                }else if(firstVisibleItem >= zMIndex[2] + 1 && zMIndex[2] != 0) {                    topTitle.setText(letters[2]);                }else if(firstVisibleItem >= zMIndex[1] + 1 && zMIndex[1] != 0) {                    topTitle.setText(letters[1]);                }else if(firstVisibleItem >= zMIndex[0] + 1) {                    topTitle.setText(letters[0]);                }            } else {                topTitle.setVisibility(View.GONE);            }        }    };

 城市实体类:

/** * Created by Luzj on 2018/8/23. * 城市列表item */public class CityInfo implements Serializable,Comparable {    /**     * 省市区标识     */    public int regionId;    /**     * 层级:0级为省、1级为市、2级为区     */    public int level;    /**     * 城市名称     */    public String name;    /**     * 拼音简称     */    public String pySname;    /**     * 编码     */    public String code;    /**     * 状态:0是无效,1是有效     */    public int status;    /**     * item类型:0为字母,1为城市带下黑线,2为城市不带下黑线     */    public int infoType;    @Override    public int compareTo(@NonNull CityInfo o) {        CityInfo cityInfo = o;        return this.pySname.compareTo(o.pySname);    }}

附加Adapter(因城市列表数据给的是单独无序的一个列表,没有做字母排序,更没有用字母分字列表,所以拿到数据之后还要做按字母排序、分字母):

/** * Created by Luzj on 2018/8/23. */public class CityListAdapter extends BaseAdapter {    private Context context;    /**     * 接口返回数据     */    private List datas;    /**     * 接口数据加上字母     */    private ArrayList allDatas = new ArrayList<>();    /**     * item type,0为字母,1为带下黑线,2不带下黑线     */    private final int ZIMU = 0, ITEM_LINE = 1, ITEM_NOLINE = 2;    /**     * 字母所带列表     */    private ArrayList aL = new ArrayList<>();    private ArrayList bL = new ArrayList<>();    private ArrayList cL = new ArrayList<>();    private ArrayList dL = new ArrayList<>();    private ArrayList eL = new ArrayList<>();    private ArrayList fL = new ArrayList<>();    private ArrayList gL = new ArrayList<>();    private ArrayList hL = new ArrayList<>();    private ArrayList iL = new ArrayList<>();    private ArrayList jL = new ArrayList<>();    private ArrayList kL = new ArrayList<>();    private ArrayList lL = new ArrayList<>();    private ArrayList mL = new ArrayList<>();    private ArrayList nL = new ArrayList<>();    private ArrayList oL = new ArrayList<>();    private ArrayList pL = new ArrayList<>();    private ArrayList qL = new ArrayList<>();    private ArrayList rL = new ArrayList<>();    private ArrayList sL = new ArrayList<>();    private ArrayList tL = new ArrayList<>();    private ArrayList uL = new ArrayList<>();    private ArrayList vL = new ArrayList<>();    private ArrayList wL = new ArrayList<>();    private ArrayList xL = new ArrayList<>();    private ArrayList yL = new ArrayList<>();    private ArrayList zL = new ArrayList<>();    private static final String[] letters = {"A","B","C","D","E","F","G","H","I","J","K","L"            ,"M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};    /**     * 总列表,每个元素都是一个字母列表     */    private ArrayList zMList = new ArrayList<>();    /**     * 字母下标位置数组     */    private int[] zMIndexs = new int[26];    public CityListAdapter(Context context, List datas) {        this.context = context;        this.datas = datas;        if(null != datas && datas.size() >= 0) {            initDatas();        }    }    private void initDatas() {        String firstChar;        StringBuffer sb;        //城市数据按照字母排序        Collections.sort(datas);        //获取每个城市首字母进行归类        for(int i = 0; i < datas.size(); i++) {            CityInfo c = datas.get(i);            sb = new StringBuffer(c.pySname);            firstChar = sb.delete(1, sb.length()).toString();            if("a".equals(firstChar)) {                aL.add(c);            }else if("b".equals(firstChar)) {                bL.add(c);            }else if("c".equals(firstChar)) {                cL.add(c);            }else if("d".equals(firstChar)) {                dL.add(c);            }else if("e".equals(firstChar)) {                eL.add(c);            }else if("f".equals(firstChar)) {                fL.add(c);            }else if("g".equals(firstChar)) {                gL.add(c);            }else if("h".equals(firstChar)) {                hL.add(c);            }else if("i".equals(firstChar)) {                iL.add(c);            }else if("j".equals(firstChar)) {                jL.add(c);            }else if("k".equals(firstChar)) {                kL.add(c);            }else if("l".equals(firstChar)) {                lL.add(c);            }else if("m".equals(firstChar)) {                mL.add(c);            }else if("n".equals(firstChar)) {                nL.add(c);            }else if("o".equals(firstChar)) {                oL.add(c);            }else if("p".equals(firstChar)) {                pL.add(c);            }else if("q".equals(firstChar)) {                qL.add(c);            }else if("r".equals(firstChar)) {                rL.add(c);            }else if("s".equals(firstChar)) {                sL.add(c);            }else if("t".equals(firstChar)) {                tL.add(c);            }else if("u".equals(firstChar)) {                uL.add(c);            }else if("v".equals(firstChar)) {                vL.add(c);            }else if("w".equals(firstChar)) {                wL.add(c);            }else if("x".equals(firstChar)) {                xL.add(c);            }else if("y".equals(firstChar)) {                yL.add(c);            }else if("z".equals(firstChar)) {                zL.add(c);            }        }        //依次将字母列表顺序添加进总列表        zMList.add(aL); zMList.add(bL); zMList.add(cL); zMList.add(dL); zMList.add(eL);        zMList.add(fL); zMList.add(gL); zMList.add(hL); zMList.add(iL); zMList.add(jL); zMList.add(kL);        zMList.add(lL); zMList.add(mL); zMList.add(nL); zMList.add(oL); zMList.add(pL);        zMList.add(qL); zMList.add(rL); zMList.add(sL); zMList.add(tL); zMList.add(uL);        zMList.add(vL); zMList.add(wL); zMList.add(xL); zMList.add(yL); zMList.add(zL);        CityInfo cZiMu;        CityInfo c;        for(int i = 0; i < letters.length; i++) {            if(zMList.get(i).size() > 0) {                //每开始取一个字母列表,先添加进该字母                cZiMu = new CityInfo();                cZiMu.infoType = 0;                cZiMu.name = letters[i];                allDatas.add(cZiMu);                zMIndexs[i] = allDatas.indexOf(cZiMu);                for(int j = 0; j < zMList.get(i).size(); j++) {                    c = (CityInfo) zMList.get(i).get(j);                    if(j == (zMList.get(i).size() - 1)) {                        //当该城市是该字母列表最后一个时,取消下黑线                        c.infoType = 2;                    }else {                        c.infoType = 1;                    }                    allDatas.add(c);                }            }        }    }    /**     * @return 字母下标数组     */    public int[] getzMIndexs() {        return zMIndexs;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        int type = allDatas.get(position).infoType;        if(ZIMU == type) {            convertView = getZiMuView(position, convertView, parent);        }else {            convertView = getItemLineView(position, convertView, parent);        }        return convertView;    }    public void updateData(List datas) {        this.datas = datas;        notifyDataSetChanged();    }    private Map letterIndex = new HashMap<>();    private View getZiMuView(int position, View convertView, ViewGroup parent) {        ZiMuHolder zM;        if(null == convertView) {            convertView = LayoutInflater.from(context).inflate(R.layout.citylist_item0, null);            zM = new ZiMuHolder(convertView);            convertView.setTag(zM);        }else {            zM = (ZiMuHolder) convertView.getTag();        }        zM.citylistZm.setText(allDatas.get(position).name);        return convertView;    }    private View getItemLineView(int position, View convertView, ViewGroup parent) {        CityListItem1 c1;        if(null == convertView) {            convertView = LayoutInflater.from(context).inflate(R.layout.citylist_item1, parent, false);            c1 = new CityListItem1(convertView);            convertView.setTag(c1);        }else {            c1 = (CityListItem1) convertView.getTag();        }        c1.citylistItem1.setText(allDatas.get(position).name);        c1.citylistItem1.setTag(allDatas.get(position));        if(ITEM_LINE == allDatas.get(position).infoType) {            c1.line.setVisibility(View.VISIBLE);        }        return convertView;    }    @Override    public int getItemViewType(int position) {        CityInfo cityInfo = allDatas.get(position);        int type = cityInfo.infoType;        if(ZIMU == type) {            return ZIMU;        }else if(ITEM_LINE == type) {            return ITEM_LINE;        }else {            return ITEM_NOLINE;        }    }    @Override    public int getViewTypeCount() {        return 3;    }    @Override    public int getCount() {        return null == allDatas ? 0 : allDatas.size();    }    @Override    public Object getItem(int position) {        if(null == allDatas) {            return null;        }else {            return allDatas.get(position);        }    }    @Override    public long getItemId(int position) {        return position;    }    public List getAllDatas() {    return allDatas;}    class ZiMuHolder {        TextView citylistZm;        ZiMuHolder(View v) {            citylistZm = (TextView) v.findViewById(R.id.citylist_zm);        }    }    class CityListItem1 {        TextView citylistItem1;        View line;        CityListItem1(View v) {            citylistItem1 = (TextView) v.findViewById(R.id.citylist_item1);            citylistItem1.setOnClickListener(onClickListener);            line = v.findViewById(R.id.bottom_line);            line.setVisibility(View.GONE);        }    }    private View.OnClickListener onClickListener = new View.OnClickListener() {        @Override        public void onClick(View v) {            onCityListClickListener.onCityListClickListener(v);        }    };    private OnCityListItemClickListener onCityListClickListener;    public interface OnCityListItemClickListener {        void onCityListClickListener(View v);    }    public void setOnCityListClickListener(OnCityListItemClickListener listener) {        this.onCityListClickListener = listener;    }}

后台数据接口:

{    "code":"mock",                //类型:String  必有字段  备注:响应状态码 0成功、!=0 不成功    "message":"mock",                //类型:String  必有字段  备注:响应提示消息    "data": - {                //类型:Object  必有字段  备注:无        "cityList": - [                //类型:Array  必有字段  备注:城市列表             - {                //类型:Object  必有字段  备注:无                "regionId":1,                //类型:Number  必有字段  备注:省市区标识                "level":1,                //类型:Number  必有字段  备注:层级:0级为省、1级为市、2级为区                "name":"mock",                //类型:String  必有字段  备注:城市名称                "pySname":"mock",                //类型:String  必有字段  备注:拼音简称                "code":"mock",                //类型:String  必有字段  备注:编码                "status":1                //类型:Number  必有字段  备注:状态:0是无效,1是有效            }        ]    }}

 

更多相关文章

  1. Spinner 下拉列表 demo
  2. 图像列表(Gallery、ImageSwithcer)
  3. Android -联系人列表
  4. android 获取正在运行的应用程序列表
  5. Android 获取默认输入法,以及获取输入法的列表的方法
  6. Android使用RecyclerView实现瀑布流效果的列表展示
  7. Android中如何使用列表对话框
  8. android edittext只能输入字母和数字,默认弹出英文输入法
  9. android sqlite3 数据库升级,加字段

随机推荐

  1. Android Studio 出现 Error: NDK integra
  2. Android APP 设置启动的第一张图片
  3. ubuntu 编译 ffmpeg For Android
  4. android一键清除最近应用按钮
  5. Android外接扫码枪监听普通输入事件
  6. android音乐播放器(2)
  7. 判断Android客户端网络是否连接
  8. Android(安卓)之 在内存中读/取数据
  9. Android Studio关闭双击Shift打开全局搜
  10. Android studio引入百度地图时的bug