AndroidAndroid技术知识Android进阶之路

Android三级联动wheel代码分析(二)

2015-12-18  本文已影响509人  许晓北

自定义View的步骤:

1、自定义View的属性

2、在View的构造方法中获得我们自定义的属性

[ 3、重写onMesure ]

4、重写onDraw

我把3用[]标出了,所以说3不一定是必须的,当然了大部分情况下还是需要重写的。

继承View,实现自己想要的组件,那么需要使用到setMeasuredDimension这个方法,这个方法决定了当前View的大小,如果不使用setMeasuredDimension这个方法,那么View的大小将不起作用。

1

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// TODO Auto-generated method stub

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

controlWidth = getWidth();

if (controlWidth != 0) {

setMeasuredDimension(getWidth(), itemNumber * unitHeight);

controlWidth = getWidth();

}

}

2

@Override

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

super.onDraw(canvas);

//绘制线条

3

drawLine(canvas);

//绘制数据

4

drawList(canvas);

//绘制覆盖板

5

drawMask(canvas);

}

3

/**

* 绘制线条

*

* @param canvas

*/

private void drawLine(Canvas canvas) {

if (linePaint == null) {

linePaint = new Paint();

linePaint.setColor(lineColor);

//抗锯齿

linePaint.setAntiAlias(true);

//设置空心线宽

linePaint.setStrokeWidth(1f);

 }

canvas.drawLine(0, controlHeight / 2 - unitHeight / 2 + 2,

controlWidth, controlHeight / 2 - unitHeight / 2 + 2, linePaint);

canvas.drawLine(0, controlHeight / 2 + unitHeight / 2 - 2,

controlWidth, controlHeight / 2 + unitHeight / 2 - 2, linePaint);

}

4


/**

* 绘制数据

*

* @param canvas

*/

private synchronized void drawList(Canvas canvas) {

if (isClearing)

return;

try {

for (ItemObject itemObject : itemList) {

itemObject.drawSelf(canvas);

}

} catch (Exception e) {

// TODO: handle exception

}

5


/**

* 绘制遮盖板

*

* @param canvas

*/

private void drawMask(Canvas canvas) {

//线性渲染

LinearGradient lg = new LinearGradient(0, 0, 0, maskHight, 0x00f2f2f2,

0x00f2f2f2, TileMode.MIRROR);

Paint paint = new Paint();

paint.setShader(lg);

canvas.drawRect(0, 0, controlWidth, maskHight, paint);

LinearGradient lg2 = new LinearGradient(0, controlHeight - maskHight,

0, controlHeight, 0x00f2f2f2, 0x00f2f2f2, TileMode.MIRROR);

Paint paint2 = new Paint();

//设置渲染对象

paint2.setShader(lg2);

canvas.drawRect(0, controlHeight - maskHight, controlWidth,

controlHeight, paint2);

}

//LinearGradient  线性渲染 

public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)

参数x0表示渐变的起始点x坐标;参数y0表示渐变的起始点y坐标;参数x1表示渐变的终点x坐标;参数y1表示渐变的终点y坐标 ;color0表示渐变开始颜色;color1表示渐变结束颜色;参数tile表示平铺方式。Shader.TileMode有3种参数可供选择,分别为CLAMP、REPEAT和MIRROR:

CLAMP的作用是如果渲染器超出原始边界范围,则会复制边缘颜色对超出范围的区域进行着色

REPEAT的作用是在横向和纵向上以平铺的形式重复渲染位图

MIRROR的作用是在横向和纵向上以镜像的方式重复渲染位图

自定义view已经画好。现在接着进行触摸事件

6

@Override

public boolean onTouchEvent(MotionEvent event) {

// isEnable是否可用

if (!isEnable)

return true;

int y = (int) event.getY();

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

/** 是否滑动中 */

isScrolling = true;

/** 按下的坐标 */

downY = (int) event.getY();

/** 按下的时间 */

downTime = System.currentTimeMillis();

break;

case MotionEvent.ACTION_MOVE:

//移动距离

7

actionMove(y - downY);

//选择监听

8

onSelectListener();

break;

case MotionEvent.ACTION_UP:

// 移动距离的绝对值

int move = (y - downY);

move = move > 0 ? move : move * (-1);

// 判断段时间移动的距离

/** 短促移动  goonTime=200*//** 短促移动距离  goonDistence=100*/

if (System.currentTimeMillis() - downTime < goonTime

&& move > goonDistence) {

10

goonMove(y - downY);

} else {

13

actionUp(y - downY);

}

17

noEmpty();

isScrolling = false;

break;


default:

break;
}

return true;


}

7

/**

* 移动的时候

*

* @param move

*/

private void actionMove(int move) {

for (ItemObject item : itemList) {

item.move(move);

 }

invalidate();

}

8

/**

* 滑动监听

*/

private void onSelectListener() {

/** 选择监听 */

9

if (onSelectListener == null)

return;

for (ItemObject item : itemList) {

if (item.isSelected()) {

//监听选择

onSelectListener.selecting(item.id, item.itemText);

}

}

}


