网上通过onTouch点击添加标签,按住拖动标签的方法都差不多,而长按删除标签很多都是采用在MotionEvent.ACTION_MOVE中判断是否有长按动作发生,但是这种方法在平板上实际操作的过程中交互性很差(可能个人能力的问题),所以长按删除采用了另外一种方式。
以下两种方式都提供了,供大家参考!
public class PictureTagLayout extends RelativeLayout implements View.OnTouchListener{
private static final int CLICKRANGE = 15;
private static final int INTERVAL = 500;
int startX = 0;
int startY = 0;
int startTouchViewLeft = 0;
int startTouchViewTop = 0;
View touchView;
boolean isLongClickModule = false;
boolean isLongClicking = false;
float downX = 0;
float downY = 0;
Context context;
Handler mHandler = null;
public PictureTagLayout(Context context) {
super(context, null);
}
public PictureTagLayout(Context context, AttributeSet attrs){
super(context, attrs);
this.setOnTouchListener(this);
this.context = context;
mHandler = new Handler();
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(touchView != null) {
((PictureTagView) touchView).setPressesState(false);
}
if(touchView != null && flag) {
((PictureTagView) touchView).setPressesState(true);
}
switch (motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:
//记录是为了加入长按事件
downX = motionEvent.getX();
downY = motionEvent.getY();
touchView = null;
startX = (int)motionEvent.getX();
startY = (int)motionEvent.getY();
if(hasView(startX,startY)){
startTouchViewLeft = touchView.getLeft();
startTouchViewTop = touchView.getTop();
} else{
addItem(startX, startY);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
longPressedDeleteView();
}
}, INTERVAL);
}
break;
case MotionEvent.ACTION_MOVE:
if(Math.abs(downX - motionEvent.getX()) > CLICKRANGE || Math.abs(downY - motionEvent.getY()) > CLICKRANGE){
mHandler.removeCallbacksAndMessages(null);
moveView((int)motionEvent.getX(), (int)motionEvent.getY());
}
// if(!isLongClickModule){
// isLongClickModule = isLongPressed(downX, downY, motionEvent.getX(), motionEvent.getY(),
// motionEvent.getDownTime(), motionEvent.getEventTime(), INTERVAL);
// }
// if(isLongClickModule && !isLongClicking){
// if(hasView((int)downX, (int)downY)){
// //处理长按事件
// ((PictureTagView)touchView).setPressesState(true);
// flag = true;
// isLongClicking = true;
// ConfirmCustomDialog.Builder dialog = new ConfirmCustomDialog.Builder(context);
// dialog.setTitle("提示");
// dialog.setMessage("您确定要删除标签么");
// dialog.setPositiveButton(new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialogInterface, int i) {
// dialogInterface.dismiss();
// //长按删除
// PictureTagLayout.this.removeView(touchView);
// flag = false;
// }
// });
// dialog.setNegativeButton(new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialogInterface, int i) {
// ((PictureTagView)touchView).setPressesState(false);
// dialogInterface.dismiss();
// flag = false;
// }
// });
// dialog.create().show();
// }
// }else {
// moveView((int)motionEvent.getX(), (int)motionEvent.getY());
// }
break;
case MotionEvent.ACTION_UP:
if(isLongClickModule){
isLongClickModule = false;
isLongClicking = false;
}else{
int endX = (int)motionEvent.getX();
int endY = (int)motionEvent.getY();
if(touchView != null){
((PictureTagView)touchView).setPressesState(false);
}
//如果挪动的范围很小,则判定为单击
if(touchView != null && Math.abs(endX - startX) < CLICKRANGE && Math.abs(endY - startY) < CLICKRANGE){
((PictureTagView)touchView).setPressesState(true);
final ChoiceCustomDialog.Builder builder = new ChoiceCustomDialog.Builder(context);
builder.setTitle("XXXXXXX");
builder.setItems(new String[]{"XX", "XX", "XX", "XX", "XX"});
builder.setOnChoiceListener(new ChoiceCustomDialog.Builder.OnChoiceListener() {
@Override
public void onClick(String item, int which) {
((PictureTagView)touchView).setPressesState(false);
}
});
builder.setNegativeButton(new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
((PictureTagView)touchView).setPressesState(false);
dialogInterface.dismiss();
}
});
builder.create().show();
}
}
break;
}
return true;
}
private boolean hasView(int x, int y) {
//循环获取子view,判断xy是否在子view上,即判断是否按住了子view
for(int index = 0; index < this.getChildCount(); index ++){
View view = this.getChildAt(index);
int left = (int) view.getX();
int top = (int) view.getY();
int right = view.getRight();
int bottom = view.getBottom();
Rect rect = new Rect(left, top, right, bottom);
boolean contains = rect.contains(x, y);
//如果是与子view重叠则返回真,表示已经有了view不需要添加新view了
if(contains){
touchView = view;
touchView.bringToFront();
return true;
}
}
touchView = null;
return false;
}
private void addItem(int x, int y) {
View view = null;
view = new PictureTagView(getContext());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
params.leftMargin = x;
params.topMargin = y;
((PictureTagView)view).setPressesState(true);
this.addView(view, params);
final ChoiceCustomDialog.Builder builder = new ChoiceCustomDialog.Builder(context);
builder.setTitle("XXXXXXXX");
builder.setItems(new String[]{"XX", "XX", "XX", "XX", "XX"});
View finalView1 = view;
builder.setOnChoiceListener(new ChoiceCustomDialog.Builder.OnChoiceListener() {
@Override
public void onClick(String item, int which) {
((PictureTagView) finalView1).setPressesState(false);
}
});
View finalView = view;
builder.setNegativeButton(new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
((PictureTagView) finalView).setPressesState(false);
dialogInterface.dismiss();
}
});
builder.create().show();
}
private void moveView(int x, int y){
if(touchView == null)
return;
RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
params.leftMargin = x - startX + startTouchViewLeft;
params.topMargin = y - startY + startTouchViewTop;
//限制子控件移动必须在视图范围内
if(params.leftMargin<0||(params.leftMargin+touchView.getWidth())>getWidth())params.leftMargin = touchView.getLeft();
if(params.topMargin<0||(params.topMargin+touchView.getHeight())>getHeight())params.topMargin = touchView.getTop();
((PictureTagView)touchView).setPressesState(true);
touchView.setLayoutParams(params);
}
/*判断是否有长按动作发生:
@param lastX 按下时X坐标
@param lastY 按下时Y坐标
@param thisX 移动时X坐标
@param thisY 移动时Y坐标
@param lastDownTime 按下时间
@param thisEventTime 移动时间
@param longPressTime 判断长按时间的阈值 */
private boolean isLongPressed(float lastX, float lastY, float thisX, float thisY,
long lastDownTime, long thisEventTime, long longPressTime){
float offsetX = Math.abs(thisX - lastX);
float offsetY = Math.abs(thisY - lastY);
long intervalTime = thisEventTime - lastDownTime;
if(offsetX <= CLICKRANGE && offsetY <= CLICKRANGE && intervalTime >= longPressTime) {
return true;
}
return false;
}
private void longPressedDeleteView(){
if(touchView != null){
isLongClickModule = true;
flag = true;
((PictureTagView)touchView).setPressesState(true);
ConfirmCustomDialog.Builder dialog = new ConfirmCustomDialog.Builder(context);
dialog.setTitle("提示");
dialog.setMessage("您确定要删除标签么");
dialog.setPositiveButton(new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
//长按删除
PictureTagLayout.this.removeView(touchView);
flag = false;
}
});
dialog.setNegativeButton(new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
((PictureTagView)touchView).setPressesState(false);
dialogInterface.dismiss();
flag = false;
}
});
dialog.create().show();
}
}
}
public class PictureTagView extends RelativeLayout {
private Context context;
private ImageView imageViewPoint;
public PictureTagView(Context context) {
super(context);
this.context = context;
LayoutInflater.from(context).inflate(R.layout.layout_config_calibration_point, this, true);
imageViewPoint = (ImageView)findViewById(R.id.imgCalibrationPoint);
// AnimationDrawable animationDrawable = (AnimationDrawable)imageViewPoint.getDrawable();
// animationDrawable.start();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
}
public void setPressesState(boolean flag){
if(flag){
imageViewPoint.setImageResource(R.drawable.mark_point_pressed);
}else{
imageViewPoint.setImageResource(R.drawable.mark_point);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/imgCalibrationPoint"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="7dp"/>
</LinearLayout>