简体   繁体   中英

[Android]onTouch in child View is not responding

I have been working on making Sudoku grid whose cell's value changes whenever I touch on a cell. So I have implemented this sudoku grid in a LinearLayout by Child View, and tried using OnTouch method, but it is not working. I tried using log method to check whether onTouch is actually called, but it seemes that this method is perfectly ignored. I have been searching for solutions on other question, but it seems none of those solutions helped. I feel kinda suck here, and any help would be greatly appreciated.

Here is my code:

SudokuActivity.java

package snacker.nonogramsolver;

import ...; /*many things are imported here*/

public class SudokuActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sudoku);
    Button btn = (Button)findViewById(R.id.btn_clear);
    Sudoku sdk = new Sudoku(this);
    sdk.setOnTouchListener(sdk);
}

}
;

Sudoku.java

package snacker.nonogramsolver;

import ...;

public class Sudoku extends View implements View.OnTouchListener {
    int mWidth = 9;
    int mHeight = 9;
    int mCellWidth, mCellHeight;
    int mCellMargin;
    int mEdgeThick;
    int mStatus;
    int mTextSize;
    int mXNow = -1, mYNow = -1;
    int[][] mBoard = new int[9][9];
    Point mBoardPt;

    Paint mTextPaint, mTileEdgePaint;

    final static int VALID = 0;

    public Sudoku(Context context){
        super(context);
        initializeBoard();
    }

    public Sudoku(Context context, AttributeSet attrs){
        super(context, attrs);
        initializeBoard();
    }

    @Override
    protected void onDraw(Canvas canvas){
        /* There are some codes here */
        Log.d("LogTest","OnDraw Complete");
    }

    public void initializeBoard(){
        for (int x=0; x< mWidth; x++){
            for (int y=0; y< mHeight; y++){
                mBoard[x][y] = 0;
            }
        }
        invalidate();
    }

    public boolean onTouch(View v, MotionEvent event){
        Log.d("LogTest","Touched?"); /* LOG NOT ACTIVE HERE */
        if(event.getAction() == MotionEvent.ACTION_DOWN){
            mXNow = getBoardX(event.getX());
            Log.d("LogTest","" + mXNow);  /* LOG NOT ACTIVE HERE */
            mYNow = getBoardY(event.getY());
            Log.d("LogTest","" + mYNow);  /* LOG NOT ACTIVE HERE */
            mBoard[mXNow][mYNow] = mBoard[mXNow][mYNow] + 1;
            invalidate();
            return true;
        }
        else return false;
    }

    int getBoardX(float scrx){
        int x = (int)((scrx) / mCellWidth);
        if (x < 0) x = 0;
        if (x > 8) x= 8;
        return x;
    }
    int getBoardY(float scry){
        int y = (int)((scry) / mCellHeight);
        if (y < 0) y = 0;
        if (y > 8) y = 8;
        return y;
    }
}

Edit: added activity XML file.

<?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:orientation="vertical"
    android:id="@+id/activity_sudoku"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="snacker.nonogramsolver.SudokuActivity">

    <snacker.nonogramsolver.Sudoku
        android:id="@+id/SudokuGrid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/btn_clear"
        android:layout_width="150dp"
        android:layout_height="30dp"
        android:layout_weight="0.06"
        android:text="Clear" />

</LinearLayout>

You cannot directly add touchListener by just creating object of Sudoku class. You should add view in xml or programatically.

Your Activity

 public class MyActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); //initializing custom views MyCustomView1 myCustomView1 = new MyCustomView1(parameterList); MyCustomView2 myCustomView2 = new MyCustomView2(parameterList); //adding both custom views to the main activity mainView.addView(myCustomView1); mainView.addView(myCustomView1); //adding custom listener to the custom view 1 myCustomView1.setCustomEventListener(new OnCustomEventListener() { @Override public void onEvent() { //firing an event of custom view 1 Toast.makeText(MainActivity.this, "Touched custom view 1", Toast.LENGTH_SHORT).show(); } }); //adding custom listener to the custom view 2 myCustomView2.setCustomEventListener(new OnCustomEventListener() { @Override public void onEvent() { //firing an event of custom view 2 Toast.makeText(MainActivity.this, "Touched custom view 2", Toast.LENGTH_SHORT).show(); } }); } } 

Your CustomView 1

 public class MyCustomView1 extends LinearLayout{ OnCustomEventListener myCustomEventListener; public MyCustomView1(ParameterList){ super(ContextFromParameterList); //Just adding something to the custom view 1 in order to distinguish it on the screen TextView tv = new TextView(ContextFromParameterList); tv.setText("Hello world from custom view 1"); addView(tv); this.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //delegating one event to another (delegating touch event to custom event) if (MyCustomView1.this.myCustomEventListener != null) MyCustomView1.this.myCustomEventListener.onEvent(); return false; } }); } 

public void setCustomEventListener(OnCustomEventListener eventListener) { //setting custom listener from activity myCustomEventListener = eventListener; } }

Your CustomView2

 public class MyCustomView2 extends LinearLayout { OnCustomEventListener myCustomEventListener; public MyCustomView2(ParameterList) { super(ContextFromParameterList); //Just adding something to the custom view 1 in order to distinguish it on the screen TextView tv = new TextView(ContextFromParameterList); tv.setText("Hello world from custom view 2"); addView(tv); this.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //delegating one event to another (delegating touch event to custom event) if (MyCustomView2.this.myCustomEventListener != null) MyCustomView2.this.myCustomEventListener.onEvent(); return false; } }); } public void setCustomEventListener(OnCustomEventListener eventListener) { //setting custom listener from activity myCustomEventListener = eventListener; } } Your listener interface: public interface OnCustomEventListener{ //interface defines one method. Can be more and methods may have parameters public void onEvent(); } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM