Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to draw line over gridview elements properly through textview cells in Android

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;
        }
    });
like image 250
Ram Avatar asked Oct 21 '22 09:10

Ram


1 Answers

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.

like image 108
SeymaKara Avatar answered Nov 04 '22 20:11

SeymaKara