2009-05-04 33 views
23

Tôi đang sử dụng chế độ xem tiêu đề tùy chỉnh trong ứng dụng của tôi cho từng hoạt động. Trong một trong các hoạt động, dựa trên các lần nhấp nút, tôi cần phải thay đổi chế độ xem tiêu đề tùy chỉnh. Bây giờ điều này làm việc tốt mỗi khi tôi thực hiện một cuộc gọi đến setFeatureInt.Android - thay đổi chế độ xem tiêu đề tùy chỉnh tại thời gian chạy

Nhưng nếu tôi cố gắng cập nhật bất kỳ mục nào trong tiêu đề tùy chỉnh (nói thay đổi văn bản của nút hoặc chế độ xem văn bản trên tiêu đề), bản cập nhật sẽ không diễn ra.

Gỡ lỗi thông qua mã cho thấy chế độ xem văn bản và các phiên bản nút không rỗng và tôi cũng có thể thấy thanh tiêu đề tùy chỉnh. Nhưng văn bản trên chế độ xem văn bản hoặc nút không được cập nhật. Có ai khác phải đối mặt với vấn đề này? Làm cách nào để giải quyết?

Cảm ơn.

EDIT

Đây là những gì tôi đã cố gắng. Không được cập nhật ngay cả khi đang gọi postInvalidate.

getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.text_title); 

    TextView databar = (TextView) findViewById(R.id.title_text); 
    databar.setText("Some Text"); 
    databar.postInvalidate(); 

    Button leftButton = (Button) findViewById(R.id.left_btn); 
    leftButton.setOnClickListener(mLeftListener); 
    leftButton.setText("Left Btn"); 
    leftButton.postInvalidate(); 

    Button rightBtn = (Button) findViewById(R.id.right_btn); 
    rightBtn.setOnClickListener(mRightListener); 
    rightBtn.postInvalidate(); 
+0

Xem giải pháp thay thế này http://stackoverflow.com/questions/8634319/how-to-set-different-title-for-alert-dialog-when-webview-page-is-loaded/9394561#9394561 – Sameer

Trả lời

30

Vấn đề là chỉ Window thực hiện (PhoneWindow) sử dụng một LayoutInflater trong phương pháp setFeatureInt và instantiates cách bố trí mới với inflateattachToRoot=true. Do đó, khi bạn gọi setFeatureInt, bố cục mới không được thay thế nhưng đính kèm vào vùng chứa tiêu đề nội bộ và do đó được vẽ lên nhau.

Bạn có thể giải quyết vấn đề này bằng cách sử dụng phương thức trợ giúp sau thay vì setFeatureInt. Các helper chỉ đơn giản là loại bỏ tất cả các quan điểm từ container tiêu đề nội bộ trước khi tính năng tiêu đề tùy chỉnh mới được thiết lập:


private void setCustomTitleFeatureInt(int value) { 
    try { 
     // retrieve value for com.android.internal.R.id.title_container(=0x1020149) 
     int titleContainerId = (Integer) Class.forName(
      "com.android.internal.R$id").getField("title_container").get(null); 

     // remove all views from titleContainer 
     ((ViewGroup) getWindow().findViewById(titleContainerId)).removeAllViews(); 

     // add new custom title view 
     getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, value); 

    } catch(Exception ex) { 
     // whatever you want to do here.. 
    } 
} 

Tôi không chắc chắn cho dù hành vi hiện tại setFeatureInt là dự định, nhưng nó chắc chắn là không được minh chứng một cách này hay cách khác đó là lý do tôi sẽ thực hiện việc này để các nhà phát triển android;)

EDIT

Như đã chỉ ra trong các ý kiến, thực hiện giải pháp nói trên không phải là lý tưởng. Thay vì dựa vào hằng số com.android.internal.R.id.title_container, bạn có thể chỉ cần ẩn tựa đề tùy chỉnh cũ bất cứ khi nào bạn đặt tiêu đề mới.

Giả sử bạn có hai bố cục tiêu đề tùy chỉnh:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout android:id="@+id/custom_title_1" ... 

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout android:id="@+id/custom_title_2" ... 

và bạn muốn thay thế custom_title_1 với custom_title_2, bạn có thể che giấu cũ và sử dụng setFeatureInt thêm sau:

findViewById(R.id.custom_title_1).setVisibility(View.GONE); 
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_2); 
+1

Điều gì xảy ra nếu bất kỳ giá trị nào trong số này (title_container, com.android.internal) trong các phiên bản sau? Điều đó sẽ không ảnh hưởng đến ứng dụng? – lostInTransit

+1

Bạn hoàn toàn đúng. Mặc dù hằng số com.android.internal.title_container không có khả năng thay đổi nhưng không thể dựa vào nó. Đây là cách giải quyết xấu nhất. –

+0

Cảm ơn. Giải pháp khác này hoạt động rất tốt. Nhưng tôi thực sự không hiểu tại sao setFeatureInt nên thêm lượt xem ở trên thay vì thay thế chúng? Esp với các lượt xem nhất định là số ít - giống như tiêu đề! – lostInTransit

0

Bạn đang gọi số không hợp lệ hoặc postInvalidate để vẽ lại chế độ xem sau khi cập nhật văn bản? Nếu đó là Chế độ xem tùy chỉnh, bạn có thể đặt điểm ngắt trong mã vẽ để đảm bảo rằng nó được gọi không?

Nếu bạn đang ở trên chuỗi giao diện người dùng, bạn có thể gọi 'không hợp lệ' nếu bạn không, bạn phải gọi 'postInvalidate' hoặc chế độ xem sẽ không tự vẽ lại.

+0

Nếu nó giúp, khung nhìn được vẽ lại coz Tôi thấy thanh tiêu đề cập nhật nhưng các điều khiển trên thanh tiêu đề không thay đổi – lostInTransit

0

Chỉ cần giá trị 2c của tôi:

Khi làm việc trong MapActivity, yêu cầu tiêu đề tùy chỉnh dẫn đến không có tiêu đề nào được hiển thị. May mắn thay, tất cả những gì tôi muốn làm là đặt văn bản tiêu đề khác nhau, và tôi sớm nhận ra rằng chỉ cần gọi setTitle() bên trong onCreate() làm việc cho tôi (tôi gọi nó sau khi tôi gọi setContentView())

Xin lỗi, nhưng tôi không có thời gian để sửa lỗi này nữa và tìm ra lý do tại sao những gì tôi đang làm không hoạt động, và tại sao thay đổi nó làm cho nó hoạt động. Như tôi đã nói, chỉ nghĩ rằng điều này có thể giúp ai đó ra đường.

13

Các cách chính xác để làm điều này là như sau:

requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
setContentView(R.layout.my_layout); 
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_custom_title); 
super.onCreate(savedInstanceState); 

Xin lưu ý rằng thứ tự của các báo cáo này là rất quan trọng.

Nếu bạn gọi super.onCreate() trước bất kỳ câu lệnh nào khác, bạn sẽ nhận được thanh tiêu đề trống, việc tìm kiếm id tiêu đề và xóa tất cả Chế độ xem khỏi nó sẽ khắc phục nhưng không được khuyến nghị.

+0

OP đang cố thay đổi thanh tiêu đề trong khi chạy, sau khi onCreate(). – CACuzcatlan

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