2011-06-07 38 views
25

Tôi không thể lấy các phần tử của mình, ví dụ: ListView, để đổi kích thước chính xác.Cách đặt kích thước và bố cục trong onSizeChanged?

Tôi đã nhận được ListActivity để tìm kiếm, với trang tổng quan, hộp chỉnh sửa và chế độ xem danh sách. Ý tưởng là để ẩn thanh hành động trong khi bàn phím đang hiển thị.

tôi mở rộng LinearLayout, để nghe xem các thay đổi kích thước (theo khuyến cáo here):

public class SizeChangingLinearLayout extends LinearLayout { 
    //... 
    @Override 
    protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) 
    {   
     View actionbar = mainView.findViewById(R.id.actionbar); 

     if (yNew > yOld) 
      actionbar.setVisibility(View.VISIBLE); 
     else if (yNew < yOld) 
      actionbar.setVisibility(View.GONE); 

     super.onSizeChanged(xNew, yNew, xOld, yOld); 

    } 
} 

Các ẩn/hiển thị của actionbar việc như mong đợi nhưng có một khoảng cách dưới ListView của cùng một chiều cao như thanh tác vụ ẩn. Ngay sau khi bất kỳ thay đổi đồ họa nào (ví dụ: viết trong hộp chỉnh sửa), ListView sẽ lấp đầy khoảng trống. Một hành vi tương tự xuất hiện ngược lại, khi ẩn bàn phím.

enter image description here

[Chỉnh sửa]

Vấn đề tương tự cũng xuất hiện trong việc thay đổi cách bố trí khác. Thay đổi Visibility những thứ trong onSizeChanged hiển thị trực tiếp, nhưng thay đổi kích thước và lề không hiển thị cho đến khi một số hành động người dùng khác vẽ lại các chế độ xem đó. Việc vô hiệu không hoạt động từ onSizeChanged.

[/ Chỉnh sửa]

Tôi đã cố gắng để làm mới đồ họa theo:

  • invalidate -ing cả tùy chỉnh LinearLayout và ListView (như khuyến here)
  • notifyDataSetChanged trên danh sách của bộ chuyển đổi
  • forceLayout

... và hơn thế nữa, không thành công. Tại sao ListView không thay đổi kích thước lúc đầu? Tôi có phải ghi đè onLayout trong LinearLayout mở rộng của mình không? Tôi đã bỏ lỡ điều gì?

+0

Không bất kỳ bản cập nhật hoạt động, tôi nhận thấy. "Ngay sau khi thay đổi đồ họa", tôi đã viết. Nhưng ví dụ một cửa sổ bật lên sẽ không thực hiện các thay đổi được hiển thị. Tôi đoán các yếu tố phải được vô hiệu hóa, nhưng họ không. – JOG

+0

Sự cố cũng xuất hiện cho tất cả thay đổi bố cục, ví dụ: thay đổi lề của EditText. Tuy nhiên, các phần tử bố cục _adding_, ví dụ: một nút ở bên phải hộp, hiển thị ngay lập tức. – JOG

Trả lời

32

Thêm sau vào cuối onSizeChanged() sẽ giải quyết nó:

Handler handler = new Handler(); 
handler.post(new Runnable() { 

    @Override 
    public void run() { 
     requestLayout(); 
    } 
}); 

Xem câu trả lời cho câu hỏi này: Views inside a custom ViewGroup not rendering after a size change

+12

Chế độ xem có phương thức post(), vì vậy bạn không cần phải phân bổ Trình xử lý. – ThomasW

+0

Tôi đã thay đổi kích thước của chế độ xem con trong 'onSizeChanged', vì vậy tôi phải đặt lại kích thước của chế độ xem con đã nói trong runnable trước khi gọi' requestLayout() ' –

0

Đây có thể là một cú sút xa bất ...

Các bạn đã thử chơi với các thiết lập android:layout_height="" cho ListView?

Có thể sử dụng match_parent hoặc wrap_content có thể buộc nó để làm việc ...

Như tôi đã nói ... một shot dài!

+0

Giống như gợi ý của @ PravinCG, nó không hoạt động. Rõ ràng không có thay đổi bố cục nào được thực hiện trong 'onSizeChanged' trên bất kỳ Chế độ xem nào được áp dụng cho đến khi một bản cập nhật bố cục khác được thực hiện. – JOG

0

Bạn có thể buộc các ListView để vẽ lại bằng cách thay đổi chiều cao của nó bằng 1px và gọi

requestLayout()

+0

Đã thử nó, và nó không hoạt động, không may: 'setLayoutParams (new LayoutParams (LayoutParams.FILL_PARENT, (int) getResources(). GetDimension (R.dimen.another_value))); ' ' requestLayout(); ' Chỉ có chiều cao mới sau bất kỳ thay đổi bố cục nào khác. Giống như trong ảnh chụp màn hình của tôi. Các hành vi tương tự cũng xuất hiện trên tất cả các lần xem Tôi cố gắng thao tác trong phương thức 'onSizeChanged'. – JOG

0

Có thể làm những gì bạn muốn bằng cách đăng ký một setOnFocusChangeListenersetOnClickListener đến EditText.

Có rất nhiều kịch bản khác nhau cần xem xét khi nói đến điều hướng và mọi thứ có thể cần phải được thay đổi để hoạt động với bố cục nhất định.

Dù sao, hãy bắt đầu bằng cách ghi đè lênSizeChanged để hiển thị phần tử bị ẩn khi chạm vào nút quay lại.

public class MyLinearLayout extends LinearLayout { 

    private MyListActivity mMyListActivity; 

    public MyLinearLayout(Context context) { 
     super(context); 
    } 

    public MyLinearLayout(Context context, AttributeSet attrs) { 
     super(context, attrs);  
    } 

    public void setMyListActivity(MyListActivity mla) { 
     mMyListActivity = mla; 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     // show the element when we get more room  
     if (h > oldh) { 
      if (mMyListActivity != null) { 
       mMyListActivity.showBar(); 
      } 
     } 
     super.onSizeChanged(w, h, oldw, oldh); 
    } 
} 

Trong ListActivity, chúng tôi lấy MyLinearLayout và pass this vào nó. Sau đó, setOnFocusChangeListener được đăng ký để xử lý mọi thứ khi tiêu điểm của EditText thay đổi. SetOnClickListener được sử dụng để ẩn phần tử khi EditText đã có tiêu điểm.

public class MyListActivity extends ListActivity { 

    private ArrayList<MyData> mDataList = new ArrayList<MyData>(); 

    private MyLinearLayout mMyLinearLayout; 
    private LinearLayout mHideMeLinearLayout; 
    private EditText mEditText; 

    public void showBar() { 
     if (mHideMeLinearLayout != null) { 
      mHideMeLinearLayout.setVisibility(View.VISIBLE); 
     } 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     // Get MyLinearLayout and pass this to it. 
     mMyLinearLayout = (MyLinearLayout) findViewById(R.id.myLinearLayout); 
     mMyLinearLayout.setMyListActivity(this); 

     // the LinearLayout to be hidden 
     mHideMeLinearLayout = (LinearLayout) findViewById(R.id.LinearLayoutToHide); 

     mEditText = (EditText) findViewById(R.id.editText);  
     mEditText.setOnFocusChangeListener(new OnFocusChangeListener() { 
      @Override 
      public void onFocusChange(View v, boolean hasFocus) { 
       InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE); 
       if (hasFocus) { 
        imm.showSoftInput(mEditText, 0); 
        mHideMeLinearLayout.setVisibility(View.GONE); 
       } else { 
        imm.hideSoftInputFromWindow(mMyLinearLayout.getWindowToken(), 0); 
        mHideMeLinearLayout.setVisibility(View.VISIBLE); 
       } 
      } 
     }); 
     mEditText.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       mHideMeLinearLayout.setVisibility(View.GONE); 
      } 
     }); 

     ..... 
    } 

    ..... 
} 

Tôi sẽ cung cấp ví dụ làm việc sau, nhưng phải chạy ngay bây giờ.

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