我有一个自定义视图,在自定义视图中我创建了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);
}
});
}
}
答案 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并查看它是否有效..