设置监听接口回调

9


/**

* 选择监听监听

*

* @author zoudong

*

*/

public interface OnSelectListener {

/**

* 结束选择

*

* @param id

* @param text

*/

public void endSelect(int id, String text);

/**

* 选中的内容

*

* @param id

* @param text

*/

public void selecting(int id, String text);

}

10

/**

* 继续移动一定距离

*/

private synchronized void goonMove(final int move) {

new Thread(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

int distence = 0;

/** 移动距离  MOVE_NUMBER=5*/

while (distence < unitHeight * MOVE_NUMBER) {

try {

Thread.sleep(5);

 } catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

 }

11

actionThreadMove(move > 0 ? distence : distence * (-1));

distence += 10;
 }    13
actionUp(move > 0 ? distence - 10 : distence * (-1) + 10);
17
noEmpty();

 }
 }).start();
}

/*  11

* 移动,线程中调用

*

* @param move

*/

private void actionThreadMove(int move) {

for (ItemObject item : itemList) {

item.move(move);

}

12

Message rMessage = new Message();

/** 刷新界面  REFRESH_VIEW=0x001 */

rMessage.what = REFRESH_VIEW;

handler.sendMessage(rMessage);
}

12

@SuppressLint("HandlerLeak")

Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

super.handleMessage(msg);

switch (msg.what) {

case REFRESH_VIEW:

invalidate();

break;

default:

break;

   }

 }

};

13

/**

* 松开的时候

*

* @param move

*/

private void actionUp(int move) {

int newMove = 0;

if (move > 0) {

for (int i = 0; i < itemList.size(); i++) {

if (itemList.get(i).isSelected()) {

14

newMove = (int) itemList.get(i).moveToSelected();

if (onSelectListener != null)

//接口回调 结束选择

onSelectListener.endSelect(itemList.get(i).id,

itemList.get(i).itemText);

break;

  }

  }

  } else {

for (int i = itemList.size() - 1; i >= 0; i--) {

if (itemList.get(i).isSelected()) {

newMove = (int) itemList.get(i).moveToSelected();

if (onSelectListener != null)

//结束选择

onSelectListener.endSelect(itemList.get(i).id,

itemList.get(i).itemText);

break;

  }

  }

  }

for (ItemObject item : itemList) {

15

item.newY(move + 0);

    }

16

slowMove(newMove);

Message rMessage = new Message();

rMessage.what = REFRESH_VIEW;

handler.sendMessage(rMessage);

}

14

/**

* 获取移动到标准位置需要的距离

*/

public float moveToSelected() {

return (controlHeight / 2 - unitHeight / 2) - (y + move);

}

15

/**

* 设置新的坐标

*

* @param move

*/

public void newY(int _move) {

this.move = 0;

this.y = y + _move;

}

16

/**

* 缓慢移动

*

* @param move

*/

private synchronized void slowMove(final int move) {

new Thread(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

// 判断正负

int m = move > 0 ? move : move * (-1);

int i = move > 0 ? 1 : (-1);

// 移动速度

int speed = 1;

while (true) {

m = m - speed;

if (m <= 0) {

for (ItemObject item : itemList) {

item.newY(m * i);

 }

Message rMessage = new Message();

rMessage.what = REFRESH_VIEW;

handler.sendMessage(rMessage);

try {

Thread.sleep(2);

 } catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

 }

break;

 }

for (ItemObject item : itemList) {

item.newY(speed * i);

 }

Message rMessage = new Message();

rMessage.what = REFRESH_VIEW;

handler.sendMessage(rMessage);

//释放系统资源

try {

Thread.sleep(2);

 } catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

 }

 }

for (ItemObject item : itemList) {

if (item.isSelected()) {

if (onSelectListener != null)

onSelectListener.endSelect(item.id, item.itemText);

break;

 }

 }

 }

 }).start();

}

17

/**

* 不能为空,必须有选项

*/

private void noEmpty() {

if (!noEmpty)

return;

for (ItemObject item : itemList) {

if (item.isSelected())

return;

 }

int move = (int) itemList.get(0).moveToSelected();

if (move < 0) {

18

defaultMove(move);h

 } else {

defaultMove((int) itemList.get(itemList.size() - 1)

.moveToSelected());

 }

for (ItemObject item : itemList) {

if (item.isSelected()) {

if (onSelectListener != null)

onSelectListener.endSelect(item.id, item.itemText);

break;

 }

 }

}

18

/**

* 移动到默认位置

*

* @param move

*/

private void defaultMove(int move) {

for (ItemObject item : itemList) {

item.newY(move);

 }

Message rMessage = new Message();

rMessage.what = REFRESH_VIEW;

handler.sendMessage(rMessage);

}

到了这一步 基本自定义控件搞定了 剩下就是暴漏一些自己需要的接口或者方法了~源码请查看

Android三级联动wheel代码分析(一)里面,等两天接着Android三级联动wheel代码分析(三)。

如有不对的地方请指正,因为这个代码较多 加上数字应该会看的稍微清楚点。。。


上一篇下一篇

猜你喜欢

热点阅读