自定义控件引用出现问题 android layoutjava 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你的layout文件还有MySlipSwitch代码 回帖记得引用,不然别人根本不知道你回复就是贴了哪些代码才知道哪的问题,你这估计是解析布局 switch_on_Bkg为null了,所以才提示空指针,不过运行起来应该是没问题的 回帖记得引用,不然别人根本不知道你回复就是贴了哪些代码才知道哪的问题,你这估计是解析布局 switch_on_Bkg为null了,所以才提示空指针,不过运行起来应该是没问题的好的,记住了public class MySlipSwitch extends View implements OnTouchListener { // 开关开启时的背景,关闭时的背景,滑动按钮 private Bitmap switch_on_Bkg, switch_off_Bkg, slip_Btn; private Rect on_Rect, off_Rect; // 是否正在滑动 private boolean isSlipping = false; // 当前开关状态,true为开启,false为关闭 private boolean isSwitchOn = false; // 手指按下时的水平坐标X,当前的水平坐标X private float previousX, currentX = 80; // 开关监听器 private OnSwitchListener onSwitchListener; // 是否设置了开关监听器 private boolean isSwitchListenerOn = false; public MySlipSwitch(Context context) { super(context); init(); } public MySlipSwitch(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { setOnTouchListener(this); } protected void setImageResource(int switchOnBkg, int switchOffBkg, int slipBtn) { switch_on_Bkg = BitmapFactory.decodeResource(getResources(), switchOnBkg); switch_off_Bkg = BitmapFactory.decodeResource(getResources(), switchOffBkg); slip_Btn = BitmapFactory.decodeResource(getResources(), slipBtn); // 右半边Rect,即滑动按钮在右半边时表示开关开启 on_Rect = new Rect(switch_off_Bkg.getWidth() - slip_Btn.getWidth(), 0, switch_off_Bkg.getWidth(), slip_Btn.getHeight()); // 左半边Rect,即滑动按钮在左半边时表示开关关闭 off_Rect = new Rect(0, 0, slip_Btn.getWidth(), slip_Btn.getHeight()); } // 设置开关状态 protected void setSwitchState(boolean switchState) { isSwitchOn = switchState; Log.e("========", "set"); } // 获取开关状态 protected boolean getSwitchState() { return isSwitchOn; } protected void updateSwitchState(boolean switchState) { isSwitchOn = switchState; Log.e("==========", "update"); invalidate(); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); Matrix matrix = new Matrix(); Paint paint = new Paint(); // 滑动按钮的左边坐标 float left_SlipBtn; // 手指滑动到左半边的时候表示开关为关闭状态,滑动到右半边的时候表示开关为开启状态 if (currentX < (switch_on_Bkg.getWidth() / 2)) { canvas.drawBitmap(switch_off_Bkg, matrix, paint); } else { canvas.drawBitmap(switch_on_Bkg, matrix, paint); } // 判断当前是否正在滑动 if (isSlipping) { if (currentX > switch_on_Bkg.getWidth()) { Log.e("=========", "slip"); left_SlipBtn = switch_on_Bkg.getWidth() - slip_Btn.getWidth(); } else { Log.e("=========", "slip"); left_SlipBtn = currentX - slip_Btn.getWidth() / 2; // 为什么是减1/2 } } else { // 根据当前的开关状态设置滑动按钮的位置 if (isSwitchOn) { Log.e("isSwitchOn", isSwitchOn + ""); Log.e("currentX", currentX + ""); Log.e("=========", "on"); left_SlipBtn = on_Rect.left; } else { Log.e("=========", "off"); left_SlipBtn = off_Rect.left; } } // 对滑动按钮的位置进行异常判断 if (left_SlipBtn < 0) { left_SlipBtn = 0; } else if (left_SlipBtn > switch_on_Bkg.getWidth()- slip_Btn.getWidth()) { left_SlipBtn = switch_on_Bkg.getWidth() - slip_Btn.getWidth(); } Log.e("left_SlipBtn", left_SlipBtn + ""); canvas.drawBitmap(slip_Btn, left_SlipBtn, 0, paint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub Log.e("widthMeasureSpec", widthMeasureSpec + ""); Log.e("heightMeasureSpec", heightMeasureSpec + ""); setMeasuredDimension(switch_on_Bkg.getWidth(), switch_on_Bkg.getHeight()); Log.e("switch_on_Bkg", switch_on_Bkg.getWidth() + ""); Log.e("switch_on_Bkg", switch_on_Bkg.getHeight() + ""); } @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub switch (event.getAction()) { // 滑动 case MotionEvent.ACTION_MOVE: Log.e("===========", "move"); currentX = event.getX(); break; // 按下 case MotionEvent.ACTION_DOWN: if (event.getX() > switch_on_Bkg.getWidth() || event.getY() > switch_on_Bkg.getHeight()) { return false; } Log.e("===========", "down"); isSlipping = true; previousX = event.getX(); currentX = previousX; break; // 松开 case MotionEvent.ACTION_UP: isSlipping = false; // 松开前开关的状态 Log.e("============", "up"); boolean previousSwitchState = isSwitchOn; if (event.getX() >= (switch_on_Bkg.getWidth() / 2)) { isSwitchOn = true; } else { isSwitchOn = false; } // 如果设置了监听器,则调用此方法 if (isSwitchListenerOn && (previousSwitchState != isSwitchOn)) { onSwitchListener.onSwitched(isSwitchOn); } break; default: break; } // 重新绘制控件 invalidate(); return true; } public void setOnSwitchListener(OnSwitchListener listener) { onSwitchListener = listener; isSwitchListenerOn = true; } public interface OnSwitchListener { abstract void onSwitched(boolean isSwitchOn); }}上面是实现功能的代码,有几个问题希望能帮忙解答。1、在判断是否滑动时,left_SlipBtn = currentX - slip_Btn.getWidth() / 2;为什么减去游标的1/22、实际效果游标和背景边缘有间距,边缘为什么不重合 回帖记得引用,不然别人根本不知道你回复就是贴了哪些代码才知道哪的问题,你这估计是解析布局 switch_on_Bkg为null了,所以才提示空指针,不过运行起来应该是没问题的能帮我看下另一个问题吗public class MySlipSwitch extends View implements OnTouchListener { // 开关开启时的背景,关闭时的背景,滑动按钮 private Bitmap switch_on_Bkg, switch_off_Bkg, slip_Btn; private Rect on_Rect, off_Rect; // 是否正在滑动 private boolean isSlipping = false; // 当前开关状态,true为开启,false为关闭 private boolean isSwitchOn = false; // 手指按下时的水平坐标X,当前的水平坐标X private float previousX, currentX = 80; // 开关监听器 private OnSwitchListener onSwitchListener; // 是否设置了开关监听器 private boolean isSwitchListenerOn = false; public MySlipSwitch(Context context) { super(context); init(); } public MySlipSwitch(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { setOnTouchListener(this); } protected void setImageResource(int switchOnBkg, int switchOffBkg, int slipBtn) { switch_on_Bkg = BitmapFactory.decodeResource(getResources(), switchOnBkg); switch_off_Bkg = BitmapFactory.decodeResource(getResources(), switchOffBkg); slip_Btn = BitmapFactory.decodeResource(getResources(), slipBtn); // 右半边Rect,即滑动按钮在右半边时表示开关开启 on_Rect = new Rect(switch_off_Bkg.getWidth() - slip_Btn.getWidth(), 0, switch_off_Bkg.getWidth(), slip_Btn.getHeight()); // 左半边Rect,即滑动按钮在左半边时表示开关关闭 off_Rect = new Rect(0, 0, slip_Btn.getWidth(), slip_Btn.getHeight()); } // 设置开关状态 protected void setSwitchState(boolean switchState) { isSwitchOn = switchState; Log.e("========", "set"); } // 获取开关状态 protected boolean getSwitchState() { return isSwitchOn; } protected void updateSwitchState(boolean switchState) { isSwitchOn = switchState; Log.e("==========", "update"); invalidate(); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); Matrix matrix = new Matrix(); Paint paint = new Paint(); // 滑动按钮的左边坐标 float left_SlipBtn; // 手指滑动到左半边的时候表示开关为关闭状态,滑动到右半边的时候表示开关为开启状态 if (currentX < (switch_on_Bkg.getWidth() / 2)) { canvas.drawBitmap(switch_off_Bkg, matrix, paint); } else { canvas.drawBitmap(switch_on_Bkg, matrix, paint); } // 判断当前是否正在滑动 if (isSlipping) { if (currentX > switch_on_Bkg.getWidth()) { Log.e("=========", "slip"); left_SlipBtn = switch_on_Bkg.getWidth() - slip_Btn.getWidth(); } else { Log.e("=========", "slip"); left_SlipBtn = currentX - slip_Btn.getWidth() / 2; // 为什么是减1/2 } } else { // 根据当前的开关状态设置滑动按钮的位置 if (isSwitchOn) { Log.e("isSwitchOn", isSwitchOn + ""); Log.e("currentX", currentX + ""); Log.e("=========", "on"); left_SlipBtn = on_Rect.left; } else { Log.e("=========", "off"); left_SlipBtn = off_Rect.left; } } // 对滑动按钮的位置进行异常判断 if (left_SlipBtn < 0) { left_SlipBtn = 0; } else if (left_SlipBtn > switch_on_Bkg.getWidth()- slip_Btn.getWidth()) { left_SlipBtn = switch_on_Bkg.getWidth() - slip_Btn.getWidth(); } Log.e("left_SlipBtn", left_SlipBtn + ""); canvas.drawBitmap(slip_Btn, left_SlipBtn, 0, paint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub Log.e("widthMeasureSpec", widthMeasureSpec + ""); Log.e("heightMeasureSpec", heightMeasureSpec + ""); setMeasuredDimension(switch_on_Bkg.getWidth(), switch_on_Bkg.getHeight()); Log.e("switch_on_Bkg", switch_on_Bkg.getWidth() + ""); Log.e("switch_on_Bkg", switch_on_Bkg.getHeight() + ""); } @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub switch (event.getAction()) { // 滑动 case MotionEvent.ACTION_MOVE: Log.e("===========", "move"); currentX = event.getX(); break; // 按下 case MotionEvent.ACTION_DOWN: if (event.getX() > switch_on_Bkg.getWidth() || event.getY() > switch_on_Bkg.getHeight()) { return false; } Log.e("===========", "down"); isSlipping = true; previousX = event.getX(); currentX = previousX; break; // 松开 case MotionEvent.ACTION_UP: isSlipping = false; // 松开前开关的状态 Log.e("============", "up"); boolean previousSwitchState = isSwitchOn; if (event.getX() >= (switch_on_Bkg.getWidth() / 2)) { isSwitchOn = true; } else { isSwitchOn = false; } // 如果设置了监听器,则调用此方法 if (isSwitchListenerOn && (previousSwitchState != isSwitchOn)) { onSwitchListener.onSwitched(isSwitchOn); } break; default: break; } // 重新绘制控件 invalidate(); return true; } public void setOnSwitchListener(OnSwitchListener listener) { onSwitchListener = listener; isSwitchListenerOn = true; } public interface OnSwitchListener { abstract void onSwitched(boolean isSwitchOn); }}实际效果游标和背景边缘有间距,边缘为什么不重合 在构造函数中加句代码试试 if (isInEditMode()) { return; } android跟新进度条,求指点! 看Surface_lockCanvas里,别人加了断代码不知道有什么含义 我这样的水平适合学android?求老师级点评。 如何将xml资源打包到apk并自动释放到指定路径? android网格设置 新手请教Android牛人调用notifyDataSetChanged()报错 安卓网页版开发问题???(急急急) android 点击操作的切换 onclick操作 UC的悬浮窗问题 android 5.0 APK安装失败问题 [菜鸟提问]用Android源码编译应用程序和用SDK编译有什么不同? 关于sharedpreferences的错误
public class MySlipSwitch extends View implements OnTouchListener { // 开关开启时的背景,关闭时的背景,滑动按钮
private Bitmap switch_on_Bkg, switch_off_Bkg, slip_Btn;
private Rect on_Rect, off_Rect; // 是否正在滑动
private boolean isSlipping = false;
// 当前开关状态,true为开启,false为关闭
private boolean isSwitchOn = false; // 手指按下时的水平坐标X,当前的水平坐标X
private float previousX, currentX = 80; // 开关监听器
private OnSwitchListener onSwitchListener;
// 是否设置了开关监听器
private boolean isSwitchListenerOn = false; public MySlipSwitch(Context context) {
super(context);
init();
} public MySlipSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} private void init() {
setOnTouchListener(this);
} protected void setImageResource(int switchOnBkg, int switchOffBkg,
int slipBtn) {
switch_on_Bkg = BitmapFactory.decodeResource(getResources(),
switchOnBkg);
switch_off_Bkg = BitmapFactory.decodeResource(getResources(),
switchOffBkg);
slip_Btn = BitmapFactory.decodeResource(getResources(), slipBtn); // 右半边Rect,即滑动按钮在右半边时表示开关开启
on_Rect = new Rect(switch_off_Bkg.getWidth() - slip_Btn.getWidth(), 0,
switch_off_Bkg.getWidth(), slip_Btn.getHeight());
// 左半边Rect,即滑动按钮在左半边时表示开关关闭
off_Rect = new Rect(0, 0, slip_Btn.getWidth(), slip_Btn.getHeight());
} // 设置开关状态
protected void setSwitchState(boolean switchState) {
isSwitchOn = switchState;
Log.e("========", "set");
} // 获取开关状态
protected boolean getSwitchState() {
return isSwitchOn;
} protected void updateSwitchState(boolean switchState) {
isSwitchOn = switchState;
Log.e("==========", "update");
invalidate();
} @Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas); Matrix matrix = new Matrix();
Paint paint = new Paint();
// 滑动按钮的左边坐标
float left_SlipBtn; // 手指滑动到左半边的时候表示开关为关闭状态,滑动到右半边的时候表示开关为开启状态
if (currentX < (switch_on_Bkg.getWidth() / 2)) {
canvas.drawBitmap(switch_off_Bkg, matrix, paint);
} else {
canvas.drawBitmap(switch_on_Bkg, matrix, paint);
} // 判断当前是否正在滑动
if (isSlipping) {
if (currentX > switch_on_Bkg.getWidth()) {
Log.e("=========", "slip");
left_SlipBtn = switch_on_Bkg.getWidth() - slip_Btn.getWidth();
}
else {
Log.e("=========", "slip");
left_SlipBtn = currentX - slip_Btn.getWidth() / 2; // 为什么是减1/2 }
}
else {
// 根据当前的开关状态设置滑动按钮的位置
if (isSwitchOn) {
Log.e("isSwitchOn", isSwitchOn + "");
Log.e("currentX", currentX + "");
Log.e("=========", "on");
left_SlipBtn = on_Rect.left;
} else {
Log.e("=========", "off");
left_SlipBtn = off_Rect.left;
}
} // 对滑动按钮的位置进行异常判断
if (left_SlipBtn < 0) {
left_SlipBtn = 0;
} else if (left_SlipBtn > switch_on_Bkg.getWidth()- slip_Btn.getWidth()) {
left_SlipBtn = switch_on_Bkg.getWidth() - slip_Btn.getWidth();
}
Log.e("left_SlipBtn", left_SlipBtn + "");
canvas.drawBitmap(slip_Btn, left_SlipBtn, 0, paint);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
Log.e("widthMeasureSpec", widthMeasureSpec + "");
Log.e("heightMeasureSpec", heightMeasureSpec + "");
setMeasuredDimension(switch_on_Bkg.getWidth(),
switch_on_Bkg.getHeight());
Log.e("switch_on_Bkg", switch_on_Bkg.getWidth() + "");
Log.e("switch_on_Bkg", switch_on_Bkg.getHeight() + "");
} @Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction()) {
// 滑动
case MotionEvent.ACTION_MOVE:
Log.e("===========", "move");
currentX = event.getX();
break; // 按下
case MotionEvent.ACTION_DOWN:
if (event.getX() > switch_on_Bkg.getWidth()
|| event.getY() > switch_on_Bkg.getHeight()) {
return false;
}
Log.e("===========", "down");
isSlipping = true;
previousX = event.getX();
currentX = previousX;
break; // 松开
case MotionEvent.ACTION_UP:
isSlipping = false;
// 松开前开关的状态
Log.e("============", "up");
boolean previousSwitchState = isSwitchOn; if (event.getX() >= (switch_on_Bkg.getWidth() / 2)) {
isSwitchOn = true;
} else {
isSwitchOn = false;
} // 如果设置了监听器,则调用此方法
if (isSwitchListenerOn && (previousSwitchState != isSwitchOn)) {
onSwitchListener.onSwitched(isSwitchOn);
}
break; default:
break;
} // 重新绘制控件
invalidate();
return true;
} public void setOnSwitchListener(OnSwitchListener listener) {
onSwitchListener = listener;
isSwitchListenerOn = true;
} public interface OnSwitchListener {
abstract void onSwitched(boolean isSwitchOn);
}
}上面是实现功能的代码,有几个问题希望能帮忙解答。
1、在判断是否滑动时,left_SlipBtn = currentX - slip_Btn.getWidth() / 2;为什么减去游标的1/2
2、实际效果游标和背景边缘有间距,边缘为什么不重合
回帖记得引用,不然别人根本不知道你回复就是贴了哪些代码才知道哪的问题,你这估计是解析布局 switch_on_Bkg为null了,所以才提示空指针,不过运行起来应该是没问题的
能帮我看下另一个问题吗
public class MySlipSwitch extends View implements OnTouchListener { // 开关开启时的背景,关闭时的背景,滑动按钮
private Bitmap switch_on_Bkg, switch_off_Bkg, slip_Btn;
private Rect on_Rect, off_Rect; // 是否正在滑动
private boolean isSlipping = false;
// 当前开关状态,true为开启,false为关闭
private boolean isSwitchOn = false; // 手指按下时的水平坐标X,当前的水平坐标X
private float previousX, currentX = 80; // 开关监听器
private OnSwitchListener onSwitchListener;
// 是否设置了开关监听器
private boolean isSwitchListenerOn = false; public MySlipSwitch(Context context) {
super(context);
init();
} public MySlipSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} private void init() {
setOnTouchListener(this);
} protected void setImageResource(int switchOnBkg, int switchOffBkg,
int slipBtn) {
switch_on_Bkg = BitmapFactory.decodeResource(getResources(),
switchOnBkg);
switch_off_Bkg = BitmapFactory.decodeResource(getResources(),
switchOffBkg);
slip_Btn = BitmapFactory.decodeResource(getResources(), slipBtn); // 右半边Rect,即滑动按钮在右半边时表示开关开启
on_Rect = new Rect(switch_off_Bkg.getWidth() - slip_Btn.getWidth(), 0,
switch_off_Bkg.getWidth(), slip_Btn.getHeight());
// 左半边Rect,即滑动按钮在左半边时表示开关关闭
off_Rect = new Rect(0, 0, slip_Btn.getWidth(), slip_Btn.getHeight());
} // 设置开关状态
protected void setSwitchState(boolean switchState) {
isSwitchOn = switchState;
Log.e("========", "set");
} // 获取开关状态
protected boolean getSwitchState() {
return isSwitchOn;
} protected void updateSwitchState(boolean switchState) {
isSwitchOn = switchState;
Log.e("==========", "update");
invalidate();
} @Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas); Matrix matrix = new Matrix();
Paint paint = new Paint();
// 滑动按钮的左边坐标
float left_SlipBtn; // 手指滑动到左半边的时候表示开关为关闭状态,滑动到右半边的时候表示开关为开启状态
if (currentX < (switch_on_Bkg.getWidth() / 2)) {
canvas.drawBitmap(switch_off_Bkg, matrix, paint);
} else {
canvas.drawBitmap(switch_on_Bkg, matrix, paint);
} // 判断当前是否正在滑动
if (isSlipping) {
if (currentX > switch_on_Bkg.getWidth()) {
Log.e("=========", "slip");
left_SlipBtn = switch_on_Bkg.getWidth() - slip_Btn.getWidth();
}
else {
Log.e("=========", "slip");
left_SlipBtn = currentX - slip_Btn.getWidth() / 2; // 为什么是减1/2 }
}
else {
// 根据当前的开关状态设置滑动按钮的位置
if (isSwitchOn) {
Log.e("isSwitchOn", isSwitchOn + "");
Log.e("currentX", currentX + "");
Log.e("=========", "on");
left_SlipBtn = on_Rect.left;
} else {
Log.e("=========", "off");
left_SlipBtn = off_Rect.left;
}
} // 对滑动按钮的位置进行异常判断
if (left_SlipBtn < 0) {
left_SlipBtn = 0;
} else if (left_SlipBtn > switch_on_Bkg.getWidth()- slip_Btn.getWidth()) {
left_SlipBtn = switch_on_Bkg.getWidth() - slip_Btn.getWidth();
}
Log.e("left_SlipBtn", left_SlipBtn + "");
canvas.drawBitmap(slip_Btn, left_SlipBtn, 0, paint);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
Log.e("widthMeasureSpec", widthMeasureSpec + "");
Log.e("heightMeasureSpec", heightMeasureSpec + "");
setMeasuredDimension(switch_on_Bkg.getWidth(),
switch_on_Bkg.getHeight());
Log.e("switch_on_Bkg", switch_on_Bkg.getWidth() + "");
Log.e("switch_on_Bkg", switch_on_Bkg.getHeight() + "");
} @Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction()) {
// 滑动
case MotionEvent.ACTION_MOVE:
Log.e("===========", "move");
currentX = event.getX();
break; // 按下
case MotionEvent.ACTION_DOWN:
if (event.getX() > switch_on_Bkg.getWidth()
|| event.getY() > switch_on_Bkg.getHeight()) {
return false;
}
Log.e("===========", "down");
isSlipping = true;
previousX = event.getX();
currentX = previousX;
break; // 松开
case MotionEvent.ACTION_UP:
isSlipping = false;
// 松开前开关的状态
Log.e("============", "up");
boolean previousSwitchState = isSwitchOn; if (event.getX() >= (switch_on_Bkg.getWidth() / 2)) {
isSwitchOn = true;
} else {
isSwitchOn = false;
} // 如果设置了监听器,则调用此方法
if (isSwitchListenerOn && (previousSwitchState != isSwitchOn)) {
onSwitchListener.onSwitched(isSwitchOn);
}
break; default:
break;
} // 重新绘制控件
invalidate();
return true;
} public void setOnSwitchListener(OnSwitchListener listener) {
onSwitchListener = listener;
isSwitchListenerOn = true;
} public interface OnSwitchListener {
abstract void onSwitched(boolean isSwitchOn);
}
}实际效果游标和背景边缘有间距,边缘为什么不重合
return;
}