实现效果: 鼠标拖动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弹出输入法的时候,那个拖动条会回到初始的位置,这是何故?