点击图像,图像随手指的一定而一定。移动只要的靠的就是View中的layout(int left,int top,int right ,int button)方法。
拖动两个图像到上下接壤的位置,拖动上面一个可以一起拖动这两个图像,拖动下面一个图像,则只会拖动下面一个图像。
这里偏移距离用的还是layout方法,但是需要试用到回掉接口,在其中一个View移动时判断是否一起移动,再回调数据。
分析:
第一个程序只需要重写自定义View的类,所有的处理都是在自定义View中编写的,只要把这个自定义类放到布局文件中,点击它就会有拖拽的效果。
第二个程序处理要写两个自定义View,并且要定义回调接口,在拖拽其中一个View时,第二个也随之被拖动,这里就要在回调中返回移动的距离,从而确定另一个View要移动的距离。
代码:
package com.example.myview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
/**
* 自定义的View
*/
public class MyImageView extends ImageView {
private int lastX;
private int lastY;
public MyImageView(Context context) {
super(context);
}
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean onTouchEvent(MotionEvent event) {
//获取到手指处的横坐标和纵坐标
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN://手指按下时
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE://手指移动时
//计算移动的距离
int offX = x - lastX;
int offY = y - lastY;
//调用layout方法来重新放置它的位置
Log.e("TAG","距离左边="+getLeft()+offX+",距离顶部="+getTop()+offY+",距离右边="+ getRight()+offX+",距离底部="+ getBottom()+offY);
movingXY(offX,offY);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
public void movingXY(int offX,int offY){
//移动View的关键代码
layout(getLeft()+offX, getTop()+offY, getRight()+offX , getBottom()+offY);
}
}
<LinearLayout xm
lns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<com.example.myview.MyImageView
android:id="@+id/view1"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/view1"
/>
LinearLayout>
其实什么都不用写,显示出布局就可以了!
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
package com.example.myview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
/**
* 自定义的View
*/
public class MyImageView extends ImageView {
private int lastX;
private int lastY;
public MyImageView(Context context) {
super(context);
}
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean onTouchEvent(MotionEvent event) {
//获取到手指处的横坐标和纵坐标
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN://手指按下时
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE://手指移动时
//计算移动的距离
int offX = x - lastX;
int offY = y - lastY;
//调用layout方法来重新放置它的位置
Log.e("TAG","距离左边="+getLeft()+offX+",距离顶部="+getTop()+offY+",距离右边="+ getRight()+offX+",距离底部="+ getBottom()+offY);
movingXY(offX,offY);
//listenerData.getDataXY(offX,offY);
if (listenerData!=null){
listenerData.getDataXY(offX,offY);
}
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
public void movingXY(int offX,int offY){
//移动View的关键代码
layout(getLeft()+offX, getTop()+offY, getRight()+offX , getBottom()+offY);
}
//监听接口的定义,用来获得数据
interface ListenerData{
void getDataXY(int offX,int offY);
}
//定义一个接口对象
ListenerData listenerData;
}
这个自定义View比上面一个就是多了一个回调接口!
并且移动时判断回调对象是否为空,不为空就返回数据。
package com.example.myview;
import android.content.Context;
import android.util.AttributeSet;
/**
* 第一个视图
*/
public class MyImageView1 extends MyImageView {
public MyImageView1(Context context) {
super(context);
}
public MyImageView1(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
(三)自定义View的类3
package com.example.myview;
import android.content.Context;
import android.util.AttributeSet;
/**
* 第二个视图
*/
public class MyImageView2 extends MyImageView {
public MyImageView2(Context context) {
super(context);
}
public MyImageView2(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
上面两个指定View有相同的继承,因为要判断是哪一个视图的点击和移动事件,所以分开两个对象。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<View
android:layout_width="20dp"
android:layout_height="30dp"
/>
<com.example.myview.MyImageView1
android:id="@+id/view1"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/view1"
/>
<View
android:layout_width="20dp"
android:layout_height="30dp"
/>
<com.example.myview.MyImageView2
android:id="@+id/view2"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/view2"
/>
LinearLayout>
package com.example.myview;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
MyImageView1 imageView1;
MyImageView2 imageView2;
boolean connect12;//连接模块12,模块1在上面
boolean connect21;//连接模块21,模块2在上面
int clickView=0;//点击的是哪一个模块
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView1= (MyImageView1) findViewById(R.id.view1);
imageView2= (MyImageView2) findViewById(R.id.view2);
//这里每个监听对象对应一个回调的方法
MyImageView1.ListenerData listenerData=new MyImageView1.ListenerData() {
@Override
public void getDataXY(int offX, int offY) {
Log.e("TAG","点击的视图:"+1111+"");
clickView=1;
if ((imageView2.getTop()-imageView1.getBottom())<20&&(imageView2.getTop()-imageView1.getBottom())>0&&Math.abs(imageView1.getLeft()-imageView2.getLeft())<30){
int y=imageView1.getBottom()-imageView2.getTop();
connect12=true;
}
if (connect12){
imageView2.movingXY(offX,offY);
}
if ((imageView1.getTop()-imageView2.getBottom())>20){
connect21=false;
}
}
};
MyImageView2.ListenerData listenerData2=new MyImageView2.ListenerData() {
@Override
public void getDataXY(int offX, int offY) {
clickView=2;
Log.e("TAG", "点击的视图:" + 22 + "");
if ((imageView2.getTop()-imageView1.getBottom())>20){
connect12=false;
}
if ((imageView1.getTop()-imageView2.getBottom())<20&&(imageView1.getTop()-imageView2.getBottom())>0&&Math.abs(imageView1.getLeft()-imageView2.getLeft())<30){
connect21=true;
}
if (connect21){
imageView1.movingXY(offX,offY);
}
}
};
//实例化View中的回调对象,示例化之后才能再自定义类中对应的方法得到回调
imageView1.listenerData=listenerData;
imageView2.listenerData=listenerData2;
}
}
getLeft(),getTop(),getRight(),getButtom()
视图左侧位置 view.getLeft()
视图右侧位置 view.getRight()
视图顶部位置 view.getTop();
视图底部位置 view.getBottom();
视图宽度 view.getWidth();
视图高度 view.getHeight()