1

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>
SnackerH
  • 11
  • 2
  • I guess you have to set onTouchListener to this custom Sudoku view in activity and handle onTouch() method there. Thing is you haven't set any listener. btw I like your approach to make this a custom view – Gaurav Chauhan May 16 '17 at 05:00
  • @GauravChauhan I have listener in OnCreate in SudokuActivity. Maybe this wasn't enough or wrong approach? – SnackerH May 16 '17 at 05:09
  • try passing activity context like sdk.setOnTouchListener(this), and implement onTouch in activity. – Gaurav Chauhan May 16 '17 at 11:41

1 Answers1

0

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();
 }
Dany
  • 71
  • 1
  • 5