2011-01-19 41 views
13

Đã đọc qua một số câu hỏi có liên quan ở đây tại SO, cũng như xem qua tài liệu và nguồn Android để cố gắng tìm ra điều này, nhưng tôi bị bối rối, mặc dù listSelector dường như chỉ áp dụng phong cách trên các mục đã chọn, tôi không bị sốc ...Danh sách nhà nước Android ListView không hiển thị nền mặt hàng mặc định

tôi đã một listview quy định tại main.xml đây:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <ListView 
    android:id="@android:id/list" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:fadingEdgeLength="5dp" 
    android:divider="#000000" 
     android:dividerHeight="1dp" 
     android:listSelector="@drawable/list_selector" /> 
    <TextView 
    android:id="@android:id/empty" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:gravity="center" 
     android:singleLine="false" 
     android:text="@string/message_list_empty" /> 
</FrameLayout> 

các listSelector tham chiếu là ở đây (mượn phần lớn từ Danh sách Trạng thái Android mặc định được tìm thấy trong SDK: /android/platforms/android-8/data/res/drawable/list_selector_background.xml):

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <!-- the window has lost focus, disable the items --> 
    <item 
     android:state_window_focused="false" 
     android:drawable="@drawable/shape_row_disabled" /> 

    <!-- the list items are disabled --> 
    <item 
     android:state_enabled="false" 
     android:state_focused="true" 
     android:state_pressed="true" 
     android:drawable="@drawable/shape_row_disabled" /> 
    <item 
     android:state_enabled="false" 
     android:state_focused="true" 
     android:drawable="@drawable/shape_row_disabled" /> 
    <item 
     android:state_enabled="false" 
     android:drawable="@drawable/shape_row_disabled" /> 

    <!-- the list items are enabled and being pressed --> 
    <item 
     android:state_focused="true" 
     android:state_pressed="true" 
     android:drawable="@drawable/shape_row_transition" /> 
    <item 
     android:state_focused="false" 
     android:state_pressed="true" 
     android:drawable="@drawable/shape_row_transition" /> 

    <!-- the list items are enabled and being used --> 
    <item 
     android:state_focused="true" 
     android:drawable="@drawable/shape_row_selected" /> 

    <!-- the default item --> 
    <item 
     android:drawable="@drawable/shape_row" /> 
</selector> 

Các drawables tham chiếu là hình dạng, hình chữ nhật tròn, như vậy:

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="rectangle"> 
    <gradient 
     android:startColor="#EF6100" 
     android:centerColor="#FF8E00" 
     android:endColor="#EF6100" 
     android:angle="270" /> 
    <corners 
     android:bottomRightRadius="7dp" 
     android:bottomLeftRadius="7dp" 
     android:topLeftRadius="7dp" 
     android:topRightRadius="7dp" /> 
</shape> 

Vì vậy, kết quả cuối cùng phải là một ListView với mục có một nền @ drawable/shape_row theo mặc định, và sau đó khác nhau nền màu tùy thuộc vào tiểu bang. Khi tôi kích hoạt danh sách của mình, mọi thứ hoạt động tốt khi trạng thái hoạt động, chẳng hạn như mục được lấy tiêu điểm, được nhấn, v.v. nhưng bản thân các mục có nền trong suốt khi không có mục nào được chọn (tức là trạng thái xem mặc định). Tôi đã hy vọng rằng quy tắc cuối cùng của Danh sách Nhà nước,

<item android:drawable="@drawable/shape_row" /> 

sẽ nắm bắt trạng thái đó, nhưng vì một lý do nào đó nó không hoạt động. Tôi đã di chuyển mọi thứ xung quanh và cố gắng cài đặt khác nhau, và không có gì. Nếu tôi chỉnh sửa tệp row.xml mà tôi sử dụng để xác định các mục danh sách trong ListView và cố gắng thêm một android cụ thể: nền trỏ đến @ drawable/shape_row, mỗi hàng sẽ có nền chính xác, NHƯNG khi nhấn, trên tiêu điểm, vv tiểu bang không xử lý (hoặc ít nhất, không thể được xem như là nền không bao giờ thay đổi).

