I would like to implement Word Search app. As part of implementation i have come across canvas and drawing line over grid view cells( letters that form the word) to indicate that user is touching finger over letters to form the word.
I have succeeded partially as of now i can draw a line over letters of grid view but the line is not through center of views of grid View.
Please can anyone assist me with your valuable suggestions .
Have a glance on below screen shot to get a clear idea.
Edited: I'm posting code to get an idea of how I'm implementing it.
xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff" >
<RelativeLayout
android:id="@+id/topbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#A9E2F3" >
<LinearLayout
android:id="@+id/topbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#336699"
android:orientation="horizontal" >
<Button
android:id="@+id/btn_pause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pause" />
<Chronometer
android:id="@+id/chronometer1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Chronometer" />
<TextView
android:id="@+id/counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="20sp"
android:typeface="serif" />
</LinearLayout>
</RelativeLayout>
<FrameLayout
android:id="@+id/gridFrame"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/wTable"
android:layout_below="@+id/textdisplay" >
<GridView
android:id="@+id/grid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#E7E8E9"
android:fitsSystemWindows="true"
android:gravity="center"
android:horizontalSpacing="10sp"
android:numColumns="10"
android:padding="1dp"
android:stretchMode="columnWidth"
android:verticalSpacing="10sp" >
</GridView>
</FrameLayout>
<GridView
android:id="@+id/wTable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#fff"
android:numColumns="3"
android:orientation="vertical" />
</RelativeLayout>
The paint is drawing over frame layout which contains grid view. Grid view elements are printed through custom text view file.
To draw a line i have used LineView.java
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;
public class LineView extends View {
public static final float LINE_WIDTH = 30.0f;
public Paint paint = new Paint();
protected Context context;
public float startingX, startingY, endingX, endingY;
public LineView(Context context) {
super(context);
this.context = context;
paint.setColor(Color.parseColor("#2E9AFE"));
paint.setStrokeWidth(LINE_WIDTH);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setDither(true);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setAlpha(90);
}
public void setPoints(float startX, float startY, float endX, float endY) {
startingX = startX;
startingY = startY;
endingX = endX;
endingY = endY;
invalidate();
}
@Override
public void onDraw(Canvas canvas) {
Log.e("LINEVIEW", "startingX" + startingX + " startingY:" + startingY);
Log.e("LINEVIEW", "endingX" + endingX + " endingY:" + endingY);
// canvas.drawLine(startingX, startingY, endingX, endingY, paint);
canvas.drawLine(startingX, startingY, endingX, endingY, paint);
}
}
Main Activity where logic is implemented:
Written only the required logic here.
newGrid = (GridView) findViewById(R.id.grid);
newGrid.setAdapter(new FormTheGridLetters());
newGrid.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// if (mp.isPlaying()) {
// mp.stop();
// }
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
// data
PaintViewHolder newPaint = new PaintViewHolder();
newPaint.DrawLine = new LineView(WordSearchActivity.this);
gridFrame.addView(newPaint.DrawLine);
buildWord = new StringBuilder();
int x = (int) event.getX();
int y = (int) event.getY();
// test = new LineView(WordSearchActivity.this);
int position = newGrid.pointToPosition(x, y);
Point one,
two;
if (position != GridView.INVALID_POSITION) {
v.getParent().requestDisallowInterceptTouchEvent(true);
cellView = (TextView) newGrid.getChildAt(position);
String a = cellView.getText().toString();
// Log.v(">>>>><<<<<<<????????", a.toString());
switch (action) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
// Checking the list for formed word ;
//if found that is painted
for (int i1 = 0; i1 < Ans.size(); i1++)
{
if (formedWord.equals(Ans.get(i1)))
{
answerAdapter.notifyDataSetChanged();
newPaint.DrawLine.setPoints(startX, startY, x, y);
// Painted the letters by passing starting and ending points
}
}
break;
}
} else {
if (mSelecting) {
mSelecting = false;
}
}
break;
case MotionEvent.ACTION_CANCEL:
mSelecting = false;
break;
}
return true;
}
});
I don't know if you fix the issue but I will answer anyway for the people that may have these kind of problems. After you recieve the valid position, you can get the center of the view and you can set these values as beginning of the draw.
Like this:
if (position != GridView.INVALID_POSITION) {
MyList.add(position);
v.getParent().requestDisallowInterceptTouchEvent(true);
TextView cellView = (TextView) gridView.getChildAt(position);
centreX = cellView.getX() + cellView.getWidth() / 2;
centreY = cellView.getY() + cellView.getHeight() / 2;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
newPaint.DrawLine.touch_start(x, y,centreX,centreY);
I have tried this code and it is working. I don't think that you need anymore but I have joined this site recently so maybe it will help other people. I can post more code if you want but
newPaint.DrawLine.touch_start(x, y,centreX,centreY);
is the trick for that issue. Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With