您的位置:首页 > 其它

安卓城市选择,列表显示,拼音排序,滑动选择。

2017-01-12 14:13 302 查看
       最近开发项目有一个需要,选择城市,有三级滚筒式的,有些丑,所以参考了他人的联系人列表选择做了一个。先上图看下效果:
https://img-blog.csdn.net/20170112141746730?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbjEwMDAx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
        具体效果,为左边显示城市列表,在每个拼音的开头显示大写字母,右边的控件点击滑动,会在中间显示选中的字母,并有小框框显示,列表滑动到相应的字母处。

        必须引入汉字转拼音开源库:https://github.com/stuxuhai/jpinyin

具体代码如下:

右侧字母表自定义控件:

public class SideCityBar extends View {
private String[] letterStrings = {"#", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "S", "Y", "Z"};
private Paint paint;
private Paint mPaint;
private Context mContext;
private int heght;
private int postion;
private boolean isShow = false;
private Rect rect = new Rect();

public SideCityBar(Context context) {
super(context);
init(context);
}

public SideCityBar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}

public SideCityBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}

private void init(Context context) {
mContext = context;
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setTextSize(30);
mPaint.setAntiAlias(true);

paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heght = getHeight() / letterStrings.length;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
setBackgroundColor(Color.BLACK);

for (int i = 0; i < letterStrings.length; i++) {
String s1 = letterStrings[i];
mPaint.getTextBounds(s1, 0, s1.length(), rect);
int h1 = rect.height();
int w1 = rect.width();
//  mPaint.measureText(s1)只需要文字宽度可用此方法。
int h2 = heght / 2 + h1 / 2 + heght * i;
int w2 = getWidth() / 2 - w1 / 2;
canvas.drawText(s1, w2, h2, mPaint);
if (isShow && (i == postion)) {
canvas.drawRect((getWidth() - heght) / 2, (0 + i * heght), (getWidth() + heght) / 2, (heght + i * heght), paint);
}
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {
float y1 = event.getY();
if (event.getAction() == MotionEvent.ACTION_UP) {
isShow = false;
mTextView.setVisibility(GONE);
mOnchangeString.setTextShow(false);
invalidate();
return true;
} else {
isShow = true;
//计算框框的位置
postion = (int) (y1 / heght);
if (postion < letterStrings.length) {
mTextView.setVisibility(VISIBLE);
mTextView.setText(letterStrings[postion]);
mOnchangeString.getChangeString(letterStrings[postion]);
mOnchangeString.setTextShow(true);
invalidate();
}

return true;
}
}

TextView mTextView;

public void setTextView(TextView textView) {
mTextView = textView;
}

public void setOnChangeLis(OnchangeString onChangeLis) {
mOnchangeString = onChangeLis;
}

OnchangeString mOnchangeString;

public interface OnchangeString {
void getChangeString(String s);

void setTextShow(boolean b);
}
}


数据封装类:

public class CityModel {
private String name;
private String fistletter;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getFistletter() {
return fistletter;
}

public void setFistletter(String fistletter) {
this.fistletter = fistletter;
}
}


接着就是主布局和列表布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<ListView
android:id="@+
16ff5
id/l1"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<TextView
android:id="@+id/t1"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:background="#3CAC48"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="50dp"
android:visibility="gone" />

<allother.two.sidecity.SideCityBar
android:id="@+id/s1"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
</RelativeLayout>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/t1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:text="A" />

<TextView
android:id="@+id/t2"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:text="A" />

</LinearLayout>

最后是我们的主要Activity:

public class SideCityActivity extends AppCompatActivity {
private String TAG = "SideCityActivity:";
private ListView listView;
private TextView txtShowCurrentLetter;
private SideCityBar sideBar;
private List<CityModel> list = new ArrayList();
private SideBarCityAdapter sideBarCityAdapter;
private Map<String, Integer> map = new HashMap<>();
private String[] nameStrings = {"$XXOO", "上海", "北京", "杭州", "广州", "南京", "苏州", "深圳", "成都", "重庆", "天津", "宁波", "扬州", "无锡", "福州",
"厦门", "武汉", "西安", "沈阳", "大连", "青岛", "济南", "海口", "石家庄", "唐山", "秦皇岛", "邯郸", "邢台", "保定", "张家口", "承德", "沧州", "廊坊",
"衡水", "太原", "大同", "阳泉", "长治", "晋城", "朔州", "晋中", "运城", "忻州", "临汾", "吕梁", "呼和浩特", "包头", "乌海", "赤峰", "通辽", "鄂尔多斯",
"呼伦贝尔", "兴安盟", "锡林郭勒", "乌兰察布", "巴彦淖尔", "阿拉善", "鞍山", "抚顺", "本溪", "丹东", "锦州", "营口", "阜新", "辽阳", "盘锦", "铁岭", "朝阳",
"葫芦岛", "长春", "吉林", "四平", "辽源", "通化", "白山", "松原", "白城", "延边", "哈尔滨", "齐齐哈尔", "鸡西", "鹤岗", "双鸭山", "大庆", "伊春", "佳木斯", "七台河",
"牡丹江", "黑河", "绥化", "大兴安岭", "徐州", "常州", "南通", "连云港", "淮安", "盐城", "镇江", "泰州", "宿迁", "温州", "嘉兴", "湖州", "绍兴", "金华", "衢州", "舟山", "台州",
"丽水", "合肥", "芜湖", "蚌埠", "淮南", "马鞍山", "淮北", "铜陵", "安庆", "黄山", "滁州", "阜阳", "宿州", "六安", "亳州", "池州", "宣城", "莆田", "三明", "泉州", "漳州", "南平", "龙岩",
"宁德", "南昌", "景德镇", "萍乡", "九江", "新余", "鹰潭", "赣州", "吉安", "宜春", "抚州", "上饶", "淄博", "枣庄", "东营", "烟台", "潍坊", "济宁", "泰安", "威海", "日照", "莱芜", "临沂", "德州",
"聊城", "滨州", "菏泽", "郑州", "开封", "洛阳", "平顶山", "安阳", "鹤壁", "新乡", "焦作", "濮阳", "许昌", "漯河", "三门峡", "南阳", "商丘", "信阳", "周口", "驻马店", "黄石", "十堰", "宜昌", "襄阳", "鄂州",
"荆门", "孝感", "荆州", "黄冈", "咸宁", "随州", "恩施州", "仙桃", "潜江", "天门", "株洲", "湘潭", "衡阳", "邵阳", "岳阳", "常德", "张家界", "益阳", "郴州", "永州", "怀化", "娄底", "湘西", "韶关", "珠海", "汕头",
"佛山", "江门", "湛江", "茂名", "肇庆", "惠州", "梅州", "汕尾", "河源", "阳江", "清远", "东莞", "中山", "潮州", "揭阳", "云浮", "南宁", "柳州", "桂林", "梧州", "北海", "防城港", "钦州", "贵港", "玉林", "百色", "贺州",
"河池", "自贡", "攀枝花", "泸州", "德阳", "绵阳", "广元", "遂宁", "内江", "乐山", "南充", "眉山", "宜宾", "广安", "达州", "雅安", "巴中", "资阳", "阿坝", "甘孜州", "凉山", "贵阳", "六盘水", "遵义", "安顺", "铜仁地区",
"黔西南", "毕节地区", "黔东南", "黔南", "昆明", "曲靖", "玉溪", "保山", "昭通", "楚雄州", "红河", "文山州", "普洱", "西双版纳", "大理州", "德宏", "丽江", "怒江", "迪庆", "临沧", "拉萨", "昌都地区", "山南",
"日喀则地区", "那曲", "阿里", "林芝地区", "铜川", "宝鸡", "咸阳", "渭南", "延安", "汉中", "榆林", "安康", "商洛", "兰州", "嘉峪关", "金昌", "白银", "天水", "武威", "张掖", "平凉", "酒泉", "庆阳", "定西",
"陇南", "临夏州", "甘南", "西宁", "海东", "海北", "黄南", "果洛", "玉树", "海西", "银川", "石嘴山", "吴忠", "固原", "乌鲁木齐", "克拉玛依", "吐鲁番地区", "哈密地区", "昌吉州", "博尔塔拉", "巴音郭楞",
"阿克苏地区", "克孜勒苏", "喀什地区", "和田地区", "伊犁", "塔城地区", "阿勒泰地区", "石河子", "香港", "澳门", "长沙", "三亚", "中卫", "儋州", "保亭", "昌江", "澄迈县", "崇左", "定安县", "东方", "济源",
"来宾", "乐东", "陵水", "琼海", "神农架林区", "图木舒克", "屯昌县", "万宁", "文昌", "海南州"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_two_sidecity);
txtShowCurrentLetter = (TextView) findViewById(R.id.t1);
sideBar = (SideCityBar) findViewById(R.id.s1);
listView = (ListView) findViewById(R.id.l1);
sideBar.setTextView(txtShowCurrentLetter);
getAllData();
sideBarCityAdapter = new SideBarCityAdapter();
listView.setAdapter(sideBarCityAdapter);

sideBar.setOnChangeLis(new SideCityBar.OnchangeString() {
@Override
public void getChangeString(String s) {
int a1 = getCurrentPosition(s);
if (a1 != -1) {
listView.setSelection(a1);
} else {

}
}

@Override
public void setTextShow(boolean b) {

}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String city = list.get(position).getName();
}
});
}

