【Android】城市列表,字母吸頂

效果動圖:

(後面補上)

總體佈局:

<?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="match_parent"
    style="@style/CommonBg_Gray">

    <!--吸頂標題-->
    <TextView
        android:id="@+id/item_title_top"
        android:layout_width="match_parent"
        android:layout_height="@dimen/x80"
        android:background="@color/more_light_gray"
        android:gravity="left|center_vertical"
        android:paddingLeft="@dimen/x30"
        style="@style/Txt_3_R_26"
        android:clickable="true"
        android:visibility="gone"/>

    <!--城市列表-->
    <ListView
        android:id="@+id/list_citylist"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        style="@style/CommonListNoLine"
        />

    <!--字母導航-->
    <com.uhome.base.common.view.MyLetterListView
        android:id="@+id/letterlist"
        android:layout_width="@dimen/x50"
        android:layout_height="@dimen/x800"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        />

</RelativeLayout>

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);
            }
        }
    };

附加Adapter(因城市列表數據給的是單獨無序的一個列表,沒有做字母排序,更沒有用字母分字列表,所以拿到數據之後還要做按字母排序、分字母):

/**
 * Created by Luzj on 2018/8/23.
 */
public class CityListAdapter extends BaseAdapter {

    private Context context;
    /**
     * 接口返回數據
     */
    private List<CityInfo> datas;
    /**
     * 接口數據加上字母
     */
    private ArrayList<CityInfo> allDatas = new ArrayList<>();
    /**
     * item type,0爲字母,1爲帶下黑線,2不帶下黑線
     */
    private final int ZIMU = 0, ITEM_LINE = 1, ITEM_NOLINE = 2;
    /**
     * 字母所帶列表
     */
    private ArrayList<CityInfo> aL = new ArrayList<>();
    private ArrayList<CityInfo> bL = new ArrayList<>();
    private ArrayList<CityInfo> cL = new ArrayList<>();
    private ArrayList<CityInfo> dL = new ArrayList<>();
    private ArrayList<CityInfo> eL = new ArrayList<>();
    private ArrayList<CityInfo> fL = new ArrayList<>();
    private ArrayList<CityInfo> gL = new ArrayList<>();
    private ArrayList<CityInfo> hL = new ArrayList<>();
    private ArrayList<CityInfo> iL = new ArrayList<>();
    private ArrayList<CityInfo> jL = new ArrayList<>();
    private ArrayList<CityInfo> kL = new ArrayList<>();
    private ArrayList<CityInfo> lL = new ArrayList<>();
    private ArrayList<CityInfo> mL = new ArrayList<>();
    private ArrayList<CityInfo> nL = new ArrayList<>();
    private ArrayList<CityInfo> oL = new ArrayList<>();
    private ArrayList<CityInfo> pL = new ArrayList<>();
    private ArrayList<CityInfo> qL = new ArrayList<>();
    private ArrayList<CityInfo> rL = new ArrayList<>();
    private ArrayList<CityInfo> sL = new ArrayList<>();
    private ArrayList<CityInfo> tL = new ArrayList<>();
    private ArrayList<CityInfo> uL = new ArrayList<>();
    private ArrayList<CityInfo> vL = new ArrayList<>();
    private ArrayList<CityInfo> wL = new ArrayList<>();
    private ArrayList<CityInfo> xL = new ArrayList<>();
    private ArrayList<CityInfo> yL = new ArrayList<>();
    private ArrayList<CityInfo> 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<List> 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<String, Integer> 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是有效
            }
        ]
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章