2011-10-02 27 views
7

Tôi có một ứng dụng bằng cách sử dụng ActionBar, nơi tôi xử lý định hướng thay đổi bản thân mình:ActionBar công suất/tràn không thay đổi về biến đổi định hướng

android:configChanges="keyboard|keyboardHidden|orientation|screenSize" 

... và menu nên phù hợp trong ActionBar mà không tràn trong cảnh quan, nhưng không phải trong bức chân dung:

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android"> 
<item android:title="@string/Game" android:id="@+id/game" android:icon="@android:drawable/ic_menu_manage"  android:showAsAction="ifRoom|withText"/> 
<item android:title="@string/Type" android:id="@+id/type" android:icon="@android:drawable/ic_menu_edit"  android:showAsAction="ifRoom|withText"/> 
<item android:title="@string/Other" android:id="@+id/other" android:icon="@android:drawable/ic_menu_gallery" android:showAsAction="ifRoom|withText"/> 
<item android:title="@string/Solve" android:id="@+id/solve" android:icon="@android:drawable/ic_menu_directions" android:showAsAction="ifRoom|withText"/> 
<item android:title="@string/Help" android:id="@+id/help" android:icon="@android:drawable/ic_menu_help"  android:showAsAction="ifRoom"/> 
</menu> 

Ngày khởi động, điều này làm việc một cách chính xác:

Cảnh: wide ActionBar with all items in

Portrait: narrow ActionBar with overflow (vâng, tôi có thể buộc tất cả các mặt hàng để luôn luôn hiển thị và họ sẽ phù hợp, như hình dưới đây, nhưng điều đó có thể phá vỡ trên một tấm bảng nhỏ hơn)

Khi giả lập thay đổi định hướng, các ActionBar của công suất dường như không thay đổi:

Portrait, khi tôi bắt đầu trong cảnh quan: narrow ActionBar with all items in (điều này là ok, nhưng không phù hợp)

Lan dscape, khi tôi bắt đầu theo chiều dọc: wide ActionBar with overflow Điều này có vẻ ngớ ngẩn và là lý do tôi muốn sửa lỗi này.

tôi thêm cuộc gọi này để invalidateOptionsMenu(), nhưng nó không giúp:

@Override 
public void onConfigurationChanged(Configuration newConfig) 
{ 
    maybeMoveSomeViewsAround(newConfig); 
    super.onConfigurationChanged(newConfig); 
    invalidateOptionsMenu(); 
} 

(Trên thực tế tôi gọi nó bằng cách phản chiếu cho khả năng tương thích ngược, nhưng chương trình gỡ rối nói với tôi nó thực sự được gọi và không gặp gỡ một ngoại lệ.)

invalidateOptionsMenu() thực sự kết thúc bằng cách gọi onCreateOptionsMenu() (làm tăng lại menu) trước khi quay trở lại và tôi có thể thấy bên trong hướng dẫn sau đó getResources(). getConfiguration(). Vì vậy, điều này thực sự khó hiểu. Nếu trình đơn tùy chọn đang được tạo lại, khi định hướng đã thay đổi, nó phải là ActionBar chính nó đệm chiều rộng?

Có cách nào để tạo lại ActionBar mà không phá hủy/tạo Hoạt động không? (vì trường hợp sau có một chút tốn kém trong trường hợp của tôi)

Chỉnh sửa: Đây là số minimal sample project hiển thị sự cố.

Chỉnh sửa 2: Tôi đã kiểm tra chiều rộng màn hình và điều chỉnh các cờ showAsAction theo chương trình giữa luôn và không bao giờ thích hợp, nhưng yêu cầu phải biết (hoặc đoán) chiều rộng của mỗi mục. ActionBar's public API không giúp tôi vào thời điểm đó.

+0

Bạn có thể tạo và gửi một dự án mẫu đầy đủ chứng minh vấn đề này? Ngoài ra, bạn đã thử điều này trên phần cứng chưa? Có thể đây là một vấn đề mô phỏng cụ thể. – CommonsWare

+0

@CommonsWare Ok, xem phần chỉnh sửa của tôi ở cuối cho dự án mẫu. Tôi hiện không có phần cứng máy tính bảng, nhưng tôi sẽ tham dự sự kiện Lab dành cho nhà phát triển Android về máy tính bảng vào Thứ Tư, vì vậy tôi có thể thử ở đó. –

+1

Tôi có thể tái tạo sự cố trên XOOM chạy Android 3.2. Điều này giống như một con bọ. Tôi đã tiếp tục và đã gửi một vấn đề cho nó: http://code.google.com/p/android/issues/detail?id=20493 – CommonsWare

Trả lời

2

Tôi đã thận trọng làm việc xung quanh vấn đề này: khi chiều rộng của thiết bị lớn hơn 850dip, buộc hiển thị tất cả các mục trong ActionBar, nếu không tiếp tục để nền tảng quyết định.

Here's the git commit. Chỉnh sửa:follow-up commit để khắc phục bằng cách sử dụng trường quá mới, oops.:-)

Tôi chắc chắn vẫn quan tâm đến các câu trả lời hay hơn (ngoài việc chờ sửa chữa nền tảng).

5

Tôi đã gặp sự cố này và đã đưa ra một bản hack hoạt động 100%.

Tôi đã gọi điện đến invalidateOptionsMenu() hai lần. Nhìn vào mã bên dưới:

private boolean hackActionBarReset = false; 

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 

    //a hack to reset the items in the action bar. 
    hackActionBarReset = true; 
    invalidateOptionsMenu(); 
    hackActionBarReset = false; 
    invalidateOptionsMenu(); 

} 

Và trong onCreateOptionsMenu của bạn() thiết lập này đến bạn menuitems bạn muốn hiển thị:

item.setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT | (hackActionBarReset ? MenuItem.SHOW_AS_ACTION_NEVER : MenuItem.SHOW_AS_ACTION_IF_ROOM)); 

Không phải là một giải pháp khá nhưng nó hoạt động.

1

Tôi thấy rằng giải pháp đơn giản và hiệu quả nhất là xóa menu và sau đó tạo lại.

Ví dụ:

Menu menu; 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    this.menu = menu; 
    // Setup code goes here... 
} 

@Override 
public void onOrientationChanged() { 
    if (menu != null) { 
     menu.close(); // Ensure the menu is closed before changing its contents. 
     menu.clear(); 
     onCreateOptionsMenu(menu); // Rebuild the menu. 
    } 
} 
Các vấn đề liên quan