/**
* list获取所有数据
*/
private void getAllData() {
list = new ArrayList();
for (int i = 0; i < nameStrings.length; i++) {
CityModel cityModel = new CityModel();
cityModel.setName(nameStrings[i]);
//将汉字转换为拼音
String pin = PinyinHelper.getShortPinyin(nameStrings[i]);
//将拼音字符串转换为大写拼音
String pinD = String.valueOf(pin.charAt(0)).toUpperCase();
//获取大写拼音字符串的第一个字符
char c1 = pinD.charAt(0);
if (c1 < 'A' || c1 > 'Z') {
cityModel.setFistletter("#");
} else {
cityModel.setFistletter(String.valueOf(c1));
}
list.add(cityModel);
}
//将联系人列表的标题字母排序
Collections.sort(list, new Comparator<CityModel>() {
@Override
public int compare(CityModel o1, CityModel o2) {
return o1.getFistletter().compareTo(o2.getFistletter());
}
});
//记录字母所在位置
String s1 = list.get(0).getFistletter();
map.put(s1, 0);
for (int i = 0; i < list.size(); i++) {
String s2 = list.get(i).getFistletter();
if (!s1.equals(s2)) {
s1 = s2;
map.put(s2, i);
}
}
}

private int getCurrentPosition(String s) {
if (map.get(s) != null) {
return map.get(s);
} else {
return -1;
}
}

public class SideBarCityAdapter extends BaseAdapter {

@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return list.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(SideCityActivity.this).inflate(R.layout.act_two_sidecity_item, null);
viewHolder.txtFirstLetter = (TextView) convertView.findViewById(R.id.t1);
viewHolder.txtName = (TextView) convertView.findViewById(R.id.t2);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.txtName.setText(list.get(position).getName());
String s1 = list.get(position).getFistletter();
if (map.get(s1) != null && map.get(s1).equals(position)) {
viewHolder.txtFirstLetter.setText(s1);
viewHolder.txtFirstLetter.setVisibility(View.VISIBLE);
} else {
viewHolder.txtFirstLetter.setVisibility(View.GONE);
}

return convertView;
}

public class ViewHolder {
TextView txtFirstLetter, txtName;
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: