实现效果: 鼠标拖动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() { @Override public void onClick(View v) { // TODO Auto-generated method stub Log.i(tag,"btn clicked"); } }); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); } OnTouchListener touchLisener=new OnTouchListener() { int lastX, lastY; @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub switch (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弹出输入法的时候,那个拖动条会回到初始的位置,这是何故?