I have a layout which might be a bit unusual. The structure is the following:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<org.CustomSurfaceView
android:id="@+id/page_flip"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="20dip" />
<org.customRelativeLayout
android:id="@+id/note"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone" />
</FrameLayout>
My customRelativeLayout at the bottom of the XML has a XML layout too:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@drawable/my_background"
android:id="@+id/note_layout">
<TextView android:id="@+id/note"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:singleLine="false"
android:layout_margin="5dp"
android:textColor="#000000" />
</LinearLayout>
My CustomRelativeLayout:
public class CustomRelativeLayout extends RelativeLayout implements OverlayView {
private TextView mNoteText;
private LinearLayout mLinearLayout;
public int mX = 0;
public int mY = 0;
public boolean mShow;
public CustomRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
li.inflate(R.layout.note, this);
mNoteText = (TextView) findViewById(R.id.note);
mLinearLayout = (LinearLayout) findViewById(R.id.note_layout);
mLinearLayout.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("touched");
mX = (int) event.getX() - 100;
mY = (int) event.getY() - 100;
invalidate();
return false;
}
});
}
@Override
public void hide() {
mShow = false;
setVisibility(View.GONE);
}
@Override
public boolean isVisible() {
return isVisible();
}
@Override
protected void onDraw(Canvas canvas) {
Log.e("Drawing the postit");
Matrix matrix = new Matrix();
matrix.postTranslate(mX, mY);
canvas.setMatrix(matrix);
super.onDraw(canvas);
}
@Override
public void setContent(Object content) {
if (content != null && content instanceof Content) {
Content noteContent = (Content) content;
if (noteContent.getText() != null) {
mNoteText.setText(noteContent.getText());
} else {
mNoteText.setText("");
}
}
mNoteText.invalidate();
mLinearLayout.invalidate();
}
@Override
public void show() {
mShow = true;
setVisibility(View.VISIBLE);
}
}
What I want to do: I want to be able to change the position of my CustomRelativeLayout. It should be follow my touch. Its smaller than the SurfaceView and should "slide" above following my touch...
There are two problems:
- The onTouchListener bind to mLinearLayout (in CustomRelativeLayout) is only triggered once and only for ACTION_DOWN. I see the log output only once
- The note never changes the position, it is never redrawn with the changed matrix... I see the output stated in
onDraw
never after the touch happened.
First might be because the SurfaceView also handles touch events. But I thought if the CustomRelativeLayout handles it first, it should work.
Some ideas?
Edit for solution
Thanks to Xil3 I was able to remove the wall I was run into... here is my solution:
my note xml:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/transparent">
<LinearLayout android:layout_width="200dp"
android:layout_height="200dp"
android:background="@drawable/postit"
android:id="@+id/textnote_layout">
<TextView android:id="@+id/textnote_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:singleLine="false"
android:layout_margin="5dp"
android:textColor="#000000" />
</LinearLayout>
</LinearLayout>
And here is my constructor:
public TextNoteOverlay(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
li.inflate(R.layout.textnote, this);
mNoteText = (TextView) findViewById(R.id.textnote_content);
mLinearLayout = (LinearLayout) findViewById(R.id.textnote_layout);
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mLinearLayout.getHitRect(mNoteRect);
if (mNoteRect.contains((int) event.getX(), (int) event.getY())) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mStartX = (int) event.getX() - mLinearLayout.getLeft();
mStartY = (int) event.getY() - mLinearLayout.getTop();
return true;
}
mX = (int) event.getX() - mStartX;
mY = (int) event.getY() - mStartY;
mLinearLayout.layout(mX, mY, mX + mLinearLayout.getWidth(), mY + mLinearLayout.getHeight());
return true;
}
return false;
}
});
}
I also found a bug/feature/issue, which is absolutely new for me: When I remove the background in my note root element (which is currently transparent) the note is only visible within the 200dp width/height I have set in the inner LinearLayout. So its not fill_parent
, its wrap_content
even as I set it to fill_parent
. So layout_width
and layout_height
only use the given fill_parent
when a background is set... weired...
See Question&Answers more detail:
os