5

Tôi đang tự động thêm chế độ xem vào bố cục tương đối và định nghĩa chúng theo cách lập trình. Các khung nhìn có thể được di chuyển xung quanh màn hình để vị trí của chúng thay đổi.Đặt chế độ xem động với cài đặt LayoutParams.addRule đến vị trí cuối cùng của chế độ xem

Khi tôi cố gắng đặt chế độ xem (button2) để ngồi bên dưới một chế độ xem khác (button1), button2 được đặt ở vị trí cũ của button1 (vị trí mặc định nơi lượt xem được thêm trước khi di chuyển). Tôi đã liên kết hình ảnh để hy vọng truyền đạt điều này tốt hơn.

Đây là Layout gốc Original Layout

Layout sau Button2 được tái định vị Re-positioned Layout

Tôi có một nền LinkedList giữ theo dõi tất cả những thay đổi quan điểm và xem thuộc tính cho cách bố trí nếu mà làm cho một sự khác biệt.

Sau đây là các chức năng mã:

Làm thế nào tôi lại vị Button1:

Buttons b = (Buttons) viewIndex; 
           positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); 
           positioningLayout.addRule(RelativeLayout.CENTER_VERTICAL); 
           b.setLayoutParams(positioningLayout); 
           baseLayout.addView(b); 

tái định vị xem bên dưới một đoạn xem Code:

Buttons b = (Buttons) viewIndex; 
           positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); 
           positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); 
           b.setLayoutParams(positioningLayout); 
           b.invalidate(); 

Làm thế nào tôi thêm các chế độ xem cho bố cục.

uiList.addView(new Buttons(this), "BUTTON"); 
      setDialogView(uiList.getLast()); 
      showDialog(SET_ID); 
      reloadUI(); 

setDialogView chỉ chuyển giao ID tới chế độ xem (để kiểm tra) theo cách thủ công. reloadUI() chỉ tìm thấy khung nhìn cuối cùng được thêm vào nền LinkedList và thêm nó vào relativeLayout bằng cách sử dụng .addView;

Nếu bạn cần thêm mã, vui lòng cho tôi biết. Tôi có thiếu cuộc gọi để cập nhật bố cục chế độ xem sau khi thực hiện thay đổi đối với chế độ xem con tương đối không? Nó có vẻ như xem là nhận được vị trí trực quan nhưng LayoutParams thực tế không cập nhật vì vậy khi bạn đặt Button2 to Button1 nó nhận được vị trí cũ.

Có cách nào để buộc bố trí lại chế độ xem bố cục tương đối không?

+0

bạn có thể chỉ cho cách bố trí chính? –

+0

Giao diện người dùng đang được tạo động hoàn toàn do đó không có XML nào đang được sử dụng:/ – Sevros

Trả lời

2

Tôi nghĩ bạn nên thử giải pháp đơn giản - thay thế b.invalidate() bằng b.requestLayout(). Để kiểm tra lý lịch chi tiết hơn this link. Tôi đã không thử nghiệm nó nhưng tôi hy vọng nó sẽ làm việc. Vì vậy, các mã nên trông giống như:

Buttons b = (Buttons) viewIndex; 
positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); 
positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); 
b.setLayoutParams(positioningLayout); 
b.requestLayout(); 

Hoặc có thể bạn có thể đơn giản hóa này để:

Buttons b = (Buttons) viewIndex; 
((RelativeLayout.LayoutParams) b.getLayoutParams()).addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); 
b.requestLayout(); 
+0

Điều này có hiệu quả, cảm ơn bạn! Bạn có thể giải thích tại sao requestlayout() hoạt động nhưng không làm mất hiệu lực()? Tôi không nghĩ rằng requestlayout() làm mới khung nhìn khi nó được gọi. – Sevros

+0

Chắc chắn, 'requestLayout()' nên được gọi, khi vị trí hoặc giới hạn của khung nhìn trong bố cục cha mẹ đã được thay đổi, trong khi 'invalidate()' nên được gọi khi hiển thị của khung nhìn đã bị thay đổi. Một mặt, khi bạn gọi phương thức 'requestLayout()' thì phương thức 'onLayout()' và 'onMeasure()' của khung nhìn sẽ được kích hoạt, mặt khác khi bạn gọi 'invalidate()', sau đó 'onDraw () 'phương thức sẽ được kích hoạt. – rom4ek

+0

Vì vậy, 'invalidate()' chỉ vẽ lại chính nó, khi 'requestLayout()' cập nhật vị trí và giới hạn của khung nhìn. Bạn đang chào đón và tôi đang tìm kiếm tiền thưởng của bạn: D – rom4ek

1

Dường như bạn đang đi đúng hướng nhưng đang thực hiện một sai lầm nhỏ. Nếu không có nhiều mã thì sẽ rất khó để cung cấp giải pháp thực tế. Nhưng tôi sẽ cố gắng chỉ ra sai lầm.

Xem, để tương đối mục vị trí lập trình trong một RelativeLayout bạn phải gán id độc đáo cho mỗi trong số họ.

Giống như,

Button b = new Button(this); 
b.setId(1); 

Button c = new Button(this); 
c.setId(2); 

Mỗi phần tử nên có id độc đáo.

Bây giờ nếu bạn muốn đặt nút b theo chiều dọc ở trung tâm,

layout.addRule(RelativeLayout.CENTER_VERTICAL); 
b.setLayoutParams(layout); 

Bây giờ nếu bạn muốn đặt nút c dưới nó,

layout.addRule(RelativeLayout.BELOW, b.getId()); 
layout.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
b.setLayoutparams(layout); 

Điều này chắc chắn sẽ đặt nút c nút dưới đây b.Như bạn đã nói, bạn có thể sử dụng bất kỳ cấu trúc dữ liệu nào mà bạn chọn để theo dõi các id của từng phần tử.

1

Đây chỉ là ví dụ chi tiết về cách bạn di chuyển nút một cách chính xác. Vì vậy, đầu tiên, tạo một id duy nhất cho View, tức là tạo ra một tập tin tài nguyên XML mới trong res/values/, và đặt tên là ids.xml:

structure

Và nội dung của ids.xml là:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <item name="button_1" type="id"/> 
    <item name="button_2" type="id"/> 
</resources> 

Chúng tôi phải đặt id thành bố cục chính của bạn:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/layout_main"> <!-- the id --> 

    <!-- content of this layout --> 

</RelativeLayout> 

Sau đó, hãy tạo thứ e Button s:

RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout_main); 

    final Button button1 = new Button(this); 
    button1.setId(R.id.button_1); 
    button1.setText("BUTTON 1"); 
    button1.setTextColor(Color.BLACK); 

    final Button button2 = new Button(this); 
    button2.setId(R.id.button_2); 
    button2.setText("BUTTON 2"); 
    button2.setTextColor(Color.BLACK); 

    relativeLayout.addView(button1, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, 
      RelativeLayout.LayoutParams.WRAP_CONTENT)); 
    relativeLayout.addView(button2, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, 
      RelativeLayout.LayoutParams.WRAP_CONTENT)); 

    RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) button1.getLayoutParams(); 
    params1.addRule(RelativeLayout.CENTER_IN_PARENT); // set to the center of screen 
    button1.setLayoutParams(params1); 

    final RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) button2.getLayoutParams(); 
    params2.addRule(RelativeLayout.ALIGN_PARENT_TOP); 
    params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
    button2.setLayoutParams(params2); 

    button2.setOnClickListener(new View.OnClickListener() { 
     @SuppressLint("NewApi") 
     @Override 
     public void onClick(View v) { 
      /* We need to remove the existing rules and update it! 
      * For API 16 and earlier, set the rule to 0, e.g. --> layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0); 
      * For API 17 and higher, call layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_LEFT); 
      */ 

      int api = android.os.Build.VERSION.SDK_INT; 
      if (api >= Build.VERSION_CODES.JELLY_BEAN_MR1) { // API level 17 
       params2.removeRule(RelativeLayout.ALIGN_PARENT_TOP); 
       params2.removeRule(RelativeLayout.ALIGN_PARENT_LEFT); 
      }else if (api < Build.VERSION_CODES.JELLY_BEAN_MR1) { 
       params2.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0); 
       params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0); 
      } 

      params2.addRule(RelativeLayout.CENTER_IN_PARENT); 
      params2.addRule(RelativeLayout.BELOW, R.id.button_1); // place below button1 
      button2.setLayoutParams(params2); 
     } 
    }); 

Vì vậy, khi bạn nhấp vào button2, nó sẽ di chuyển xuống dưới button1.

+0

Cảm ơn bạn đã trả lời nhanh nhưng đáng buồn là điều này không hoạt động – Sevros

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