查找运动事件结束的视图(按钮)

时间:2012-07-05 23:47:35

标签: java android android-menu

问题

我正在寻找创建效果,初始按下按钮可将其他3个按钮的可见性设置为可见。在向一个新显示的按钮滑动并结束之后,我想开始一个不同的活动。

我的问题是,无论使用哪种方法来获取视图的位置(使用Rect对象,findNearestTouchable)和位置触摸事件(使用带有ACTION_UP的onTouch / Gestures),它们似乎永远不会匹配,我永远不会能够返回我想要的视图;

所需功能

一个动作事件,从按下按钮开始,到另一个按钮结束,返回它结束的按钮的id / view对象。

我的main_menu.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:fillViewport="true"
    android:orientation="vertical" >


    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Button"        
        android:tag="1"

        />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/button1"
        android:layout_marginBottom="36dp"
        android:layout_marginRight="19dp"
        android:layout_toLeftOf="@+id/button1"
        android:text="Button"
        android:visibility="gone"
        android:tag="3" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/button3"
        android:layout_alignBottom="@+id/button3"
        android:layout_toRightOf="@+id/button3"
        android:text="Button"
        android:visibility="gone" 
        android:tag="2"/>

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/button3"
        android:layout_alignBottom="@+id/button3"
        android:layout_alignParentRight="true"
        android:layout_marginRight="20dp"
        android:text="Button"
        android:visibility="gone"
        android:tag="4" />

</RelativeLayout>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="fill_parent" android:fillViewport="true" android:orientation="vertical" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="Button" android:tag="1" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/button1" android:layout_marginBottom="36dp" android:layout_marginRight="19dp" android:layout_toLeftOf="@+id/button1" android:text="Button" android:visibility="gone" android:tag="3" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button3" android:layout_alignBottom="@+id/button3" android:layout_toRightOf="@+id/button3" android:text="Button" android:visibility="gone" android:tag="2"/> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button3" android:layout_alignBottom="@+id/button3" android:layout_alignParentRight="true" android:layout_marginRight="20dp" android:text="Button" android:visibility="gone" android:tag="4" /> </RelativeLayout>

当前对Activity的尝试,没有设置(我对完全不同的实现非常开放)

foundit

public class Menu extends Activity {
    private GestureDetector gestureDetector;
    View.OnTouchListener gestureListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_menu);

        gestureDetector = new GestureDetector(new MyGestureDetector());
        gestureListener = new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                View findViewById2 = findViewById(R.id.button2);
                View findViewById3 = findViewById(R.id.button3);
                View findViewById4 = findViewById(R.id.button4);
                findViewById2.setVisibility(View.VISIBLE);
                findViewById3.setVisibility(View.VISIBLE);
                findViewById4.setVisibility(View.VISIBLE);
                return gestureDetector.onTouchEvent(event);
            }
        };
        View button = findViewById(R.id.button1);
        button.setOnTouchListener(gestureListener);

    }

    class MyGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {

            View foundit = null;
            ViewGroup menu = (ViewGroup) findViewById(R.id.button1).getParent();
            for (int numChildren = menu.getChildCount(); numChildren >= 0; --numChildren) {
                View child = menu.getChildAt(numChildren - 1);
                if (child instanceof Button) {
                    Rect bounds = new Rect();
                    child.getHitRect(bounds);
                    if (bounds.contains((int) e2.getX(), (int) e2.getY())) {
                        foundit = child;
                    }
                }
            }
            if (foundit != null) {
                Log.i("found", "FOUND IT");
            }
            return false;
        }

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
    }

}

有没有人有任何见解?

修改

测试以下内容: public class Menu extends Activity { private GestureDetector gestureDetector; View.OnTouchListener gestureListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_menu); gestureDetector = new GestureDetector(new MyGestureDetector()); gestureListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { View findViewById2 = findViewById(R.id.button2); View findViewById3 = findViewById(R.id.button3); View findViewById4 = findViewById(R.id.button4); findViewById2.setVisibility(View.VISIBLE); findViewById3.setVisibility(View.VISIBLE); findViewById4.setVisibility(View.VISIBLE); return gestureDetector.onTouchEvent(event); } }; View button = findViewById(R.id.button1); button.setOnTouchListener(gestureListener); } class MyGestureDetector extends SimpleOnGestureListener { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { View foundit = null; ViewGroup menu = (ViewGroup) findViewById(R.id.button1).getParent(); for (int numChildren = menu.getChildCount(); numChildren >= 0; --numChildren) { View child = menu.getChildAt(numChildren - 1); if (child instanceof Button) { Rect bounds = new Rect(); child.getHitRect(bounds); if (bounds.contains((int) e2.getX(), (int) e2.getY())) { foundit = child; } } } if (foundit != null) { Log.i("found", "FOUND IT"); } return false; } @Override public boolean onDown(MotionEvent e) { return true; } } }

