Android 自定义seekbar【仿微信联系人】
2016-01-03 22:06
726 查看
/**
*
* 转载请标明出处:http://blog.csdn.net/u013598111/article/details/50452578
* @author:【JunTao_sun】
*
*
*/
汉子转拼音 需要依赖 pinyin4j 架包
public class MainActivity extends Activity implements Select2String {
private static final String TAG = null;
//自定义 seekbar
private MySeekBar seekbar;
private ListView listView;
// 联系人信息
private ArrayList<String> Names;
//自定义比较器
private PinyinComparator comparator;
// 实体类
private List<NamesModel> namesData = new ArrayList<NamesModel>();
private ListViewadapte adapat;
private TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
comparator = new PinyinComparator();
initViews();
initData();
sortData();
}
/**
* 将数据NamesModel排序
*/
private void sortData() {
Collections.sort(namesData, comparator);
adapat = new ListViewadapte(namesData, this);
listView.setAdapter(adapat);
}
private void initViews() {
text = (TextView) this.findViewById(R.id.text_tag);
listView = (ListView) this.findViewById(R.id.listview);
View head = View.inflate(MainActivity.this, R.layout.head, null);
listView.addHeaderView(head);
seekbar = (MySeekBar) this.findViewById(R.id.seekbar);
seekbar.setOnSelect2StringListener(this);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if(position!=0){
Toast.makeText(MainActivity.this,
namesData.get(position-1).getName(), Toast.LENGTH_SHORT)
.show();
}
}
});
}
/*
*
* 接口回调的
* @str字母
*/
@Override
public void getSelect(String str) {
for (int i = 0; i < namesData.size(); i++) {
if (str.equals("↑")) {
listView.setSelection(0);
}
if (str.equals(namesData.get(i).getNameLeftPinying())) {
int select = adapat.getSelectPosition(i);
int point = adapat.getSelectItem(select);
listView.setSelection(point);
}}}
private void initData() {
// 先添加数据
Names = new ArrayList<String>();
Names.add("浅蓝色大海");
Names.add("梦幻彩虹");
Names.add("湛蓝天空");
Names.add("美丽故乡");
Names.add("离城梦");
Names.add("梦仙境");
Names.add("羽化尘");
Names.add("人来疯");
Names.add("苦恋伊");
Names.add("淡年华");
Names.add("追梦少年");
Names.add("曼陀罗");
Names.add("石头人");
Names.add("忆往昔");
Names.add("夜未央");
Names.add("巴黎港");
Names.add("温暖");
Names.add("幻想爱");
Names.add("笄发醒");
Names.add("Elisc");
Names.add("Ahiso");
Names.add("goiso");
Names.add("苦酒满");
Names.add("@魅力");
Names.add("U可爱");
Names.add("t天空");
Names.add("&money$");
Names.add("*雪花*");
Names.add("吖美呀");
Names.add("大话水浒");
Names.add("一沙一世界");
Names.add("花儿朵朵");
Names.add("韩国旅游");
Names.add("富士山");
Names.add("旧金山");
Names.add("太阳");
Names.add("月亮");
Names.add("温暖的旧时光");
Names.add("记忆美好的");
Names.add("喝点小酒");
Names.add("几碟花生");
// 将上面的数据 添加到NameModel中 并加入部首拼音
for (int i = 0; i < Names.size(); i++) {
NamesModel name = new NamesModel();
String str = Names.get(i);
char[] ch = str.toCharArray();
name.setName(str);
String saveLeft=null;
String firstWord=str.substring(0, 1);
//检查str 第一个string是否 是字母开头
boolean isEnglish=firstWord.matches("[a-z-A-Z]");
Log.e(TAG, "isEnglish"+isEnglish);
if(isEnglish){
saveLeft=PinyingTrasfrom.getInstance().english2Left(str);
}else if(!isEnglish){//如果不是字母开头 是汉字 则调用拼音转换工具
//如果是中文 再调用拼音转换 不然会抛异常
if(str.matches("^[\u4E00-\u9FFF]+$")){
String s=PinyingTrasfrom.getInstance().HanZid2Pinying(ch[0]);
s = s.substring(0, 1);
saveLeft = s.matches("[A-Z]") ? s : "#";
}else {
saveLeft="#";
}
}
// 判断是否为字母
name.setNameLeftPinying(saveLeft);
namesData.add(name);
}
}
@Override
public void onHidden() {
text.setVisibility(View.GONE);
}
@Override
public void onAppear(String info) {
text.setVisibility(View.VISIBLE);
text.setText(info);
}
}
拼音转换工具类:
package com.example.pingyin.utils;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
public class PinyingTrasfrom {
private static PinyingTrasfrom py;
private PinyingTrasfrom() {
super();
}
public static PinyingTrasfrom getInstance(){
if(py==null){
//为什么不放在方法 因为不必要每次都检查 效率低
//为什么放在中间 里面还要判断一次 因为防止里面有多余线程 多次创建
synchronized (PinyingTrasfrom.class) {
if(py==null){
py= new PinyingTrasfrom();
}
}
}
return py;
}
public String HanZid2Pinying(char ch){
//拼音转换格式
HanyuPinyinOutputFormat outputFormat = new HanyuPinyinOutputFormat();
// 大小写
outputFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
// outputFormat.setVCharType(HanyuPinyinVCharType.WITH_U_AND_COLON);
// 音调 返回有带数字
// outputFormat.setToneType(HanyuPinyinToneType.WITH_TONE_NUMBER);
String[] st=null;
try {
//得到 每一个字符的拼音 String
st = PinyinHelper.toHanyuPinyinStringArray(ch, outputFormat);
} catch (BadHanyuPinyinOutputFormatCombination e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return st[0];
};
/**
*
* 得到是英语名字的时候 第一个大写字母
* @param english
* @return
*/
public String english2Left(String english){
String en=english.substring(0, 1);
return en.toUpperCase();
}
}
ListView适配器:
package com.example.pingyin;
import java.util.Arrays;
import java.util.List;
import com.example.pingyin.utils.PinyingTrasfrom;
import com.hp.hpl.sparta.xpath.PositionEqualsExpr;
import android.R.array;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class ListViewadapte extends BaseAdapter {
private static final String TAG = null;
private List<NamesModel> data;
private Context c;
public ListViewadapte() {
super();
}
public ListViewadapte(List<NamesModel> t, Context c) {
super();
data = (List<NamesModel>) t;
this.c = c;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return data.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
static class ViewHold {
TextView textLeft;
TextView text;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHold hold;
if (convertView == null) {
convertView = View.inflate(c, R.layout.list_item, null);
hold = new ViewHold();
hold.textLeft = (TextView) convertView.findViewById(R.id.left);
hold.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(hold);
} else {
hold = (ViewHold) convertView.getTag();
}
int selection = getSelectPosition(position);
//判断是否是首字母的位置
if (position == getSelectItem(selection)) {
hold.textLeft.setVisibility(View.VISIBLE);
hold.textLeft.setTextSize(20);
hold.textLeft.setText(data.get(position).getNameLeftPinying());
} else {
hold.textLeft.setVisibility(View.GONE);
}
hold.text.setText(data.get(position).getName());
return convertView;
}
/*
* 根据ListView的当前位置获取分类的首字母的Char ascii值
*
* @param position
*
* @return 该position 对应的数据 拼音对应的ascii值
*/
public int getSelectPosition(int position) {
NamesModel namesModel = data.get(position);
String s = namesModel.getNameLeftPinying();
char[] charResult = s.toCharArray();
char charFirst = charResult[0];
int selection = 0;
return selection = charFirst;
}
/**
* @param postion
* 数据position 是否是第一次出现 归类 @selection Char ascii值
* @return
*/
public int getSelectItem(int selection) {
NamesModel str = null;
for (int i = 0; i < data.size(); i++) {
str = data.get(i);
char[] cs = str.getNameLeftPinying().toCharArray();
//得到汉子 第一个字的拼音字符
char c = cs[0];
if (c == selection) {
return i;
}
}
return -1;
}
}
排序比较器
package com.example.pingyin;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Rect;
import android.graphics.pdf.PdfDocument;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
public class MySeekBar extends View {
private static final String TAG = null;
private String[] pinyin = new String[] { "↑", "☆", "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", "#" };
public MySeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
rect = new Rect();
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(0xff0000ff);
paint.setDither(true);
paint.setTextSize(sp2px(45));
}
public MySeekBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MySeekBar(Context context) {
this(context, null);
}
private Paint paint;
private Rect rect;
private int textWidth;
private int textHheiht;
private int padding = 16;
//字母中 最大的宽度
private int maxWdith;
private float choose;
//是否画背景
private boolean showBkg;
//间隙 可以忽略
private float gap;
private int shengxia;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
maxWdith = 0;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
paint.setTextSize(sp2px(16));
for (int i = 0; i < pinyin.length; i++) {
textMeasure(pinyin[i]);
maxWdith = Math.max(maxWdith, rect.width());
}
// 得到最宽的字母长度
int w = maxWdith + 2 * padding;
setMeasuredDimension(w, getMeasuredHeight());
}
private void textMeasure(String str) {
paint.getTextBounds(str, 0, str.length(), rect);
}
private int getTextHeight() {
FontMetrics fm = paint.getFontMetrics();
return (int) (fm.ascent + fm.descent);
}
@Override
protected void onDraw(Canvas canvas) {
if (showBkg) {
canvas.drawColor(Color.parseColor("#40000000"));
}
int height = 0;
//得到控件宽度
int width = getWidth();
for (int i = 0; i < pinyin.length; i++) {
//在循环设置大小 因为下边paint设置重置了
paint.setTextSize(sp2px(16));
textMeasure(pinyin[i]);
//开始画字体的起始
int startLeft = (width) / 2 - maxWdith / 2;
if (choose == i) {
paint.setColor(0xffff0000);
paint.setFakeBoldText(true);
}
if (i == 1)
startLeft = startLeft - maxWdith / 4;
// 为了让最后个字符串 与末端有间隔 第一个字母开始的Y不变 所以把总体向上移动 一半个字体高度
canvas.drawText(pinyin[i], startLeft, (mEachHeight + gap) * i
+ mEachHeight - getTextHeight() + getTextHeight() / 2,
paint);
paint.reset();
}
}
private float mEachHeight;
private float downY;
private boolean isChoose = false;
// 选择区域的 位置
private int c;
private Select2String callback;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = (float) event.getY();
//得到点击 字母的位置
c = (int) (downY / getMeasuredHeight() * pinyin.length);
//刷新 那个字母变色
choose = c;
//控制是否画背景
showBkg = true;
if (callback != null) {
callback.onAppear(pinyin[c]);
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if (callback != null) {
callback.getSelect(pinyin[c]);
callback.onHidden();
}
showBkg = false;
invalidate();
break;
}
return true;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mEachHeight = (h - getPaddingBottom() - getPaddingTop()) / 32;
// 除了字母占据的空间大小
shengxia = (int) (h - 27 * mEachHeight) + (-getTextHeight() * 2);
// 字母间的间隙
gap = shengxia / 54;
}
// 回调接口 当点击那个字母的时候进行回调
interface Select2String {
void getSelect(String str);
void onHidden();
void onAppear(String pinyin);
}
public void setOnSelect2StringListener(Select2String select) {
this.callback = select;
}
/**
* sp 2 px
*
* @param spVal
* @return
*/
protected int sp2px(int spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, getResources().getDisplayMetrics());
}
}
实体类NamesModel:
下边是布局实现:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ListView
android:id="@+id/listview"
android:listSelector="#CCCCCC"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:dividerHeight="0dp"
android:scrollbars="none" >
</ListView>
<com.example.pingyin.MySeekBar
android:id="@+id/seekbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
<TextView android:layout_width="120dp"
android:layout_height="120dp"
android:text="A"
android:textColor="#ffffffff"
android:id="@+id/text_tag"
android:layout_centerInParent="true"
android:gravity="center"
android:textSize="40sp"
android:visibility="gone"
android:background="@drawable/tip"/>
</RelativeLayout>
List_Item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/left"
android:layout_width="fill_parent"
android:layout_height="45dp"
android:gravity="center_vertical"
android:background="@drawable/leftpy" />
<TextView
android:id="@+id/text"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="35dp"
/>
</LinearLayout>
*
* 转载请标明出处:http://blog.csdn.net/u013598111/article/details/50452578
* @author:【JunTao_sun】
*
*
*/
汉子转拼音 需要依赖 pinyin4j 架包
public class MainActivity extends Activity implements Select2String {
private static final String TAG = null;
//自定义 seekbar
private MySeekBar seekbar;
private ListView listView;
// 联系人信息
private ArrayList<String> Names;
//自定义比较器
private PinyinComparator comparator;
// 实体类
private List<NamesModel> namesData = new ArrayList<NamesModel>();
private ListViewadapte adapat;
private TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
comparator = new PinyinComparator();
initViews();
initData();
sortData();
}
/**
* 将数据NamesModel排序
*/
private void sortData() {
Collections.sort(namesData, comparator);
adapat = new ListViewadapte(namesData, this);
listView.setAdapter(adapat);
}
private void initViews() {
text = (TextView) this.findViewById(R.id.text_tag);
listView = (ListView) this.findViewById(R.id.listview);
View head = View.inflate(MainActivity.this, R.layout.head, null);
listView.addHeaderView(head);
seekbar = (MySeekBar) this.findViewById(R.id.seekbar);
seekbar.setOnSelect2StringListener(this);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if(position!=0){
Toast.makeText(MainActivity.this,
namesData.get(position-1).getName(), Toast.LENGTH_SHORT)
.show();
}
}
});
}
/*
*
* 接口回调的
* @str字母
*/
@Override
public void getSelect(String str) {
for (int i = 0; i < namesData.size(); i++) {
if (str.equals("↑")) {
listView.setSelection(0);
}
if (str.equals(namesData.get(i).getNameLeftPinying())) {
int select = adapat.getSelectPosition(i);
int point = adapat.getSelectItem(select);
listView.setSelection(point);
}}}
private void initData() {
// 先添加数据
Names = new ArrayList<String>();
Names.add("浅蓝色大海");
Names.add("梦幻彩虹");
Names.add("湛蓝天空");
Names.add("美丽故乡");
Names.add("离城梦");
Names.add("梦仙境");
Names.add("羽化尘");
Names.add("人来疯");
Names.add("苦恋伊");
Names.add("淡年华");
Names.add("追梦少年");
Names.add("曼陀罗");
Names.add("石头人");
Names.add("忆往昔");
Names.add("夜未央");
Names.add("巴黎港");
Names.add("温暖");
Names.add("幻想爱");
Names.add("笄发醒");
Names.add("Elisc");
Names.add("Ahiso");
Names.add("goiso");
Names.add("苦酒满");
Names.add("@魅力");
Names.add("U可爱");
Names.add("t天空");
Names.add("&money$");
Names.add("*雪花*");
Names.add("吖美呀");
Names.add("大话水浒");
Names.add("一沙一世界");
Names.add("花儿朵朵");
Names.add("韩国旅游");
Names.add("富士山");
Names.add("旧金山");
Names.add("太阳");
Names.add("月亮");
Names.add("温暖的旧时光");
Names.add("记忆美好的");
Names.add("喝点小酒");
Names.add("几碟花生");
// 将上面的数据 添加到NameModel中 并加入部首拼音
for (int i = 0; i < Names.size(); i++) {
NamesModel name = new NamesModel();
String str = Names.get(i);
char[] ch = str.toCharArray();
name.setName(str);
String saveLeft=null;
String firstWord=str.substring(0, 1);
//检查str 第一个string是否 是字母开头
boolean isEnglish=firstWord.matches("[a-z-A-Z]");
Log.e(TAG, "isEnglish"+isEnglish);
if(isEnglish){
saveLeft=PinyingTrasfrom.getInstance().english2Left(str);
}else if(!isEnglish){//如果不是字母开头 是汉字 则调用拼音转换工具
//如果是中文 再调用拼音转换 不然会抛异常
if(str.matches("^[\u4E00-\u9FFF]+$")){
String s=PinyingTrasfrom.getInstance().HanZid2Pinying(ch[0]);
s = s.substring(0, 1);
saveLeft = s.matches("[A-Z]") ? s : "#";
}else {
saveLeft="#";
}
}
// 判断是否为字母
name.setNameLeftPinying(saveLeft);
namesData.add(name);
}
}
@Override
public void onHidden() {
text.setVisibility(View.GONE);
}
@Override
public void onAppear(String info) {
text.setVisibility(View.VISIBLE);
text.setText(info);
}
}
拼音转换工具类:
package com.example.pingyin.utils;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
public class PinyingTrasfrom {
private static PinyingTrasfrom py;
private PinyingTrasfrom() {
super();
}
public static PinyingTrasfrom getInstance(){
if(py==null){
//为什么不放在方法 因为不必要每次都检查 效率低
//为什么放在中间 里面还要判断一次 因为防止里面有多余线程 多次创建
synchronized (PinyingTrasfrom.class) {
if(py==null){
py= new PinyingTrasfrom();
}
}
}
return py;
}
public String HanZid2Pinying(char ch){
//拼音转换格式
HanyuPinyinOutputFormat outputFormat = new HanyuPinyinOutputFormat();
// 大小写
outputFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
// outputFormat.setVCharType(HanyuPinyinVCharType.WITH_U_AND_COLON);
// 音调 返回有带数字
// outputFormat.setToneType(HanyuPinyinToneType.WITH_TONE_NUMBER);
String[] st=null;
try {
//得到 每一个字符的拼音 String
st = PinyinHelper.toHanyuPinyinStringArray(ch, outputFormat);
} catch (BadHanyuPinyinOutputFormatCombination e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return st[0];
};
/**
*
* 得到是英语名字的时候 第一个大写字母
* @param english
* @return
*/
public String english2Left(String english){
String en=english.substring(0, 1);
return en.toUpperCase();
}
}
ListView适配器:
package com.example.pingyin;
import java.util.Arrays;
import java.util.List;
import com.example.pingyin.utils.PinyingTrasfrom;
import com.hp.hpl.sparta.xpath.PositionEqualsExpr;
import android.R.array;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class ListViewadapte extends BaseAdapter {
private static final String TAG = null;
private List<NamesModel> data;
private Context c;
public ListViewadapte() {
super();
}
public ListViewadapte(List<NamesModel> t, Context c) {
super();
data = (List<NamesModel>) t;
this.c = c;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return data.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
static class ViewHold {
TextView textLeft;
TextView text;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHold hold;
if (convertView == null) {
convertView = View.inflate(c, R.layout.list_item, null);
hold = new ViewHold();
hold.textLeft = (TextView) convertView.findViewById(R.id.left);
hold.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(hold);
} else {
hold = (ViewHold) convertView.getTag();
}
int selection = getSelectPosition(position);
//判断是否是首字母的位置
if (position == getSelectItem(selection)) {
hold.textLeft.setVisibility(View.VISIBLE);
hold.textLeft.setTextSize(20);
hold.textLeft.setText(data.get(position).getNameLeftPinying());
} else {
hold.textLeft.setVisibility(View.GONE);
}
hold.text.setText(data.get(position).getName());
return convertView;
}
/*
* 根据ListView的当前位置获取分类的首字母的Char ascii值
*
* @param position
*
* @return 该position 对应的数据 拼音对应的ascii值
*/
public int getSelectPosition(int position) {
NamesModel namesModel = data.get(position);
String s = namesModel.getNameLeftPinying();
char[] charResult = s.toCharArray();
char charFirst = charResult[0];
int selection = 0;
return selection = charFirst;
}
/**
* @param postion
* 数据position 是否是第一次出现 归类 @selection Char ascii值
* @return
*/
public int getSelectItem(int selection) {
NamesModel str = null;
for (int i = 0; i < data.size(); i++) {
str = data.get(i);
char[] cs = str.getNameLeftPinying().toCharArray();
//得到汉子 第一个字的拼音字符
char c = cs[0];
if (c == selection) {
return i;
}
}
return -1;
}
}
排序比较器
package com.example.pingyin.utils; import java.util.Comparator; import j e129 ava.util.List; import com.example.pingyin.NamesModel; public class PinyinComparator implements Comparator<NamesModel> { @Override public int compare(NamesModel o1, NamesModel o2) { //# >@ if (o1.getNameLeftPinying().equals("@") || o2.getNameLeftPinying().equals("#")) { return -1; } else if (o1.getNameLeftPinying().equals("#") || o2.getNameLeftPinying().equals("@")) { return 1; } else { return o1.getNameLeftPinying().compareTo(o2.getNameLeftPinying()); } }}自定义seekbar:
package com.example.pingyin;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Rect;
import android.graphics.pdf.PdfDocument;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
public class MySeekBar extends View {
private static final String TAG = null;
private String[] pinyin = new String[] { "↑", "☆", "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", "#" };
public MySeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
rect = new Rect();
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(0xff0000ff);
paint.setDither(true);
paint.setTextSize(sp2px(45));
}
public MySeekBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MySeekBar(Context context) {
this(context, null);
}
private Paint paint;
private Rect rect;
private int textWidth;
private int textHheiht;
private int padding = 16;
//字母中 最大的宽度
private int maxWdith;
private float choose;
//是否画背景
private boolean showBkg;
//间隙 可以忽略
private float gap;
private int shengxia;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
maxWdith = 0;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
paint.setTextSize(sp2px(16));
for (int i = 0; i < pinyin.length; i++) {
textMeasure(pinyin[i]);
maxWdith = Math.max(maxWdith, rect.width());
}
// 得到最宽的字母长度
int w = maxWdith + 2 * padding;
setMeasuredDimension(w, getMeasuredHeight());
}
private void textMeasure(String str) {
paint.getTextBounds(str, 0, str.length(), rect);
}
private int getTextHeight() {
FontMetrics fm = paint.getFontMetrics();
return (int) (fm.ascent + fm.descent);
}
@Override
protected void onDraw(Canvas canvas) {
if (showBkg) {
canvas.drawColor(Color.parseColor("#40000000"));
}
int height = 0;
//得到控件宽度
int width = getWidth();
for (int i = 0; i < pinyin.length; i++) {
//在循环设置大小 因为下边paint设置重置了
paint.setTextSize(sp2px(16));
textMeasure(pinyin[i]);
//开始画字体的起始
int startLeft = (width) / 2 - maxWdith / 2;
if (choose == i) {
paint.setColor(0xffff0000);
paint.setFakeBoldText(true);
}
if (i == 1)
startLeft = startLeft - maxWdith / 4;
// 为了让最后个字符串 与末端有间隔 第一个字母开始的Y不变 所以把总体向上移动 一半个字体高度
canvas.drawText(pinyin[i], startLeft, (mEachHeight + gap) * i
+ mEachHeight - getTextHeight() + getTextHeight() / 2,
paint);
paint.reset();
}
}
private float mEachHeight;
private float downY;
private boolean isChoose = false;
// 选择区域的 位置
private int c;
private Select2String callback;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = (float) event.getY();
//得到点击 字母的位置
c = (int) (downY / getMeasuredHeight() * pinyin.length);
//刷新 那个字母变色
choose = c;
//控制是否画背景
showBkg = true;
if (callback != null) {
callback.onAppear(pinyin[c]);
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if (callback != null) {
callback.getSelect(pinyin[c]);
callback.onHidden();
}
showBkg = false;
invalidate();
break;
}
return true;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mEachHeight = (h - getPaddingBottom() - getPaddingTop()) / 32;
// 除了字母占据的空间大小
shengxia = (int) (h - 27 * mEachHeight) + (-getTextHeight() * 2);
// 字母间的间隙
gap = shengxia / 54;
}
// 回调接口 当点击那个字母的时候进行回调
interface Select2String {
void getSelect(String str);
void onHidden();
void onAppear(String pinyin);
}
public void setOnSelect2StringListener(Select2String select) {
this.callback = select;
}
/**
* sp 2 px
*
* @param spVal
* @return
*/
protected int sp2px(int spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, getResources().getDisplayMetrics());
}
}
实体类NamesModel:
package com.example.pingyin; public class NamesModel { public NamesModel() { } //汉子 private String name; //汉子第一个字的 拼音 private String nameLeftPinying; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNameLeftPinying() { return nameLeftPinying; } public void setNameLeftPinying(String nameLeftPinying) { this.nameLeftPinying = nameLeftPinying; } }
下边是布局实现:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ListView
android:id="@+id/listview"
android:listSelector="#CCCCCC"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:dividerHeight="0dp"
android:scrollbars="none" >
</ListView>
<com.example.pingyin.MySeekBar
android:id="@+id/seekbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
<TextView android:layout_width="120dp"
android:layout_height="120dp"
android:text="A"
android:textColor="#ffffffff"
android:id="@+id/text_tag"
android:layout_centerInParent="true"
android:gravity="center"
android:textSize="40sp"
android:visibility="gone"
android:background="@drawable/tip"/>
</RelativeLayout>
List_Item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/left"
android:layout_width="fill_parent"
android:layout_height="45dp"
android:gravity="center_vertical"
android:background="@drawable/leftpy" />
<TextView
android:id="@+id/text"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="35dp"
/>
</LinearLayout>
相关文章推荐
- 微信jssdk 开发 常见问题 jssdk invalid signature
- 微信开发笔记——微信网页登录授权,获取用户信息
- 微信商城开发实战 代码下载地址
- 微信公众平台开发 OAuth2.0网页授权认证
- mysql 小程序
- iOS微信支付SDK开发经验
- 微信支付
- Android微信登陆
- 夺命雷公狗---微信开发02----了解下微信公众平台交互原理和加密和解密原理
- 夺命雷公狗---微信开发01----测试下回访消息
- django搭建微信后台——批量获取用户信息
- zabbix微信报警脚本
- 微信公众账号开发入门
- 带参数二维码提示该公众号暂时无法提供服务,请稍后再试
- 微信公众平台开发学习系列(二):微信公众平台接收消息与发送消息
- C#-MVC开发微信应用(5)--自动应答系统-自动回复机器人
- C#-MVC开发微信应用(4)--微信门户菜单的管理操作
- 【随笔】这段时间没有写博客是因为一边看Qt5的帮助文档一边写小程序
- php 版本 微信支付 APP 服务端开发
- IOS微信支付 总结