2012-01-06 26 views
19

Tôi có LinearLayout mà tôi muốn thay đổi màu nền khi một trong các khung nhìn con của nó (một ImageButton) được nhấp. Tôi có thể làm điều này, nhưng không phải ngay lập tức - sự thay đổi không xảy ra trên màn hình cho đến sau này (tôi nghĩ trong một cuộc gọi onResume). Tôi muốn tìm hiểu cách buộc bố cục vẽ lại sau khi nền được đặt, trước khi dòng mã tiếp theo thực thi. Đây là phương thức onClick của OnClickListener của tôi cho nút:Cách ép buộc xem lại để vẽ lại ngay trước khi dòng mã tiếp theo được thực thi

public void onClick(View v) { 

    LinearLayout parentLayout = (LinearLayout) v.getParent(); 
    parentLayout.setBackgroundResource(R.color.my_color); 
    SystemClock.sleep(1000); //ms 

} 

Lệnh ngủ nằm trong đó để kiểm tra xem việc vẽ lại có xảy ra trước hoặc sau nó. Kết quả: sau. Hầu hết các câu hỏi về chủ đề này (như herehere) nói để sử dụng invalidate() trên chế độ xem. Tôi đã sử dụng các lệnh parentLayout.invalidate();, parentLayout.postInvalidate();parentLayout.refreshDrawableState(); ở giữa các đường nền và dòng ngủ, tất cả đều không có sẵn. Việc vẽ lại vẫn xảy ra sau lệnh ngủ. Bất cứ ai có thể cho tôi biết làm thế nào để làm cho nó xảy ra ngay lập tức?

Thông tin có thể hữu ích khác: LinearLayout được gắn với các hàng của một ListView và OnClickListener ở trên là trong một lớp tùy chỉnh mở rộng SimpleCursorAdapter, không phải trong chính hoạt động đó. (Bằng cách này tôi có thể thiết lập một người nghe cho mỗi hàng trong ListView.)

+0

Dường như bạn sẽ không nhận được câu trả lời chính xác cho điều này ít nhất là tôi không thể tìm thấy câu trả lời. Bạn có thể cho chúng tôi biết tại sao bạn cần xem lại để được vẽ lại ngay lập tức? Có thể sẽ có các giải pháp khác để giải quyết vấn đề. – manjusg

+0

@manjusg Những gì tôi đang cố gắng chỉ là những gì thường được thực hiện với bộ chọn nền của chế độ xem trong xml (nền ngắn thay đổi màu khi được nhấn ngay trước khi thực hiện gọi lại), ngoại trừ việc tôi muốn thay đổi nền của chế độ xem khác với nút được nhấn - cụ thể là bố cục chứa nút và cũng là chế độ xem văn bản. – pvans

+0

@manjusg Các hàng trong listview của tôi có văn bản và nút xóa, và tôi muốn toàn bộ hàng, bao gồm cả textview, được đánh dấu ngắn trước khi nó bị xóa và xóa, để người dùng có một số phản hồi mà anh ta đã nhấn hàng anh ta định làm. Có lẽ có một số cách để xem qua liên kết với một bộ chọn trong xml? – pvans

Trả lời

2

Được rồi, cuối cùng tôi đã tìm được giải pháp cho vấn đề này và thật đơn giản. Có vẻ như vấn đề chỉ là tôi đang thực hiện các thay đổi có thể kéo được trong OnClickLIstener, khi tôi nên làm điều đó trong một OnTouchListener. Nếu tôi đặt OnTouchListener cho nút tìm ACTION_DOWN và sau đó chạy setBackgroundColor trên bố cục gốc, thay đổi sẽ xảy ra ngay lập tức.

Giải pháp thay thế, ít mạnh mẽ hơn là từ this post. Bạn có thể gán một bộ chọn cho nền bố trí cha mẹ trong xml, sau đó trong OnTouchListener được đề cập ở trên, hãy chạy setPressed (true) trên bố cục đó. Nó không phải là một giải pháp tuyệt vời bởi vì bộ chọn cung cấp cho bạn rất ít tự do hơn là trực tiếp thay đổi các thuộc tính của khung nhìn trong mã. Bạn không thể đặt nền bố cục thành một màu khác bằng cách nhấn một nút khác, ví dụ.

Nhờ những người đã trợ giúp với các đề xuất về điều này!

1

thực hiện các thay đổi và gọi listview.invalidate(); để phản ánh những thay đổi đó trên giao diện người dùng

+0

Tôi không có quyền truy cập trực tiếp vào chính ListView trong mã này, vì nó nằm trong lớp bộ điều hợp, không phải là hoạt động. Tôi có thể tham chiếu đếnListView bằng cách sử dụng dòng này: 'mActivity.mListView.invalidate();' (mActivity là hoạt động gọi được lấy từ Context, mListView là một trường công khai của hoạt động tham chiếu đến ListView), nhưng chèn dòng này trước giấc ngủ vẫn không khắc phục được vấn đề. – pvans

3

Bạn có thể thử forceLayout() với cuộc gọi đến draw(canvas) ngay sau đó. Nếu bạn không ghi đè onLayout(), onMeasure, draw() hoặc onDraw(), thì triển khai mặc định sẽ chạy. Vấn đề duy nhất với điều này là bạn phải lấy Canvas hoặc tạo một cách thủ công.

Bạn không nên theo đuổi cách tiếp cận này vì Android được thiết kế đặc biệt để tránh vẽ bên ngoài các bản cập nhật bình thường. Trong khi bạn chính xác rằng invalidate() không xảy ra ngay lập tức, đó là cách an toàn nhất và tốt nhất để khuyến khích vẽ lại. Nếu bạn muốn xử lý bản vẽ bên ngoài các bản cập nhật, Android cung cấp một cách để làm điều đó với lớp SurfaceHolder.

+0

Hmm. Tôi nghĩ rằng tôi muốn tránh thực hành mạnh mẽ nản lòng. Tôi đang thêm một số thông tin thêm về những gì tôi đang cố gắng thực hiện như một bình luận trong câu hỏi. – pvans

+0

Điều đó đang được nói, một điều cần xem xét: Nguyên tắc Android khuyến khích mạnh mẽ không bao giờ chặn chuỗi giao diện người dùng vì lý do. Bằng cách đặt lệnh 'SystemClock.sleep()', bạn đang chặn luồng UI. Nếu đây là để thử nghiệm lý thuyết, tuyệt vời! Vui lòng cho chúng tôi biết kết quả của bạn. Nếu điều này là cho một ứng dụng thế giới thực, tôi sẽ mạnh mẽ xem xét bạn reanalyzing chương trình của bạn. –

+0

Giấc ngủ chỉ để thử nghiệm. Mặc dù tò mò, bạn nên thực hiện tạm dừng như thế nào giữa một lần nhấp và hành động gọi lại được liên kết? – pvans