产生以下LogCat输出:

    gestureListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            View findViewById2 = findViewById(R.id.button2);
            View findViewById3 = findViewById(R.id.button3);
            View findViewById4 = findViewById(R.id.button4);
            findViewById2.setVisibility(View.VISIBLE);
            findViewById3.setVisibility(View.VISIBLE);
            findViewById4.setVisibility(View.VISIBLE);
            if (event.getAction() == MotionEvent.ACTION_UP) {
                Log.i("TOUCH X IS", Float.toString(event.getRawX()));
                Log.i("TOUCH Y IS", Float.toString(event.getRawY()));
            }
            for (int numChildren = ((ViewGroup) v.getParent())
                    .getChildCount(); numChildren >= 0; --numChildren) {
                View child = ((ViewGroup) v.getParent())
                        .getChildAt(numChildren - 1);
                if (child instanceof Button) {
                    Rect bounds = new Rect();
                    child.getHitRect(bounds);
                    Log.i(child.getTag().toString() + " CENTER X IS",
                            Float.toString(bounds.exactCenterX()));
                    Log.i(child.getTag().toString() + " CENTER Y IS",
                            Float.toString(bounds.exactCenterY()));
                }
            }
            return false;
        }
    };

gestureListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { View findViewById2 = findViewById(R.id.button2); View findViewById3 = findViewById(R.id.button3); View findViewById4 = findViewById(R.id.button4); findViewById2.setVisibility(View.VISIBLE); findViewById3.setVisibility(View.VISIBLE); findViewById4.setVisibility(View.VISIBLE); if (event.getAction() == MotionEvent.ACTION_UP) { Log.i("TOUCH X IS", Float.toString(event.getRawX())); Log.i("TOUCH Y IS", Float.toString(event.getRawY())); } for (int numChildren = ((ViewGroup) v.getParent()) .getChildCount(); numChildren >= 0; --numChildren) { View child = ((ViewGroup) v.getParent()) .getChildAt(numChildren - 1); if (child instanceof Button) { Rect bounds = new Rect(); child.getHitRect(bounds); Log.i(child.getTag().toString() + " CENTER X IS", Float.toString(bounds.exactCenterX())); Log.i(child.getTag().toString() + " CENTER Y IS", Float.toString(bounds.exactCenterY())); } } return false; } };

2 个答案:

答案 0 :(得分:1)

获取SubView,如果可以通过以下方法在Linear Layout或GridLayout中。

| * |如果视图垂直放置在LinearLayout中,我已经向你展示了如何获取SubView。

NamVyuVar.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View view, MotionEvent MsnEvtPsgVar)
    {
        switch (MsnEvtPsgVar.getActionMasked())
        {
            case MotionEvent.ACTION_DOWN:
                Log.d("TAG", "onTouch: ACTION_DOWN");
                break;

            case MotionEvent.ACTION_MOVE:
                LinearLayout NamLloVav = (LinearLayout)view;
                float SubVyuHytVal = NamLloVav.getChildAt(0).getHeight();
                float TchPntYcoVal = MsnEvtPsgVar.getY();
                int NamIdxVal = (int) (TchPntYcoVal / SubVyuHytVal);

                View NamIdxVyuVav = NamLloVav.getChildAt(NamIdxVal)

            // CodTodo With the Indexed View NamIdxVyuVav :

                break;

            case MotionEvent.ACTION_UP:
                Log.d("TAG", "onTouch: ACTION_UP");
                break;
        }
        return true;
    }
});

| * |类似地,如果你希望获得SubView,如果视图水平放置在LinearLayout Change 3行以下。

float SubVyuWdtVal = NamLloVav.getChildAt(0).getWidth();
float TchPntXcoVal = MsnEvtPsgVar.getX();
int NamIdxVal = (int) (TchPntXcoVal / SubVyuWdtVal);

| * |同样的技术也可以应用于网格布局。

答案 1 :(得分:0)

在您的手势监听器中,检查MotionEvent是MotionEvent.ACTION_UP的时间并使用coords event.getX()和event.getY(),然后确定这些坐标处的视图。

public boolean onTouch(View view, MotionEvent event) {
  if (event == MotionEvent.ACTION_UP) {
    int x = event.getX();
    int y = event.getY();
    //find what view is at x, y
  }
}

按下第一个按钮时会触发一些标记(使用onClick或运动事件为ACTION_DOWN时)。然后当他们抬起手指时,上面会被解雇。

编辑:请务必使用event.getY()而不是event.getRawY()。计算方法不同,按钮的界限计算方式与getY()

的计算方式相同