上面展示的是效果图,我们平时使用的通过点击字母就能找到相关字母的联系人,这就是我们想要达到的效果。
根据我们想要实现的效果,我们先要理一理思路,所有的编程都是这样,有了清晰的思路才能确定每一步我们具体要做什么。
首先我们想要出现手机联系人的效果,就要先绘制右侧的字母,再对屏幕的手势滑动进行监听,使字母在被点击时变色,然后是我们的布局中的TextView内容的改变,这里TextView的改变我们需要用到监听者模式。
思路:使用drawtext方法循环从上到下进行绘制。
根据屏幕高度,设置字体大小
//必须写在onMeasure方法中,
//如果写在构造器中,由于开始的时候没有及时获得宽高,导致高度默认为0
mpainttext.setTextSize(height/26f);
String数组,用于循环绘制
private String[] array=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"};
在onDraw方法中进行绘制
for(int i=0;i<26;i++){ //由于字母大小不一致,选择宽度最大的'm'相减,作为x轴坐标 canvas.drawText(array[i], width-mpainttext.measureText("m"), height/26*(i+1), mpainttext); }
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
//ACTION_MOVE监听手指滑动
case MotionEvent.ACTION_MOVE:
//ACTION_DOWN监听手指落下
case MotionEvent.ACTION_DOWN:
//获取手指落下的x坐标与Y坐标
x=event.getX();
y=event.getY();
if(x>=width-mpainttext.measureText("m")&&x<width){
//确定点击的是第几个
index=(int)y/(height/26);
Log.d("touch", "点击的是"+array[index]);
invalidate();
return true;
}
break;
//ACTION_UP监听手指抬起
case MotionEvent.ACTION_UP:
return true;
default:
break;
}
return super.onTouchEvent(event);
}
使用index作为判断
private int index=-1;
//设置画笔
//创建新画笔,设置画笔颜色
mpaintcolor=new Paint();
mpaintcolor.setColor(Color.RED);
mpaintcolor.setTextAlign(Align.CENTER);
//onMeasure方法中才会获得高度
mpaintcolor.setTextSize(height/26f);
手势监听事件中进行index设置,用于后面绘制时改变颜色的判断
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_DOWN:
x=event.getX();
y=event.getY();
if(x>=width-mpainttext.measureText("m")&&x<width){
index=(int)y/(height/26);
Log.d("touch", "点击的是"+array[index]);
invalidate();
return true;
}
break;
case MotionEvent.ACTION_UP:
if(index!=-1){
index=-1;
}
invalidate();
return true;
default:
break;
}
onDraw方法中根据index改变显示颜色
for(int i=0;i<26;i++){
if(index!=-1&&i==index){
canvas.drawText(array[index], width-mpainttext.measureText("m"), height/26*(i+1), mpaintcolor);
index=-1;
}else{
canvas.drawText(array[i], width-mpainttext.measureText("m"), height/26*(i+1), mpainttext);
}
}
监听者模式:
(1)在被监听对象中编写接口interface,在接口中编写抽象方法,用于调用。
(2)创建被监听的对象
(3)
被监听者在继承View的class中编写接口
//interface接口
public interface OnItemSelect{
//抽象方法
public void OnItemSelectListener(String indexString);
}
//创建传递对象()
private OnItemSelect OnItemSelectlistener;
//监听者将要调用的方法
public void OnItemSelectlistener( OnItemSelect OnItemSelectlistener){
//监听者中调用到该方法,传递进一个OnItemSelectlistener对象
this.OnItemSelectlistener=OnItemSelectlistener;
}
监听者中调用
这里写代码片
View
public class MySlider extends View{
private int width;
private int height;
private Paint mpainttext;
private Paint mpaintcolor;
private int index=-1;
private String[] array=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 MySlider(Context context) {
super(context);
}
public MySlider(Context context, AttributeSet attrs) {
super(context, attrs);
mpainttext=new Paint();
mpainttext.setTextAlign(Align.CENTER);
mpaintcolor=new Paint();
mpaintcolor.setColor(Color.RED);
mpaintcolor.setTextAlign(Align.CENTER);
}
public interface OnItemSelect{
public void OnItemSelectListener(String indexString);
}
private OnItemSelect OnItemSelectlistener;
public void OnItemSelectlistener( OnItemSelect OnItemSelectlistener){
this.OnItemSelectlistener=OnItemSelectlistener;
}
private float x;
private float y;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_DOWN:
x=event.getX();
y=event.getY();
if(x>=width-mpainttext.measureText("m")&&x<width){
index=(int)y/(height/26);
Log.d("touch", "点击的是"+array[index]);
OnItemSelectlistener.OnItemSelectListener(array[index]);
invalidate();
return true;
}
break;
case MotionEvent.ACTION_UP:
if(index!=-1){
index=-1;
}
invalidate();
return true;
default:
break;
}
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int i=0;i<26;i++){
if(index!=-1&&i==index){
canvas.drawText(array[index], width-mpainttext.measureText("m"), height/26*(i+1), mpaintcolor);
index=-1;
}else{
canvas.drawText(array[i], width-mpainttext.measureText("m"), height/26*(i+1), mpainttext);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);//告知父布局该View的大小
//测量出来之后使用
mpainttext.setTextSize(height/26f);
mpaintcolor.setTextSize(height/26f);
}
}
Activity
public class MainActivity_bitmap extends Activity {
private TextView mtextview;
private MySlider msliderview;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.bitmap_view);
mtextview = (TextView) findViewById(R.id.textview);
msliderview = (MySlider) findViewById(R.id.slider);
msliderview.OnItemSelectlistener(new OnItemSelect() {
@Override
public void OnItemSelectListener(String indexString) {
mtextview.setText(indexString);
}
});
}
}