customview中的TextView onTouchEvent

时间:2013-04-05 16:56:41

标签: android android-canvas

我有一个自定义视图,在自定义视图中我创建了4个文本视图。我希望每个文本视图都能响应触摸事件。但是,文本视图本身不会响应触摸事件。但是,我可以为整个自定义视图创建一个ontouch侦听器。但是,我不希望整个视图都有ontouch事件,因为我希望拖放我创建的textview。我尝试了注册ontouch事件的x和y坐标的路线,并假设如果ontouch事件在textview的范围内,则更改textview的坐标,但这过于复杂,因为如果拖动了一个textview到另一个的坐标,然后ontouch事件会“拾取”另一个文本视图,那么我将移动两个文本视图,这不是我想要的。总而言之,我想知道是否可以在ontouch监听器中为customview中的textview设置,如果可能的话,为什么它不起作用:

                mScale.mPositive.get(0).setOnTouchListener(new OnTouchListener()
                    {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) 
                        {
                                mScale.mCurrentXPos[0] = event.getX();
                                mScale.mCurrentYPos[0] = event.getY();
                                mScale.mDrag = true;

                            return true;
                        }

                    });

此相同代码适用于自定义视图,但不适用于该自定义视图中的特定文本视图。

以下是自定义视图代码:

public class Scale扩展View {

public Scale(Context context, AttributeSet attrs) 
{
    super(context, attrs);
    mContext = this.getContext();
            h = new Handler();
            mCalendarDbHelper=new CalendarDbAdapter(mContext);
            mCalendarDbHelper.open();
    Cursor thoughts = mCalendarDbHelper.fetchThoughts();

    //create a string array of negative thoughts from the db
        while (thoughts.moveToNext())
        {
            if (thoughts.getString(thoughts.getColumnIndexOrThrow(CalendarDbAdapter.COLUMN_NAME_THOUGHT)).length() > 0 && thoughts.getString(thoughts.getColumnIndexOrThrow(CalendarDbAdapter.COLUMN_NAME_THOUGHT)).charAt(0) == '-')
            {
                negative_thoughts.add(thoughts.getString(thoughts.getColumnIndexOrThrow(CalendarDbAdapter.COLUMN_NAME_THOUGHT)));
            }

        }
     thoughts.close();
     array_size = negative_thoughts.size();
     mBag =BitmapFactory.decodeResource(getResources(), R.drawable.bag);
     mGreenBag = BitmapFactory.decodeResource(getResources(), R.drawable.green_bag);

    for (int i = 0; i < 72; i ++)
    {
        try
        {
        mScale[i] = BitmapFactory.decodeStream(context.getAssets().open("scale_"+i+".gif"));
        }
        catch (IOException e) 
        {

        }
    }
}


private Runnable r= new Runnable() 
{

    @Override
    public void run() {
        invalidate();

    }

};


protected void onDraw (Canvas canvas)
{
    if (first == true)
    {
        width = this.getWidth();
        height = this.getHeight();
        mScale[i] = Bitmap.createScaledBitmap(mScale[i], (int) (width * 1.5), height, true);
        mBag = Bitmap.createScaledBitmap(mBag, width/2, height/2, true);
        negative = new TextView(mContext);
        word = negative_thoughts.get((int) (Math.random() * array_size));
        negative.setText(word);
        negative.layout(0, 0, width/3, height/4);
        negative.setGravity(Gravity.CENTER);
        negative.setTextSize(15);
        negative.setTextColor(Color.BLACK);
        negative.setTypeface(Typeface.DEFAULT_BOLD);
        negative.setShadowLayer(5, 2, 2, Color.WHITE);
        negative.setDrawingCacheEnabled(true);
        negative.setBackgroundResource(R.drawable.graycloud);
        positive_paint.setColor(Color.parseColor("#FF4444"));
        positive_paint.setShadowLayer(5, 2, 2, Color.YELLOW);
        positive_paint.setTypeface(Typeface.DEFAULT_BOLD);
        positive_paint.setTextSize(25);
        mCurrentXPos[0] = (width/2);
        mCurrentYPos[0] = height/4;
        mCurrentXPos[1] = (width/2) + (width/8);
        mCurrentYPos[1] = height/6;
        mCurrentXPos[2] = width/2;
        mCurrentYPos[2] = height/12;
        mCurrentXPos[3] = (width/2) + (width/8);
        mCurrentYPos[3] = height/18;
        mMoveXPos[0] = ((width/2) - width)/FRAME_RATE;
        mMoveYPos[0] = ((height/4) - (height + (height/4)))/FRAME_RATE;
        mMoveXPos[1] = (((width/2) + (width/8)) - width)/ FRAME_RATE;
        mMoveYPos[1] = ((height/6) - (height + (height/4)))/FRAME_RATE;
        mMoveXPos[2] = ((width/2) - width)/ FRAME_RATE;
        mMoveYPos[2] = ((height/12) - (height + (height/4)))/FRAME_RATE;
        mMoveXPos[3] = (((width/2) + (width/8)) - width)/ FRAME_RATE;
        mMoveYPos[3] = ((height/18) - (height + (height/4)))/FRAME_RATE;
        mMoveByXPos[0] = -(width/2)/ FRAME_RATE;
        mMoveByYPos[0] = -(height/4)/FRAME_RATE;
        mMoveByXPos[1] =  ((width - (width/3)) - (width/2 + (width/8)))/ FRAME_RATE;
        mMoveByYPos[1] = -(height/6)/FRAME_RATE;
        mMoveByXPos[2] = - (width/2)/ FRAME_RATE;
        mMoveByYPos[2] =  ((height) - (height/12))/FRAME_RATE;
        mMoveByXPos[3] =  ((width - (width/3)) - (width/2 + (width/8)))/ FRAME_RATE;
        mMoveByYPos[3] =  ((height) - (height/18))/FRAME_RATE;
        currentX = width;
        currentY = height + height/4;
        first = false;
    }


    if (game_over == false)
    {
        canvas.drawBitmap(mScale[i], 0 - (width/4), 0, null);
        canvas.drawBitmap(negative.getDrawingCache(),(int) (width/12), (int) (height - (height)/2.5) - (j), null);
    }

    else
    {
        canvas.drawBitmap(mBag, width/4, height/4, null);
    }

    if (mMoveScale == true)
    {
        i++;
        j+=3;
        ScaleIt(canvas, i);
        if (i == 21 || i == 37 || i == 53 || i == 71)
        {
            mMoveScale = false;
        }

    }

    if (tracker > 0)
    {
        if (tracker == 1)
        {
            if (currentX > width/2 && currentY > height/4 && sStop == false)
            {
                currentX += mMoveXPos[0]; 
                currentY += mMoveYPos[0];
                canvas.drawBitmap(mPositive.get(tracker -1 ).getDrawingCache(), currentX, currentY, null);

            }

            else 
            {
                if (sStop == false)
                {


                    mMoveScale = true;
                    sStop = true;
                    currentX = width;
                    currentY = height + height/4;
                    draw_em++;
                }

            }
        }


        if (tracker == 2)
        {

            if (currentX > width/2 + (width/8) && currentY > (height/6) && sStop == false)
            {
                currentX += mMoveXPos[1]; 
                currentY += mMoveYPos[1];
                canvas.drawBitmap(mPositive.get(tracker -1 ).getDrawingCache(), currentX, currentY, null);

            }

            else
            {
                if (sStop == false)
                {
                    mMoveScale = true;
                    sStop = true;
                    currentX = width;
                    currentY = height + height/4;
                    draw_em++;
                }
            }
        }


        if (tracker == 3)
        {

            if (currentX > width/2 && currentY > height/12 && sStop == false)
            {
                currentX += mMoveXPos[2]; 
                currentY += mMoveYPos[2];
                canvas.drawBitmap(mPositive.get(tracker -1 ).getDrawingCache(), currentX, currentY, null);

            }

            else 
            {
                if (sStop == false)
                {
                    mMoveScale = true;
                    sStop = true;
                    currentX = width;
                    currentY = height + height/4;
                    draw_em++;
                }
            }
        }

        if (tracker == 4)
        {

            if (currentX > width/2 + (width/8) && currentY > (height/18) && sStop == false)
            {
                currentX += mMoveXPos[3]; 
                currentY += mMoveYPos[3];
                canvas.drawBitmap(mPositive.get(tracker -1 ).getDrawingCache(), currentX, currentY, null);
            }

            else 
            {
                    if (sStop == false)
                    {
                    mMoveScale = true;
                    sStop = true;
                    game_over = true;
                    currentX = width;
                    currentY = height + height/4;
                    draw_em++;

                    }
            }
        }


        if (draw_em > 0 && game_over == false)
        {
            for (int i = 0; i < draw_em; i ++)
            {
            if (i == 0)
            {
                canvas.drawBitmap(mPositive.get(i).getDrawingCache(), width/2, height/4 + j, null);
            }
            if (i == 1)
            {
                canvas.drawBitmap(mPositive.get(i).getDrawingCache(), width/2 + (width/8), height/6 + j, null);

            }
            if (i == 2)
            {
                canvas.drawBitmap(mPositive.get(i).getDrawingCache(), width/2, height/12 + j, null);


            }
            if (i == 3)
            {
                canvas.drawBitmap(mPositive.get(i).getDrawingCache(), width/2 + (width/8), height/18 + j, null);
            }

        }

        }

        else if (game_over == true)
        {
            for (int i = 0; i < draw_em; i++)
            {
                if (i == 0 && mCurrentXPos[0] > 0 && mCurrentYPos[0] >  0 && mDrag == false)
                {

                    mCurrentXPos[0] += mMoveByXPos[0];
                    mCurrentYPos[0] += mMoveByYPos[0];
                    canvas.drawBitmap(mPositive.get(i).getDrawingCache(), mCurrentXPos[0], mCurrentYPos[0], null);
                }

                else if (i == 0 && mCurrentXPos[0] <= 0 || mCurrentYPos[0] <=  0 && mDrag == false)
                { 
                    canvas.drawBitmap(mPositive.get(0).getDrawingCache(), 0, 0, null);
                }

                else if (i == 0 && mDrag == true)
                {
                    canvas.drawBitmap(mPositive.get(0).getDrawingCache(), mCurrentXPos[0], mCurrentYPos[0], null);
                }

                if (i == 1 && mCurrentXPos[1] < (width - (mPositive.get(i).getWidth()/2)) && mCurrentYPos[1] >  mPositive.get(i).getHeight()/2)
                {
                    mCurrentXPos[1] += mMoveByXPos[1];
                    mCurrentYPos[1] += mMoveByYPos[1];
                    canvas.drawBitmap(mPositive.get(i).getDrawingCache(), mCurrentXPos[1], mCurrentYPos[1], null);

                }

                else if (i == 1 && mCurrentXPos[1] >= (width - (mPositive.get(i).getWidth()/2)) || mCurrentYPos[1] <=  mPositive.get(i).getHeight()/2)
                {
                    canvas.drawBitmap(mPositive.get(1).getDrawingCache(), width - (width/3), 0, null);
                }

                if (i == 2 && mCurrentXPos[2] > (mPositive.get(i).getWidth()/2) && mCurrentYPos[2] <  (height - mPositive.get(i).getHeight()/2))
                {
                    mCurrentXPos[2] += mMoveByXPos[2];
                    mCurrentYPos[2] += mMoveByYPos[2];
                    canvas.drawBitmap(mPositive.get(i).getDrawingCache(), mCurrentXPos[2], mCurrentYPos[2], null);
                }

                else if (i == 2 && mCurrentXPos[2] <= (mPositive.get(i).getWidth()/2) || mCurrentYPos[2] >=  (height - mPositive.get(i).getHeight()/2))
                {
                    canvas.drawBitmap(mPositive.get(2).getDrawingCache(), 0, height - (height/4), null);    
                }

                if (i == 3 && mCurrentXPos[3] < (width - (mPositive.get(i).getWidth()/2)) && mCurrentYPos[3] < (height - mPositive.get(i).getHeight()/2))
                {
                    mCurrentXPos[3] += mMoveByXPos[3];
                    mCurrentYPos[3] += mMoveByYPos[3];
                    canvas.drawBitmap(mPositive.get(i).getDrawingCache(), mCurrentXPos[3], mCurrentYPos[3], null);
                }

                else if (i == 3 && mCurrentXPos[3] >= (width - (mPositive.get(i).getWidth()/2)) || mCurrentYPos[3] >= (height - mPositive.get(i).getHeight()/2))
                {
                    canvas.drawBitmap(mPositive.get(3).getDrawingCache(), width - (width/3), height - (height/4), null);    
                }


            }
        }
    }
    h.postDelayed(r, FRAME_RATE);

}

protected void moveIt(Canvas canvas, int moveX,int moveY, int i)
{
    if (i == 0)
    {
        canvas.drawBitmap(mPositive.get(i).getDrawingCache(), moveX, moveY, null);
    }

    if (i == 1)
    {
        canvas.drawBitmap(mPositive.get(i).getDrawingCache(), moveX, moveY, null);
    }

    if (i == 2)
    {
        canvas.drawBitmap(mPositive.get(i).getDrawingCache(), moveX, moveY, null);
    }

    if (i == 3)
    {
        canvas.drawBitmap(mPositive.get(i).getDrawingCache(), moveX, moveY, null);

    }
}

protected void moveEm(Canvas canvas, int[]mMovePosX, int[] mMovePosY)
{
    for (int i = 0; i < 4; i++)
    {

    }
}

protected void ScaleIt(Canvas canvas, int i)
{
    mScale[i] = Bitmap.createScaledBitmap(mScale[i], (int) (width * 1.5), height, true);
    mScale[i-1].recycle();

}


}

