J'ai une disposition qui pourrait être un peu inhabituel. La structure est la suivante:Mise en page avec la position dynamique
<?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>
Mon customRelativeLayout au fond du XML a une mise en page XML aussi:
<?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>
Mon 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);
}
}
Ce que je veux faire: Je veux pouvoir changer la position de mon CustomRelativeLayout. Cela devrait suivre mon contact. Son plus petit que le SurfaceView et devrait « glisser » ci-dessus suite à mon contact ...
Il y a deux problèmes:
- La liaison onTouchListener à mLinearLayout (en CustomRelativeLayout) ne se déclenche une fois et seulement pour ACTION_DOWN. Je vois la sortie du journal une seule fois
- La note ne change jamais la position, elle n'est jamais redessinée avec la matrice modifiée ... Je vois la sortie indiquée dans
onDraw
jamais après le contact.
D'abord, il se peut que SurfaceView gère également les événements tactiles. Mais j'ai pensé que si CustomRelativeLayout le gère en premier, cela devrait fonctionner.
Quelques idées?
Modifier pour une solution
Merci à Xil3 j'ai pu enlever le mur que je tombe sur ... voici ma solution:
ma 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>
Et voici mon constructeur:
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;
}
});
}
J'ai aussi trouvé un bug/feature/issue, ce qui est absolument nouveau pour moi: quand je supprime l'arrière-plan de l'élément racine de ma note (qui est actuellement transparent), la note n'est visible que dans la largeur/hauteur de 200dp LinearLayout. Donc ce n'est pas fill_parent
, c'est wrap_content
même si je l'ai mis à fill_parent
. Alors layout_width
et layout_height
utiliser uniquement le fill_parent
donné quand un arrière-plan est ... weired ...
right ... * smackmyhead * mais le deuxième problème reste ... il ne change jamais la position car 'onDraw' n'est jamais appelé. J'ai corrigé ceci pour le moment en appelant 'onDraw' dans le même thread que le SurfaceView. N'y at-il pas une meilleure façon d'utiliser 'invalidate()' d'une façon ou d'une autre? – WarrenFaith
hmm, est-ce un fil d'interface utilisateur? Sinon, essayez postInvalidate() – xil3
J'ai ajouté ma solution en fonction de votre réponse à ma question. Merci! – WarrenFaith