即: 支持 拖动图标 然后把之插入 2个View 之间
为了降低难度 选用了若干ImageView 放入ViewGroup : vertical LinearLayout
[代码 步骤]
1. 定义布局:main.xml :
- <? xml version = "1.0" encoding = "utf-8" ?>
- < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
- android:orientation = "vertical"
- android:layout_width = "fill_parent"
- android:layout_height = "fill_parent"
- android:id = "@+id/linear"
- >
- < ImageButton
- android:layout_width = "100dip"
- android:layout_height = "100dip"
- android:src = "@drawable/beijing1_b" />
- < ImageButton
- android:layout_width = "100dip"
- android:layout_height = "100dip"
- android:src = "@drawable/beijing2_b" />
- < ImageButton
- android:layout_width = "100dip"
- android:layout_height = "100dip"
- android:src = "@drawable/beijing3_b" />
- < ImageButton
- android:layout_width = "100dip"
- android:layout_height = "100dip"
- android:src = "@drawable/beijing3_b" />
- </ LinearLayout >
2. 变量初始化
- lLayout = (LinearLayout)findViewById(R.id.linear);
lLayout = (LinearLayout)findViewById(R.id.linear);
3. 定义OnTouchListener 用于监听所有动作 并注册LinearLayour的所有View 实现为:
- touchListener = new OnTouchListener(){
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- // TODO Auto-generated method stub
- int action = event.getAction();
- int x = ( int ) event.getRawX();
- int y = ( int ) event.getRawY();
- switch (action){
- //鼠标按下 拖拉动作开始
- case MotionEvent.ACTION_DOWN:
- point1 = v.getTop();
- startX = (int )event.getX();
- startY = y - v.getTop();
- break ;
- //鼠标移动 拖拉动作进行中
- case MotionEvent.ACTION_MOVE:
- v.layout(x - startX, y - startY, x + v.getWidth()
- - startX, y - startY + v.getHeight());
- v.bringToFront();
- v.postInvalidate();
- break ;
- //鼠标释放 拖拉动作结束
- case MotionEvent.ACTION_UP:
- point2 = v.getTop();
- //计算插入位置 位于哪两个相邻View之间
- int dest = getLocation(v);
- //remove ori view, and then add view here
- lLayout.removeView(v);
- lLayout.addView(v, dest);
- break ;
- }
- return false ;
- }
- };
- //to listener all ImageView
- for ( int i= 0 ;i<lLayout.getChildCount();i++){
- ImageView iv = (ImageView)lLayout.getChildAt(i);
- if (iv != null ){
- iv.setOnTouchListener(touchListener);
- }
- else {
- //error, view is null!
- }
- }
touchListener = new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch(action){
//鼠标按下 拖拉动作开始
case MotionEvent.ACTION_DOWN:
point1 = v.getTop();
startX = (int)event.getX();
startY = y - v.getTop();
break;
//鼠标移动 拖拉动作进行中
case MotionEvent.ACTION_MOVE:
v.layout(x - startX, y - startY, x + v.getWidth()
- startX, y - startY + v.getHeight());
v.bringToFront();
v.postInvalidate();
break;
//鼠标释放 拖拉动作结束
case MotionEvent.ACTION_UP:
point2 = v.getTop();
//计算插入位置 位于哪两个相邻View之间
int dest = getLocation(v);
//remove ori view, and then add view here
lLayout.removeView(v);
lLayout.addView(v, dest);
break;
}
return false;
}
};
//to listener all ImageView
for(int i=0;i<lLayout.getChildCount();i++){
ImageView iv = (ImageView)lLayout.getChildAt(i);
if(iv !=null){
iv.setOnTouchListener(touchListener);
}
else {
//error, view is null!
}
}
4. getLocation(View) 用于: 根据目标View 判断待插入的位置 即:哪2个相邻ImageView 之间 实现为:
- public int getLocation(View v){
- for ( int i= 0 ;i<lLayout.getChildCount()- 1 ;i++){
- ImageView iv = (ImageView)lLayout.getChildAt(i);
- ImageView iv2 = (ImageView)lLayout.getChildAt(i+1 );
- if (iv.getTop()< v.getTop() && iv2.getTop() > v.getTop()){
- //refer delta of point1 & point2
- if (point1 < point2){ //drag to bottom
- return i+ 1 ;
- }
- else { //drag to up
- return i+ 1 ;
- }
- }
- }
- //otherwise return last location
- return lLayout.getChildCount()- 1 ;
- }
public int getLocation(View v){
for(int i=0;i<lLayout.getChildCount()-1;i++){
ImageView iv = (ImageView)lLayout.getChildAt(i);
ImageView iv2 = (ImageView)lLayout.getChildAt(i+1);
if(iv.getTop()< v.getTop() && iv2.getTop() > v.getTop()){
//refer delta of point1 & point2
if(point1 < point2){//drag to bottom
return i+1;
}
else {//drag to up
return i+1;
}
}
}
//otherwise return last location
return lLayout.getChildCount()-1;
}
5. emulator 运行截图:
- 拖拉前:
- 拖拉后: