拖动一个控件在另一个控件(layout)上,并固定位置在几个位置显示

实现效果: 鼠标拖动btn SSS,SSS在水平的layout上移动。 当鼠标抬起 响应UP事件。SSS会自动移动到距离其最近的Btn上,与其重合。即SSS如图只存在五个固定的显示位置。
SSS响应setOnTouchListener事件。
在MotionEvent.ACTION_UP事件中,调用TranslateAnimation动画效果,将其从UP事件位置移动到最近的btn所在位置。
即在UP事件中,响应函数:
private void setPosition() { int positionPixel = (touchBtn.getLeft()+touchBtn.getRight())/2; int positionIndex = (positionPixel)/btn[1].getWidth(); int toPosition = positionIndex*btn[1].getWidth()+touchBtn.getWidth()/2; touchBtn.layout(positionIndex*btn[1].getWidth(), touchBtn.getTop(),positionIndex*btn[1].getWidth()+touchBtn.getWidth(), touchBtn.getBottom()); MoveAction = new TranslateAnimation(positionPixel - toPosition,0,0,0); MoveAction.setDuration(500); touchBtn.startAnimation(MoveAction);// touchBtn.invalidate(); }动画效果,将其移动到最近位置上
或者也可以这样计算:
/***获得最佳停留位置*/private void setBestPosition(View v) {int width=v.getWidth(); int left = v.getLeft(); int selectedPosition = Math.round(1.0F*left/width);//四舍五入 int toPosition = selectedPosition*width; v.layout(selectedPosition*width, v.getTop(), selectedPosition*width+width, v.getBottom()); TranslateAnimation animation = new TranslateAnimation(left-toPosition,0,0,0); animation.setInterpolator(new LinearInterpolator()); animation.setDuration(400); animation.setFillAfter(true); v.startAnimation(animation); // v.invalidate(); }全代码:
public class App extends Activity{private static final String tag="App";private Context context;private FrameLayout container;private Button btn; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); context=this; container=(FrameLayout)findViewById(R.id.container); btn=(Button)findViewById(R.id.btn); btn.setBackgroundResource(R.drawable.tabswitcher_short); btn.setOnTouchListener(touchLisener); btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubLog.i(tag,"btn clicked");}}); } @Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();}OnTouchListener touchLisener=new OnTouchListener() { int lastX, lastY;@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubswitch (event.getAction()) {case MotionEvent.ACTION_DOWN:lastX = (int) event.getRawX(); lastY = (int) event.getRawY();break;case MotionEvent.ACTION_MOVE:int dx = (int) event.getRawX() - lastX; //int dy = (int) event.getRawY() - lastY; int dy = 0; int left = v.getLeft() + dx; int top = v.getTop() + dy; int right = v.getRight() + dx; int bottom = v.getBottom() + dy; if (left < 0) { left = 0; right = left + v.getWidth(); } if (right > container.getMeasuredWidth()) { right = container.getMeasuredWidth(); left = right - v.getWidth(); } if (top < 0) { top = 0; bottom = top + v.getHeight(); } if (bottom > container.getMeasuredHeight()) { bottom = container.getMeasuredHeight(); top = bottom - v.getHeight(); } v.layout(left, top, right, bottom); lastX = (int) event.getRawX(); lastY = (int) event.getRawY();break;case MotionEvent.ACTION_UP:setBestPosition(v);break;default:break;}return false;}};private void setBestPosition(View v) {int width=v.getWidth(); int left = v.getLeft(); int selectedPosition = Math.round(1.0F*left/width);//四舍五入 int toPosition = selectedPosition*width; v.layout(selectedPosition*width, v.getTop(), selectedPosition*width+width, v.getBottom()); TranslateAnimation animation = new TranslateAnimation(left-toPosition,0,0,0); animation.setInterpolator(new LinearInterpolator()); animation.setDuration(400); animation.setFillAfter(true); v.startAnimation(animation); // v.invalidate(); }}布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.ql.app" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="TEST DRAG"android:textSize="20sp"/> <FrameLayout android:id="@+id/container" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" > <Button android:id="@+id/btn" android:layout_width="80dp"android:layout_height="wrap_content"android:text="drag me!" /> </FrameLayout> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" /></LinearLayout>
但是这样有个问题:当点击EditText弹出输入法的时候,那个拖动条会回到初始的位置,这是何故?