同时GridView按钮事件/确定触摸了哪个按钮

时间:2012-07-02 05:57:16

标签: android gridview ontouchevent ontouchlistener

我正在努力解决这个问题。我有8个按钮的gridview。目前我正在使用onItemClickListener触发按钮操作,但是这会给我带来两个问题。

1)按钮动作在按下按钮后发生。

2)两个按钮不能同时按下,必须松开第一个按钮。

据我所知,onTouchListener应解决我的第一个问题,但我不知道如何确定按下了哪个按钮。我的onItemClickListener代码如下

gridview.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {

        Toast.makeText(Activity.this, "" + position, Toast.LENGTH_SHORT).show();

  }
        });

现在有了上面的内容,我确切地知道哪个按钮被按下了。我相信实现onTouchListener的代码如下

        gridview.setOnTouchListener(new OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            return false;
        }
    }) {

我应该如何确定使用MotionEvent按下了哪个按钮?在我获得通过“位置”之前,它使这变得相当容易。我还需要考虑是否同时推动了两个或更多按钮/没有让另一个按钮去。

有谁知道如何实现这个目标?

3 个答案:

答案 0 :(得分:1)

我最近遇到了这个问题并在寻求帮助时遇到了这个问题,我想从我所做的事情中添加两件似乎有用的东西:

1)我将onTouchListener添加到适配器中的对象而不是活动或网格视图。

2)在OnTouchListener中,我查找了MotionEvent.ACTION_DOWN(第一次手指触摸)和MotionEvent.ACTION_POINTER_DOWN(后续手指触摸),这样我就可以获得多头并立即处理它们而无需等待用户抬起手指(或多个)。

请注意,我称之为ImageAdapter,即使我已经为每个人添加了TextView,我可以使用TextView背景作为图像,但是将不可见的文本添加到TextView以便它与Talkback一起使用):< / p>

public class ImageAdapter extends BaseAdapter {
    private Context mContext;

    public ImageAdapter(Context c) {
        mContext = c;
    }

    public int getCount() {
        return numCols * numRows;
    }

    public Object getItem(int position) {
        return this;
    }

    public long getItemId(int position) {
        return position;
    }

    // create a new TextView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView textView;

        if (convertView == null) {  // if it's not recycled, initialize some attributes
            textView = new TextView(mContext);

        } else {
            textView = (TextView) convertView;
        }

        // place any other initial setup needed for the TextView here

        // here's our onTouchListener
        textView.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                boolean returnValue;
                int thePosition = v.getId();

                // MotionEvent.ACTION_DOWN gets the first touch
                // MotionEvent.ACTION_POINTER_DOWN gets any subsequent touches (if you place a second finger on the screen)
                // Between these I can get touches as soon as they happen, including multitouch support, without needing to wait until the user lifts their finger.

                if ((event.getAction() == MotionEvent.ACTION_DOWN) || (event.getAction() == MotionEvent.ACTION_POINTER_DOWN)) {
                    TextView textView;
                    if (v == null) {  // if it's not recycled, initialize some attributes
                        textView = new TextView(mContext);

                    } else {
                        textView = (TextView) v;
                    }

                    // Do any processing based on the touch - I call a function and pass the position (number of cell, 1..n) and textview so can make changes to it as needed
                    ScreenTapped(thePosition, textView);
                    // I used a returnValue
                    returnValue = true;
                } else returnValue = false;

                return returnValue;

        });
        return textView;

    } // getView
} //imageadapter

答案 1 :(得分:0)

我实际上试图想出同样的事情。我找到了使用以下代码点击了哪个gridcell

public boolean onTouch(View v, MotionEvent me) {

            float currentXPosition = me.getX();
            float currentYPosition = me.getY();
            int position = gridView.pointToPosition((int) currentXPosition, (int) currentYPosition);

位置为您提供gridView上的数字,您可以根据以下内容检索该特定项目

gridView.getItemAtPosition(position)

但那是我被困的地方。我的gridView中包含Textview项目,我无法将项目转换为textview,然后对其执行操作。

希望这有帮助!

答案 2 :(得分:0)

使用gridView时,理念是:

  • 网格视图实现onTouchLister
  • 触摸发生在onTouchLister时收集坐标(很多:)) 对于所有ACTION_MOVE事件
  • 当触摸事件为MOVE_UP时,计算下的实际位置 坐标并返回网格中的项目

所以解决方案是:

在您的 findViewById(some_grid_view)

的活动中
//Register handler for the onTouch event of gridView in your activity
gridView.setOnTouchListener(new MyActivityOnTouchListener(this));

注意:我的onTouch监听器是在另一个类(MyActivityOnTouchListener)中实现的,而不是在活动内部实现

...然后在MyActivityOnTouchListener类中实现 onTouch 方法:

public class CalendarActivityOnTouchListener implements View.OnTouchListener {
    private MyActivity myActivityContext; 
    private GridView mGridView;
    private HashSet<Point> movementCoordinates = new HashSet<Point>;

    //Constructor
    public MyActivityOnTouchListener (MyActivity context){
        this.myActivityContext= context;
        mGridView= myActivityContext.getGridView();  //assign touched gridView into a local variable
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

    /*
     *   NOTE: 
     *    ACTION_MOVE fires events until you release it
     *    ACTION_UP once you release it fires it   
     */

    //while touching the grid a bunch of ACTION_MOVE events are dispatched
    if (event.getAction() == MotionEvent.ACTION_MOVE) {
       //gather all coordinates touched (in a set to avoid duplicates)
       movementCoordinates.add(new Point((int)event.getX(), (int)event.getY()));
       return true;
    }

    //Finally the finger is lifted   
    if (event.getAction() == MotionEvent.ACTION_UP) {

         //convert all movementCoordinates gathered in the previous block into real grid positions
        int position;
        for(Point p : movementCoordinates){
            Log.d("Luka", p.x +" / "+p.y);
            position = calendarGridView.pointToPosition(p.x, p.y);

            //...Do whatever with the position
        }
    }
  }

}

小心 pointToPosition()方法,因为在某些情况下它可以返回-1而不是坐标后面的位置。例如,如果网格中的项目之间有边距,则这些坐标不能返回位置,因此为-1

希望它有所帮助...