这是活动:

 public class ScaleView extends Activity 
 {  
    Context mContext; 
Scale mScale;
EditText positive_thought;
Button fire;
TextView pos;
private static Set<String> mPositiveWords;
private static Set<String> mNegativeWords;
int count;
private Pattern four_letter_words = Pattern.compile("not|cant|cnt|can't"); 
String inputLine;
private String[] inputTokens;
Button question;
Button skip;

public static boolean populatePositiveWords(Context context)
{
    mNegativeWords = new HashSet<String>();


    try
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open("negative_words.txt")));          
        String line = reader.readLine();

        while (line != null)
        {
            mNegativeWords.add(line.toLowerCase(Locale.US));
            line = reader.readLine();
        }

        reader.close();
    }
    catch (IOException exception)
    {
        return false;
    }

    return true;
    //TODO list of negative words 
}



@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    this.getActionBar().hide();
    mContext = this;
    populatePositiveWords(mContext);
    setContentView(R.layout.activity_scale);
    mScale = (Scale) findViewById(R.id.anim_view);
    mScale.setClickable(true);
    positive_thought = (EditText) findViewById(R.id.thoughts);
    fire = (Button) findViewById(R.id.scale_it);
    skip = (Button) findViewById(R.id.skip);
    question = (Button) findViewById(R.id.question);
    InputFilter[] FilterArray = new InputFilter[1];
    FilterArray[0] = new InputFilter.LengthFilter(60);
    positive_thought.setFilters(FilterArray);


    fire.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View view) 
        {
            //if the button is clicked invalidate the ondraw method and pass in the text of the positive word 
            inputLine = positive_thought.getText().toString();
            inputTokens = inputLine.split(" ");

            if (inputLine.isEmpty())
            {
                Toast.makeText(mContext, "You have to write something!", Toast.LENGTH_SHORT).show();
                return;                 
            }

            if (inputTokens.length < 3)
            {
                Toast.makeText(mContext, "At least three words are required.", Toast.LENGTH_SHORT).show();
                return;
            }               

            if (four_letter_words.matcher(inputLine).find() == true)
            {
                Toast.makeText(mContext, "Make an affirmative statement!", Toast.LENGTH_SHORT).show();
                return;
            }

            boolean matchesToken = false;

            for (int i = 0; i < inputTokens.length; i++)
            {
                String token = inputTokens[i];

                if (mNegativeWords.contains(token.toLowerCase(Locale.US)))
                {
                    matchesToken = true;
                    break;
                }
            }

            if (matchesToken == true)
            {
                Toast.makeText(mContext, "Use positive words!", Toast.LENGTH_SHORT).show();
                return;
            }

            else
            {

            InputMethodManager imm = (InputMethodManager)mContext.getSystemService(
                      Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(positive_thought.getWindowToken(), 0);
            pos = new TextView (mContext);
            pos.layout(0, 0, mScale.width/3, mScale.height/4);
            pos.setGravity(Gravity.CENTER);
            pos.setTextSize(15);
            pos.setTextColor(Color.RED);
            pos.setTypeface(Typeface.DEFAULT_BOLD);
            pos.setShadowLayer(5, 2, 2, Color.YELLOW);
            pos.setText(positive_thought.getText().toString());
            pos.setDrawingCacheEnabled(true);
            pos.setBackgroundResource(R.drawable.whitecloud);
            pos.setClickable(true);
            mScale.mPositive.add(pos);
            mScale.scale_it = true;
            count++;
            mScale.sStop = false;
            mScale.tracker = count;
            if (count == 4)
            {
                ((RelativeLayout)question.getParent()).removeView(question);
                ((RelativeLayout)skip.getParent()).removeView(skip);
                mScale.mPositive.get(0).setOnTouchListener(new OnTouchListener()
                    {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) 
                        {
                                mScale.mCurrentXPos[0] = event.getX();
                                mScale.mCurrentYPos[0] = event.getY();
                                mScale.mDrag = true;
                                return true;
                        }

                    });


            }



            }
            positive_thought.setText(null);

        }
    });

}

}

2 个答案:

答案 0 :(得分:1)

TextView无法接收触摸事件的原因是TextView在画布上绘制为位图,而不是视图。下面显示的代码摘录说明了这一点。

protected void onDraw(Canvas canvs)
{
    ....
    negative = new TextView(mContext);
    ...
    canvas.drawBitmap(negative.getDrawingCache(), ...)

要向TextView提供触摸事件,您的Scale类应该扩展而不是View,而ViewGroup和TextView需要通过使用ViewGroup.addView()或addViewInLayout()作为子类添加到Scale类。实现ViewGroup子类并不是一项简单的任务。您可能必须根据需要实现onInterceptTouchEvent(MotionEvent)。

Android的源代码将有所帮助。

答案 1 :(得分:0)

您的CustomView是否也设置了一些TouchListner? 如果是,则可能导致问题。从CustomView中移除TouchListner并查看它是否有效..