OnTouchListener ACTION_MOVE is not working while moving finger on the screen

Viewed 197

Here is what I want:

  1. Touch the screen.
  2. keep moving your finger.
  3. If you touch any buttons on the screen while moving your finger, the color of the button changes its color to green.

Issue: The 'if' condition not working on its way in the 57th row (.java)

if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) until it changes to if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) which is I don't want.

Please, take a look to .java file below:

public class MainActivity extends AppCompatActivity implements View.OnTouchListener , GestureDetector.OnGestureListener{

    private Button bt1,bt2,bt3
    
    private GestureDetector mGestureDetector;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        
        // ------ buttons findViewByID
      
            bt1 = (Button) findViewById(R.id.b1);
            bt2 = (Button) findViewById(R.id.b2);
            bt3 = (Button) findViewById(R.id.b3);  
       

        //------Set UP id for buttons    

            bt1.setId(1);
            bt2.setId(2);
            bt3.setId(3);
        
       //-------set up touchlisteners for buttons
        
            bt1.setOnTouchListener(this);
            bt2.setOnTouchListener(this);
            bt3.setOnTouchListener(this);
    
        //
        mGestureDetector = new GestureDetector(this,this);

    }
    //---------Override Event
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
    
       /*----------When finger  touched + finger is moving. But the  condition below is not working  finger moving event (ACTION_MOVE) not working. but finger touch event(ACTION_DOWN) is working*/
        if (motionEvent.getAction() == MotionEvent.ACTION_MOVE)   // condition doesn't work until it changes                                //if(motionEvent.getAction() == MotionEvent.ACTION_DOWN).
        {
                switch (view.getId())
                    {
                    case 1:
                        bt1.setBackgroundColor(GREEN);
                        break;
                    case 2:
                        bt2.setBackgroundColor(GREEN);
                        break;
                    case 3:
                        bt3.setBackgroundColor(GREEN);
                        break;
                    }
                            
        }

            return true;
                }
//--------Other Overrides
    @Override
    public boolean onDown(MotionEvent motionEvent) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {

        return false;
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {

    }

    @Override
    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        return false;
    }

 
 
 }

And please, take a look to the .XML file below

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:id="@+id/lin"

        tools:context=".MainActivity">
        
        //------Mode: HORIZONTAL
    <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            // ------ BUTTONS
        <Button
                android:id="@+id/b1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="60sp"
                android:layout_weight="1"/>
        <Button
                android:id="@+id/b2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="60sp"
                android:layout_weight="1" />
        <Button
                android:id="@+id/b3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="60sp"
                android:layout_weight="1"/>
    </LinearLayout>
    
</LinearLayout>
1 Answers

That's because when You set onTouchListener on buttons and first start moving on container (LinearLayout) touch event it's not passed to child (button). To make it work You have to set a listener on the container and then check if touch coordinates contains in buttons rectangle.

Code:

private Button bt1, bt2, bt3;
private LinearLayout lin;
private GestureDetector mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // ------ buttons findViewByID
    bt1 = (Button) findViewById(R.id.b1);
    bt2 = (Button) findViewById(R.id.b2);
    bt3 = (Button) findViewById(R.id.b3);
    lin = findViewById(R.id.lin);
    //-------set up touchlisteners for buttons
    lin.setOnTouchListener(this);
    //
    mGestureDetector = new GestureDetector(this, this);
}

@Override
public boolean onTouch(View view, MotionEvent motionEvent)
{
    if (motionEvent.getAction() == MotionEvent.ACTION_MOVE)
    {
        Rect but1 = new Rect();
        bt1.getHitRect(but1);
        if (but1.contains((int) motionEvent.getX(), (int) motionEvent.getY()))
        {
            bt1.setBackgroundColor(getColor(R.color.colorAccent));
            return true;
        }
        Rect but2 = new Rect();
        bt2.getHitRect(but2);
        if (but2.contains((int) motionEvent.getX(), (int) motionEvent.getY()))
        {
            bt2.setBackgroundColor(getColor(R.color.colorAccent));
            return true;
        }
        Rect but3 = new Rect();
        bt3.getHitRect(but3);
        if (but3.contains((int) motionEvent.getX(), (int) motionEvent.getY()))
        {
            bt3.setBackgroundColor(getColor(R.color.colorAccent));
            return true;
        }
    }
    return true;
}

I tested this code and it's working fine.
Of course, You can make it better, when You have 200 buttons it will be better to load rectangles in onCreate() than to create them every time in touching event

Related