Android:onTouchListener无法正常工作

时间:2012-06-04 08:25:43

标签: android android-layout ontouchlistener

我目前正在开发一款应用程序,其中RelativeLayout有4个子FrameLayouts,每个FrameLayout都有一组ImageViews,内部View有自己的行为。我正在尝试实施拖放到FrameLayouts,同时实现this tutorial中找到的onTouchListener。但不幸的是,拖放不能正常工作,也没有发生任何事情。

有关如何正确实现拖放的任何想法?我错过了什么?

<小时/> 这是FrameLayouts

的单个子项的xml代码
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="80dp"
    android:layout_height="108dp" >

    <ImageView
        android:id="@+id/secondImage"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/back" />

    <ImageView
        android:id="@+id/firstImage"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/c2" />

</FrameLayout>

<小时/> 这是main.xml

的xml代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/pinecropped"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/cardNumber1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:layout_marginTop="60dp" >

        <include layout="@layout/card" />
    </FrameLayout>

    <FrameLayout
        android:id="@+id/cardNumber2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/cardNumber1"
        android:layout_marginLeft="50dp"
        android:layout_marginTop="100dp" >

        <include layout="@layout/card" />
    </FrameLayout>

    <FrameLayout
        android:id="@+id/cardNumber3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="50dp"
        android:layout_marginTop="60dp" >

        <include layout="@layout/card" />
    </FrameLayout>

    <FrameLayout
        android:id="@+id/cardNumber4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/cardNumber3"
        android:layout_marginRight="50dp"
        android:layout_marginTop="100dp" >

        <include layout="@layout/card" />
    </FrameLayout>

</RelativeLayout>

<小时/> 这是单个子代的Java代码:

public class Card implements OnClickListener {
    private int _resId;

    private Context _context;
    private ImageView firstImage, secondImage;
    private boolean isFirst;

    public Card(Context context, FrameLayout parent) {
        _context = context;
        firstImage = (ImageView) parent.findViewById(R.id.firstImage);
        secondImage = (ImageView) parent.findViewById(R.id.secondImage);

    }

    public void setupCards(int resId, boolean hasBackSide) {
        _resId = resId;
        Bitmap temp = BitmapFactory.decodeResource(_context.getResources(),
                _resId);
        firstImage.setImageBitmap(temp);
        if (hasBackSide) {
            temp = BitmapFactory.decodeResource(_context.getResources(),
                    R.drawable.back);
        }
        secondImage.setImageBitmap(temp);
        isFirst = true;
        secondImage.setVisibility(View.GONE);

    }

    // MORE IMPLEMENTATION
}

<小时/> 这是我的主要活动Java代码:

public class FaceUpActivity extends Activity {
    FrameLayout firstCard, secondCard, thirdCard, forthCard;
    Card cardNumber1, cardNumber2, cardNumber3, cardNumber4;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        initUI();
    }

    private void initUI() {
        firstCard = (FrameLayout) findViewById(R.id.cardNumber1);
        secondCard = (FrameLayout) findViewById(R.id.cardNumber2);
        thirdCard = (FrameLayout) findViewById(R.id.cardNumber3);
        forthCard = (FrameLayout) findViewById(R.id.cardNumber4);

        cardNumber1 = new Card(this, firstCard);
        cardNumber2 = new Card(this, secondCard);
        cardNumber3 = new Card(this, thirdCard);
        cardNumber4 = new Card(this, forthCard);

        cardNumber1.setupCards(R.drawable.c2, true);
        cardNumber2.setupCards(R.drawable.d0, true);
        cardNumber3.setupCards(R.drawable.h5, true);
        cardNumber4.setupCards(R.drawable.sj, true);

        firstCard.setOnTouchListener(dragMe);
        secondCard.setOnTouchListener(dragMe);
        thirdCard.setOnTouchListener(dragMe);
        forthCard.setOnTouchListener(dragMe);

    }

    OnTouchListener dragMe = new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            FrameLayout.LayoutParams params = (LayoutParams) v
                    .getLayoutParams();
            int maxWidth = getWindowManager().getDefaultDisplay().getWidth();
            int maxHeight = getWindowManager().getDefaultDisplay().getHeight();
            int topMargin, leftMargin;

            int cond = v.getId();
            if (cond == R.id.cardNumber1 || cond == R.id.cardNumber2
                    || cond == R.id.cardNumber3 || cond == R.id.cardNumber4) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_UP:

                    topMargin = (int) event.getRawY() - (v.getHeight());
                    leftMargin = (int) event.getRawX() - (v.getWidth()) / 2;

                    if (topMargin < 0) {
                        params.topMargin = 0;
                    } else if (topMargin > maxHeight) {
                        params.topMargin = maxHeight - v.getHeight();
                    } else {
                        params.topMargin = topMargin;
                    }

                    if (leftMargin < 0) {
                        params.leftMargin = 0;
                    } else if (leftMargin > maxWidth) {
                        params.leftMargin = maxWidth - (v.getWidth() / 2);
                    } else {
                        params.leftMargin = leftMargin;
                    }

                    v.setLayoutParams(params);

                    break;

                case MotionEvent.ACTION_MOVE:

                    topMargin = (int) event.getRawY() - (v.getHeight());
                    leftMargin = (int) event.getRawX() - (v.getWidth()) / 2;

                    if (topMargin < 0) {
                        params.topMargin = 0;
                    } else if (topMargin > maxHeight) {
                        params.topMargin = maxHeight - v.getHeight();
                    } else {
                        params.topMargin = topMargin;
                    }

                    if (leftMargin < 0) {
                        params.leftMargin = 0;
                    } else if (leftMargin > maxWidth) {
                        params.leftMargin = maxWidth - (v.getWidth() / 2);
                    } else {
                        params.leftMargin = leftMargin;
                    }

                    v.setLayoutParams(params);

                    break;
                }
            }
            return true;
        }
    };
}

2 个答案:

答案 0 :(得分:0)

我认为有几个潜在的问题:

  1. 您确定在onTouch()中获得了正确的ID吗? (由于触摸侦听器仅用于您的卡片视图,因此您可以删除if ID检查)
  2. 你正在使用FrameLayout - 所以使用x和y位置而不是边距编辑:我的不好,你正在使用RelativeLayout,所以边距很友好是的。不过,我会使用FrameLayout代替
  3. API表示如果您使用了此活动,则需要在true中返回onTouch(),否则会false(当您未移动时,您将返回true卡片,而你什么都没做)

答案 1 :(得分:0)

为什么您的D&amp; D无效:

D&amp; D无效,因为您的卡(使用内部FrameLayout)正在实施“吃掉”d&amp; d事件的onClick事件。

解决方案有两个:

你可以有2个不同的区域,一个用于点击事件(卡的最大部分),一个用于d&amp; d事件(卡的左下边缘)。您可以在Android音乐播放器中看到实现此解决方案的实例。

否则你可以同时处理这两个事件:

  • 在相同的x / y位置同时(在100毫秒内)点击==向下+向上
  • dd ==在不同时间向下+向上(> 50 / 100ms)