2010-09-10 5 views
5

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:

  1. 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
  2. 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 ...

Répondre

2

Le problème est que vous retournez faux en cas OnTouch -, vous êtes au fond, ce que vous dire » ne sont pas intéressés par des événements ultérieurs.

Changez cela pour retourner vrai.

+0

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

+0

hmm, est-ce un fil d'interface utilisateur? Sinon, essayez postInvalidate() – xil3

+0

J'ai ajouté ma solution en fonction de votre réponse à ma question. Merci! – WarrenFaith

Questions connexes