1,安卓自定义View总体来说有三种方式
1,继承自View
2,继承自ViewGroup
3,继承自ViewGroup子类
需要重写三个方法onMeasure onLayout onDraw
2,安卓View坐标
http://android.jobbole.com/83276/
3,继承ViewGroup子类实例
1,实例背景
产品设计,要滑动,可点击,点击后可弹出车辆信息(原始控件无法实现)
2,实现思想
继承RelativeLayout,背景,拖动车辆都事先写进layout文件中,自行控制onTouch事件
3,实现效果
![]()
public class SlideThreeSelectView extends RelativeLayout {
@InjectView(R.id.cartype_background)
ImageView mBackgroundView;
@InjectView(R.id.cartype_car)
ImageView mCarTypeView;
private DisplayMetrics mdDisplayMetrics;
private int mHalfScreenWidth;
public SlideThreeSelectView(Context context) {
this(context, null);
}
public SlideThreeSelectView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
initView();
initListener();
}
private void initView() {
View view = View.inflate(getContext(), R.layout.select_three_cartype_view, this);
ButterKnife.inject(view);
mdDisplayMetrics = new DisplayMetrics();
mdDisplayMetrics = getResources().getDisplayMetrics();
mHalfScreenWidth = mdDisplayMetrics.widthPixels / 2; //获取一般屏幕宽度
}
private void initListener() {
//为本就添加onTouch事件是为了响应点击车出现popupwindow显示车辆详情
mBackgroundView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int backgroundWidth = mBackgroundView.getWidth();
int offSetLength = backgroundWidth / 4;
int carTypeViewHalfLength = mCarTypeView.getWidth() / 2;
int carTypeViewHigh = mCarTypeView.getHeight();
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
int upX = (int) event.getRawX();
updateCarTypeStatus(offSetLength, carTypeViewHalfLength, carTypeViewHigh, upX);
break;
default:
break;
}
return true;
}
});
mCarTypeView.setOnTouchListener(new OnTouchListener() {
private int mStartX = 0; //x记录起始位置
@Override
public boolean onTouch(View v, MotionEvent event) {
int backgroundLeft = mBackgroundView.getLeft(); //背景左边坐标
int backgroundWidth = mBackgroundView.getWidth(); //背景宽度
int offSetLength = backgroundWidth / 4; //背景1/4宽度
int carTypeViewHalfLength = mCarTypeView.getWidth() / 2; //车辆宽度 1/2
int carTypeViewHigh = mCarTypeView.getHeight(); //车辆高度
int upX; //为了在松开手时车辆弹回使用
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartX = (int) event.getRawX(); //按下时的x轴坐标
break;
case MotionEvent.ACTION_MOVE:
int newX = (int) event.getRawX(); //移动时 x坐标
int dX = newX - mStartX; //移动坐标 - 按下坐标 记录偏移量
int newl = mCarTypeView.getLeft() + dX; //车辆图片加入left right添加偏移量
int newr = mCarTypeView.getRight() + dX;
if (newl <= backgroundLeft || newr > (backgroundLeft + backgroundWidth)) { // 左侧坐标偏移过背景左侧,右侧坐标偏移过背景右侧,不处理
break;
}
mCarTypeView.layout(
mCarTypeView.getLeft() + dX,
mCarTypeView.getTop(),
mCarTypeView.getRight() + dX,
mCarTypeView.getBottom()); //将坐标设置进去 实现车辆跟随手指移动,只是移动了x轴,top bottom不变
mStartX = (int) event.getRawX(); //记录x新的起始位置
break;
case MotionEvent.ACTION_CANCEL://个人理解这个状态是 甩手的 状态跟 up类似
upX = (int) event.getRawX();
updateCarTypeStatus(offSetLength, carTypeViewHalfLength, carTypeViewHigh, upX);
break;
case MotionEvent.ACTION_UP:
upX = (int) event.getRawX(); //手指抬起时记录 抬起时x轴的位置
updateCarTypeStatus(offSetLength, carTypeViewHalfLength, carTypeViewHigh, upX);
break;
default:
break;
}
return true; //如果让车子响应onclick方法这个要返回false
}
});
}
/**
* 手指抬起后,实现车辆回弹。不能你拖到哪里就在哪里,那样有点太尴尬了 --- 这里的定位方式是要画图说明的
* @param offSetLength
* @param carTypeViewHalfLength
* @param carTypeViewHigh
* @param upX
*/
private void updateCarTypeStatus(int offSetLength, int carTypeViewHalfLength, int carTypeViewHigh, int upX) {
if (upX < mHalfScreenWidth - offSetLength) { //如果在中间偏左,那就定位在左边
mCarTypeView.layout(
mBackgroundView.getLeft(),
mBackgroundView.getTop(),
mBackgroundView.getLeft() + (2 * carTypeViewHalfLength),
mBackgroundView.getTop() + carTypeViewHigh);
} else if (upX >= (mHalfScreenWidth - offSetLength) && upX <= (mHalfScreenWidth + offSetLength)) { //如果在中间,那就定位在中间
mCarTypeView.layout(
mBackgroundView.getLeft() + (2 * offSetLength) - carTypeViewHalfLength,
mBackgroundView.getTop(),
mBackgroundView.getLeft() + (2 * offSetLength) + carTypeViewHalfLength,
mBackgroundView.getTop() + carTypeViewHigh);
} else if (upX > (mHalfScreenWidth + offSetLength)) { //如果在中间偏右,那就定位在右边
mCarTypeView.layout(
mBackgroundView.getLeft() + (4 * offSetLength) - (2 * carTypeViewHalfLength),
mBackgroundView.getTop(),
mBackgroundView.getLeft() + (4 * offSetLength),
mBackgroundView.getTop() + carTypeViewHigh);
}
}
}
绘制view思路