Có ai có thể chỉ cho tôi đúng hướng ở đây không? Tôi rất gần với việc đặt cái này lên giường, nhưng sau khi cố gắng gần như mọi thứ, chỉ cần không thể lấy được các mục ListView để lấy một nền mặc định VÀ trả lời Danh sách Trạng thái được triển khai thông qua android: listSelector.

Cảm ơn,

Paul

EDIT:

Cũng chỉ cố gắng thêm android: itemBackground = "@ drawable/shape_row" vào ListView trong main.xml, và không ngạc nhiên không may mắn (các tài liệu nói rằng nó nên được sử dụng để xác định nguồn gốc của các mục menu, nhưng nghĩ rằng nó đáng giá với một mục danh sách).

Một điều khác đã được thử, thêm android: visible = "true" vào mỗi định nghĩa chọn và mục. Các tài liệu StateListDrawable dường như chỉ ra rằng "Provides initial visibility state of the drawable; the default value is false", nhưng việc thêm này không thay đổi gì cả.

EDIT2: Vì vậy, dựa trên nghiên cứu được thực hiện dưới đây bởi Qberticus, có vẻ như chỉ có một bộ công cụ chọn danh sách cho mỗi chế độ xem, xác nhận hành vi chọn danh sách. Tôi cũng có thể xác nhận rằng cài đặt android: drawSelectorOnTop không di chuyển bộ chọn IN FRONT của mục đã chọn, nhưng điều này tất nhiên che khuất mục đó sao cho tôi chỉ thấy chính công cụ chọn (trong trường hợp của tôi là hình dạng màu).

Đây là những gì danh sách có vẻ như với nền thiết lập:

normal, unselected list with background set

Do nền thiết lập, không có sự thay đổi về ngoại hình khi mục được chọn. Nếu tôi thay đổi android: drawSelectorOnTop chỉ là true và chọn một mục, tôi nhận được:

selected, with drawSelectorOnTop set to true

Và cuối cùng, nếu tôi không đặt hình nền cho các mục danh sách, chọn công trình như mong đợi, nhưng tất nhiên , không có hình ảnh nền như các quy tắc cuối cùng của StateSelector không xuất hiện để được theo sau (không nên nó đóng vai trò như một catchall?) cho các hạng mục chưa được chọn có nghĩa là không tùy chỉnh thoải mái tròn hình dạng:

selected, no background

Vì vậy, vấn đề của tôi vẫn còn; nếu tôi không đặt nền cho từng mục danh sách, tôi có thể thấy công cụ chọn làm việc NHƯNG các mục không có nền khi không được chọn. Nếu tôi đặt nền cho mục, chúng trông tuyệt vời khi không được chọn, nhưng nền sẽ che khuất bộ chọn. Chỉ đơn giản là không thể có một mục danh sách có hình dạng duy nhất với các bộ chọn làm việc?

Cám ơn bất cứ ai khác có thể cân nặng trong.

Trả lời

9

đặn này ra, vấn đề là trong khi tôi đang thiết lập các listSelector cho ListView vào Danh sách nhà nước một cách chính xác thông qua android:listSelector="@drawable/list_selector", tôi cũng cần thiết để thiết lập nền tảng cho mục danh sách khác Danh sách nhà nước qua android:background="@drawable/list_background"

Trong list_background.xml danh sách nhà nước, tôi có:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" 
android:visible="true"> 

    <!-- the list items are disabled --> 
<item 
     android:state_window_focused="false" 
     android:drawable="@drawable/shape_row_disabled" /> 

    <!-- the list items are enabled, in focus but not being touched/pressed (idle) --> 
    <item 
     android:state_window_focused="true" 
     android:state_pressed="false" 
     android:state_focused="false" 
     android:state_selected="false" 
     android:drawable="@drawable/shape_row" /> 

    <!-- the catch-all --> 
    <item 
     android:drawable="@android:color/transparent" /> 
</selector> 

