2010-09-10 2 views
5

У меня есть макет, который может быть немного необычным. Структура выглядит следующим образом:Макет с динамическим положением

<?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> 

Мой customRelativeLayout в нижней части XML имеет XML-макет тоже:

<?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> 

Мой 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); 
    } 
} 

Что я хочу сделать: Я хочу иметь возможность изменить позицию моего CustomRelativeLayout. Он должен следовать моему прикосновению. Его меньше SurfaceView и должен «слайд» выше после моего прикосновения ...

Есть две проблемы:

  1. onTouchListener связываются с mLinearLayout (в CustomRelativeLayout) включается только один раз и только для ACTION_DOWN. Я вижу вывод журнала только один раз
  2. Примечание никогда не меняет положение, оно никогда не перерисовывается с измененной матрицей ... Я вижу результат, указанный в onDraw, после того, как произошло касание.

Во-первых, возможно, потому, что SurfaceView также обрабатывает события касания. Но я думал, что если CustomRelativeLayout обрабатывает его первым, он должен работать.

Некоторые идеи?

Edit для решения

Благодаря Xil3 я был в состоянии удалить стену, я был бежать в ... вот мое решение:

мое примечание 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> 

И вот мой конструктор:

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; 
     } 
    }); 
} 

Я также нашел ошибку/особенность/проблему, которая для меня совершенно новая: когда я удаляю фон в моем корневом элементе примечания (который в настоящее время прозрачен), заметка видна только в ширине и высоте 200 дп, которые я установил во внутренней LinearLayout. Так что его не fill_parent, его wrap_content, даже когда я установил его на fill_parent. Так layout_width и layout_height только использовать данную fill_parent когда фон установлен ... weired ...

ответ

2

Проблема заключается в том, что вы возвращение ложным в случае onTouch - так, что вы в основном говорю это, что вы» не интересуются никакими последующими событиями.

Измените это, чтобы вернуть true.

+0

правый ... * smackmyhead *, но второй вопрос остается ... он никогда не меняет позицию, потому что 'onDraw' никогда не вызывается. Я исправил это на данный момент, вызвав 'onDraw' в том же потоке, что и SurfaceView. Разве нет лучшего способа использования 'invalidate()' каким-то образом? – WarrenFaith

+0

Хмм, это что-то вроде UI? Если нет, попробуйте postInvalidate() – xil3

+0

Я добавил свое решение на основе вашего ответа на мой вопрос. Благодаря! – WarrenFaith

Смежные вопросы