OnSwipeTouchListener does not work for a GridView of Button objects?

霸气de小男生 提交于 2019-12-24 00:48:28

问题


DISCLAIMER: I am aware that this post may be long compared to others, but I honestly could not find any post in SO that was helpful (recommended links welcome!), and I also could not find any other way to break this problem down any simpler... That said, I would greatly appreciate it if you could help me out as I have been stuck on this issue for quite awhile now...

For an array of String values in GridView (Linear Layout - vertical), I implemented the OnSwipeTouchListener class for swiping in each direction and it worked throughout the whole screen as the according Toast messages popped up...

The following green circle shows that the whole screen outputs Toast messages for each swipe direction accurately:

But why is that when I try the same thing with an array of Button objects (for the sake of applying backgrounds for each String value) in GridView, it's only accurate for the bottom side of the layout?

The following red circle implies that the swipe directions are either only up or null objects as this is the inaccurate side, whereas the green circle implies the opposite as every swipe direction is accurate on the bottom third of the screen:

As for my Java code, here's my MainActivity:

package dpark.sample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.Toast;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private int height, width;
    private String[] list;
    private GridView grid;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        height = 6;
        width = 6;

        grid = (GridView)findViewById(R.id.gridview);
        grid.setNumColumns(width);

        buildList();

        display();

        //*** COMMENTED OUT AS THE FOLLOWING STATEMENTS ARE USED FOR JUST STRING VALUES ***
        /*ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, list);
        grid.setAdapter(adapter);*/

        grid.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) {
            public void onSwipeTop() {
                 Toast.makeText(MainActivity.this, "top", Toast.LENGTH_SHORT).show();
            }

            public void onSwipeRight() {
                Toast.makeText(MainActivity.this, "right", Toast.LENGTH_SHORT).show();
            }

            public void onSwipeLeft() {
                Toast.makeText(MainActivity.this, "left", Toast.LENGTH_SHORT).show();
            }

            public void onSwipeBottom() {
                Toast.makeText(MainActivity.this, "bottom", Toast.LENGTH_SHORT).show();
            }

        });
    }

    private void buildList() {
        int tempIncrementor = 1;
        int dimensions = height * width;
        list = new String[dimensions];

        for (int i = 0; i < dimensions; i++) {
            list[i] = String.valueOf(tempIncrementor);
            tempIncrementor++;
         }
    }

    private void display() {
        Button cb = null;
        ArrayList<Button> mButtons = new ArrayList<Button>();

        for (int i =0; i < list.length; i++) {
            cb = new Button(this);
            cb.setText(list[i]);
            cb.setBackgroundResource(R.drawable.brownblock);
            mButtons.add(cb);
        }

        grid.setAdapter(new CustomAdapter(mButtons));
    }

CustomAdapter for displaying the grid with Buttons:

package dpark.puzzle_15;

import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import java.util.ArrayList;

public class CustomAdapter extends BaseAdapter {
    private ArrayList<Button> buttonArray = null;

    public CustomAdapter(ArrayList<Button> b) {
        buttonArray = b;
    }

    @Override
    public int getCount() {
        return buttonArray.size();
    }

    @Override
    public Object getItem(int position) {
        return (Object) buttonArray.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Button button;
        if (convertView == null) {
            button = buttonArray.get(position);
        } else {
            button = (Button) convertView;
        }
        return button;
   }
}

Lastly, here's OnSwipeTouchListener:

package dpark.puzzle_15;

import android.content.Context;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class OnSwipeTouchListener implements OnTouchListener {
    private final GestureDetector gestureDetector;

    public OnSwipeTouchListener (Context ctx){
        gestureDetector = new GestureDetector(ctx, new GestureListener());
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    private final class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

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

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            onSwipeRight();
                        } else {
                            onSwipeLeft();
                        }
                    }
                    result = true;
                }
                else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeBottom();
                    } else {
                        onSwipeTop();
                    }
                }
                result = true;

            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public void onSwipeRight() {
    }

    public void onSwipeLeft() {
    }

    public void onSwipeTop() {
    }

    public void onSwipeBottom() {
    }
}

Oh, and here's the XML code:

<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:textStyle="bold"
        android:layout_gravity="center"
        android:layout_margin="12dip"
        android:text="GridView of Buttons Swipe Demo"/>

    <GridView
        android:id="@+id/gridview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:numColumns="auto_fit"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        android:columnWidth="90dp"
        android:stretchMode="columnWidth"
        android:gravity="center"
        android:layout_gravity="center"/>

</LinearLayout>

... All of that said, is there any way I could apply the swipe touch interface for a GridView of Button objects, let alone the whole screen layout?

Again, thank you so much.

来源:https://stackoverflow.com/questions/35511294/onswipetouchlistener-does-not-work-for-a-gridview-of-button-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!