Tìm thấy câu trả lời ở đây:

Changing background color of ListView items on Android

Cùng với danh sách chọn của tôi ở trên, nó hoạt động một cách hoàn hảo.

+0

Thật không may, tôi vẫn gặp sự cố khi tùy chỉnh chế độ xem danh sách của mình. Tôi đã đăng các vấn đề cụ thể của mình tại đây: http://stackoverflow.com/questions/5426385/listview-with-nine-patch-item-background-issues; Tôi sẽ đánh giá cao bất kỳ đầu vào bạn có thể có. – LostNomad311

+1

Ngoài ra, hãy đặt thuộc tính danh sách "cacheColorHint" thành màu bg của bạn. Nếu không, việc vuốt nhanh qua danh sách của bạn có thể dẫn đến danh sách các mục màu đen. – larham1

2

Các listSelector chỉ được sử dụng để xác định một View sẽ được rút ra trong cùng một vị trí như chọn mục View. Tức là, chỉ có một phiên bản của listSelector cho mỗi ListView. Bạn có thể chỉ định xem nó có thể vẽ lên trên hay không bằng cách sử dụng drawSelectorOnTop.

Nếu bạn muốn tất cả View s của mình để sử dụng danh sách trạng thái thì bạn nên chỉ định nơi trẻ được định nghĩa là View.

Tôi đang sử dụng nguồn cho AbsListView làm tham chiếu. Cụ thể AbsListView#setSelector(Drawable), AbsListView#positionSelector, AbsListView#drawSelector, và AbsListView#dispatchDraw

AbsListView#drawSelector:

private void drawSelector(Canvas canvas) { 
     if (shouldShowSelector() && mSelectorRect != null && !mSelectorRect.isEmpty()) { 
      final Drawable selector = mSelector; 
      selector.setBounds(mSelectorRect); 
      selector.draw(canvas); 
     } 
} 

AbsListView#positionSelector:

void positionSelector(View sel) { 
    final Rect selectorRect = mSelectorRect; 
    selectorRect.set(sel.getLeft(), sel.getTop(), sel.getRight(), sel.getBottom()); 
    positionSelector(selectorRect.left, selectorRect.top, selectorRect.right, 
      selectorRect.bottom); 

    final boolean isChildViewEnabled = mIsChildViewEnabled; 
    if (sel.isEnabled() != isChildViewEnabled) { 
     mIsChildViewEnabled = !isChildViewEnabled; 
     refreshDrawableState(); 
    } 
} 

Nguồn chỉ ra rằng chỉ có một mSelector tạo/sử dụng và nó được đặt trong cùng giới hạn trực tràng là được chọn mục.

+0

Cảm ơn tất cả công việc khó khăn! Khi bạn đề cập đến listSelector chỉ được sử dụng một lần cho mỗi ListView, đây là những gì tôi đang chỉ định nó trong ListView XML. Thiết lập từng mục List riêng biệt (chúng là TextViews) để có background nghĩa là listSelector bị ẩn đi ... không background nghĩa là nền trong suốt cho mỗi TextView cho đến khi selector khởi động. Tôi đã thử sử dụng lệnh drawSelectorOnTop cho ListView, và nó làm việc trong đó tôi có thể thấy bộ chọn trên nền, nhưng nó cũng là trên nền trước, che khuất nội dung của TextView là tốt. –

+0

Có lẽ nó không thể có một tùy chỉnh (trong trường hợp của tôi, làm tròn) ListView mục VÀ hành vi chọn thích hợp ... có lẽ tôi cần phải xác định một nền cho toàn bộ ListView, nói một màu, và sau đó các bộ chọn sẽ được hiển thị đúng cách . Được hy vọng sẽ làm tròn các mục ListView và tương tác chọn, nhưng có lẽ nó không thể. –

0

Bạn có thể gán nền mặc định cho bố cục gốc và selector_background cho con, trong trường hợp này nếu mục không được chọn thì nền mặc định sẽ không che khuất bộ chọn. Công việc của nó đối với tôi.

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