2010-09-10 31 views
5

Tôi có bố cục có thể hơi khác thường. Cấu trúc như sau:Bố cục với vị trí động

<?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 tôi ở dưới cùng của XML có một bố cục XML quá:

<?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 của tôi:

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

Những gì tôi muốn làm: Tôi muốn có thể thay đổi vị trí của CustomRelativeLayout của tôi. Nó nên được làm theo liên lạc của tôi. Nó nhỏ hơn so với SurfaceView và nên "trượt" ở trên sau liên lạc của tôi ...

Có hai vấn đề:

  1. Các onTouchListener ràng buộc để mLinearLayout (trong CustomRelativeLayout) chỉ được kích hoạt một lần và chỉ cho ACTION_DOWN. Tôi chỉ thấy đầu ra nhật ký chỉ một lần
  2. Ghi chú không bao giờ thay đổi vị trí, nó không bao giờ được vẽ lại bằng ma trận đã thay đổi ... Tôi thấy đầu ra được nêu trong onDraw không bao giờ sau khi chạm xảy ra.

Thứ nhất có thể là do SurfaceView cũng xử lý các sự kiện chạm. Nhưng tôi nghĩ nếu CustomRelativeLayout xử lý nó trước, nó sẽ hoạt động.

Một số ý tưởng?

Chỉnh sửa cho giải pháp

Nhờ Xil3 tôi đã có thể loại bỏ các bức tường tôi đã chạy vào ... đây là giải pháp của tôi:

lưu ý tôi 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> 

Và đây là nhà xây dựng của tôi:

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

Tôi cũng tìm thấy lỗi/tính năng/vấn đề, hoàn toàn mới đối với tôi: Khi tôi xóa nền trong phần tử gốc ghi chú của tôi (hiện đang trong suốt), ghi chú chỉ hiển thị trong chiều rộng/chiều cao 200dp mà tôi đã đặt ở bên trong LinearLayout. Vì vậy, nó không phải fill_parent, wrap_content của nó ngay cả khi tôi đặt nó là fill_parent. Vì vậy, layout_widthlayout_height chỉ sử dụng fill_parent nhất định khi nền được thiết lập ... chúng tôi đã ...

Trả lời

2

Vấn đề là bạn trả về false trong sự kiện onTouch - vì vậy, về cơ bản bạn đang nói rằng bạn ' không quan tâm đến bất kỳ sự kiện tiếp theo nào.

Thay đổi điều đó để trả về giá trị đúng.

+0

phải ... * smackmyhead * nhưng vấn đề thứ hai vẫn còn ... nó không bao giờ thay đổi vị trí vì 'onDraw' không bao giờ được gọi. Tôi đã sửa lỗi này bằng cách gọi 'onDraw' trong cùng một luồng mà SurfaceView đang chạy. Không có cách nào tốt hơn bằng cách sử dụng 'invalidate()' bằng cách nào đó? – WarrenFaith

+0

hmm, có phải là một chuỗi giao diện người dùng không? Nếu không, hãy thử postInvalidate() – xil3

+0

Tôi đã thêm giải pháp của mình dựa trên câu trả lời cho câu hỏi của tôi. Cảm ơn! – WarrenFaith

Các vấn đề liên quan