Sự khác biệt giữa các trạng thái được chọn, kiểm tra và kích hoạt trong Android là gì?


114

Tôi muốn biết điều gì khác biệt với những trạng thái đó. Tôi không tìm thấy bất kỳ trang web nào làm rõ điều này.


4
Các trạng thái của một chế độ xem (ví dụ: một mục ListView) developer.android.com/guide/topics/resources/…
Louis,

stackoverflow.com/questions/13634259/… là một câu hỏi tương tự đã giúp tôi hiểu rõ hơn về điều này. Kiểm tra nó nếu bạn muốn tìm hiểu thêm.
Acsor

Câu trả lời:


182

Sự khác biệt giữa Đã kiểm tra và Đã kích hoạt thực sự khá thú vị. Ngay cả tài liệu của Google cũng xin lỗi (nhấn mạnh bên dưới được thêm vào):

... Ví dụ, trong chế độ xem danh sách với một hoặc nhiều lựa chọn được bật, các chế độ xem trong nhóm lựa chọn hiện tại sẽ được kích hoạt. (Ừm, vâng, chúng tôi rất lấy làm tiếc về thuật ngữ ở đây.) Trạng thái đã kích hoạt được truyền cho trẻ em của chế độ xem mà nó được thiết lập.

Vì vậy, đây là sự khác biệt:

  1. Kích hoạt đã được giới thiệu trong Honeycomb nên bạn không thể sử dụng nó trước đó
  2. Đã kích hoạt bây giờ là một thuộc tính của mọi Chế độ xem. Nó có các phương thức setActiised () và isActiised ()
  3. Đã kích hoạt truyền bá cho trẻ em của Chế độ xem mà nó được thiết lập
  4. Đã kiểm tra xoay quanh Chế độ xem triển khai giao diện Có thể kiểm tra. Các phương thức setChecked (), isChecked (), toggle ()
  5. ListView (sau Honeycomb) gọi setChecked () HOẶC setActiised () tùy thuộc vào phiên bản Android như bên dưới (lấy từ mã nguồn Android):

    if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
        if (child instanceof Checkable) {
            ((Checkable) child).setChecked(mCheckStates.get(position));
        } else if (getContext().getApplicationInfo().targetSdkVersion
                >= android.os.Build.VERSION_CODES.HONEYCOMB) {
            child.setActivated(mCheckStates.get(position));
        }
    }

    Lưu ý biến mCheckStates. Nó theo dõi những vị trí nào trong danh sách của bạn được kiểm tra / kích hoạt. Chúng có thể truy cập được qua ví dụ: getCheckedItemPositions (). Cũng lưu ý rằng một lệnh gọi đến ListView.setItemChecked () sẽ gọi như trên. Nói cách khác, nó có thể được gọi là setItemActiised ().

  6. Trước Honeycomb, chúng tôi phải thực hiện các giải pháp thay thế để phản ánh state_checked trong các mục danh sách của chúng tôi. Điều này là do ListView chỉ gọi setChecked () ở Chế độ xem trên cùng trong bố cục (và bố cục không triển khai có thể kiểm tra) ... và nó KHÔNG phổ biến nếu không có trợ giúp. Các cách giải quyết này có dạng sau: Mở rộng bố cục gốc để triển khai Checkable. Trong phương thức khởi tạo của nó, hãy tìm một cách đệ quy tất cả các phần tử con triển khai Checkable. Khi setChecked () vv ... được gọi, hãy chuyển lệnh gọi đến các Chế độ xem đó. Nếu các dạng xem đó triển khai các khả năng có thể kéo của danh sách trạng thái (ví dụ: CheckBox) với một tệp có thể vẽ khác cho state_checked thì trạng thái đã kiểm tra được phản ánh trong giao diện người dùng.

  7. Để tạo nền đẹp cho một mục danh sách sau Honeycomb, tất cả những gì bạn cần làm là có một danh sách trạng thái có thể vẽ được với một tệp có thể vẽ cho trạng thái state_actiised như thế này (và tất nhiên là sử dụng setItemChecked ()):

    <item android:state_pressed="true"
        android:drawable="@drawable/list_item_bg_pressed"/>
    <item android:state_activated="true"
        android:drawable="@drawable/list_item_bg_activated"/>
    <item android:drawable="@drawable/list_item_bg_normal"/>

  8. Để tạo nền đẹp cho một mục danh sách trước HoneyComb, bạn sẽ làm điều gì đó giống như trên cho state_checked và bạn CŨNG cần mở rộng chế độ xem trên cùng của mình để triển khai giao diện Checkable. Trong phạm vi đó, bạn cần cho Android biết trạng thái bạn đang triển khai là đúng hay sai bằng cách triển khai onCreateDrawableState () và gọi refreshDrawableState () bất cứ khi nào trạng thái thay đổi.

    <item android:state_pressed="true"
        android:drawable="@drawable/list_item_bg_pressed"/>
    <item android:state_checked="true"
        android:drawable="@drawable/list_item_bg_checked"/>
    <item android:drawable="@drawable/list_item_bg_normal"/>

... và mã để triển khai Checkable được kết hợp với state_checked trong RelativeLayout có thể là:

public class RelativeLayoutCheckable extends RelativeLayout implements Checkable {

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

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

    private boolean mChecked = false;

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }
    @Override
    public boolean isChecked() {
        return mChecked;
    }

    @Override
    public void setChecked(boolean checked) {
        mChecked = checked;
        refreshDrawableState();
    }

    private static final int[] mCheckedStateSet = {
        android.R.attr.state_checked,
    };

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked()) {
            mergeDrawableStates(drawableState, mCheckedStateSet);
        }
        return drawableState;
    }    

    @Override
    public void toggle() {
        setChecked(!mChecked);
    }
}

Nhờ những điều sau:

http://sriramramani.wordpress.com/2012/11/17/custom-states/

Stackoverflow: Cách thêm trạng thái nút tùy chỉnh

Stackoverflow: Chế độ xem có thể kiểm tra tùy chỉnh phản hồi với Bộ chọn

http://www.charlesharley.com/2012/programming/custom-drawable-states-in-android/

http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList

http://blog.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/


4
câu trả lời này là vô giá. Tôi ước mình đã đọc nó trước khi cố gắng tìm ra cách triển khai bố cục Có thể kiểm tra, v.v. Cảm ơn bạn rất nhiều.
Blake Mumford

12
câu trả lời tuyệt vời, nhưng không giải quyết các mục "đã chọn". Tôi tìm thấy câu trả lời trong câu ngay trước khi một trong những bạn trích dẫn: Selection is a transient property, representing the view (hierarchy) the user is currently interacting with. Activation is a longer-term state that the user can move views in and out of. For example, in a list view with single or multiple selection enabled, the views in the current selection set are activated. (Um, yeah, we are deeply sorry about the terminology here.) nguồn
woojoo666

màu nền tùy chỉnh của tôi chỉ xuất hiện chọn đằng sau / tập trung các mặt hàng, không kiểm tra các mặt hàng, khi sử dụng phương pháp sau Honeycomb bạn được đăng trên: gọi setItemChecked()và sau đó sử dụng một bộ chọn với bất động sảnandroid:state_activated="true"
woojoo666

1
Cảm ơn bạn rất nhiều, tôi đã lãng phí 3 ngày để cố gắng tìm ra điều này cho đến khi cuối cùng tôi quyết định tự hỏi bản thân "sự khác biệt giữa đã chọn, đã chọn và kích hoạt là gì", thật tệ khi đối phó với một thứ quá đơn giản như một menu lại phức tạp và đòi hỏi quá nhiều bởi các thiên tài của Google, gần như giống như một chướng ngại vật được công ty này cố ý đặt ra để làm chậm các công ty khác.
Gubatron

20

Theo doc gia :

  • android: state_selected Boolean . " true" nếu mục này nên được sử dụng khi đối tượng là lựa chọn của người dùng hiện tại khi điều hướng bằng điều khiển hướng (chẳng hạn như khi điều hướng qua danh sách bằng phím d-pad); " false" nếu mục này nên được sử dụng khi đối tượng không được chọn. Trạng thái đã chọn được sử dụng khi tiêu điểm (android: state_focused) không đủ (chẳng hạn như khi chế độ xem danh sách có tiêu điểm và một mục trong đó được chọn bằng một phím d-pad).

  • android: state_checked Boolean . " true" nếu mục này nên được sử dụng khi đối tượng được kiểm tra; " false" nếu nó nên được sử dụng khi đối tượng được bỏ chọn.

  • android: state_actiised Boolean . " true" nếu mục này nên được sử dụng khi đối tượng được kích hoạt dưới dạng lựa chọn liên tục (chẳng hạn như để "đánh dấu" mục danh sách đã chọn trước đó trong chế độ xem điều hướng liên tục); " false" nếu nó nên được sử dụng khi đối tượng không được kích hoạt. Được giới thiệu trong API cấp 11 .

Tôi nghĩ rằng tài liệu là khá rõ ràng, vì vậy vấn đề là gì?


5
Bạn có thể nói rõ hơn về android: state_selected. Những trường hợp nào khi nó được đặt thành true?
Anderson

@Anderson nó sẽ phụ thuộc vào ViewGroup mà bạn đang sử dụng - ListView, RecyclerView (có thể là LayoutManagers của nó), GridView có thể có các cách triển khai khác nhau: ListView gọi setFocused trong đó GridView gọi setSelected chẳng hạn. Nó có thể chỉ là một trường hợp kiểm tra ứng dụng của bạn trên các phiên bản nền tảng khác nhau.
ataulm

1
@Anderson: Nếu bạn có một danh sách và người dùng có các phím mũi tên, một phím được "chọn" và khi họ mũi tên lên / xuống, lựa chọn sẽ di chuyển lên / xuống. Khi họ nhấn phím "kích hoạt", nó sẽ "kích hoạt" điều khiển, nghĩ rằng việc lựa chọn nó mơ hồ giống như di chuột qua và kiểm tra / kích hoạt mơ hồ giống như nhấp chuột.
Con vịt đang kêu gào,

Tôi đã tự hỏi, tôi sẽ sử dụng kích hoạt để đánh dấu một mục trong chế độ xem danh sách, nhưng nó có đặt kích hoạt cho các mục danh sách khác thành false không ... nếu không, một trong hai điều này sẽ làm điều đó nên tôi không phải tìm mục con được kích hoạt khác và đặt kích hoạt thành false?
Lion789

0

Đây là giải pháp khác cho vấn đề này: https://github.com/jiahaoliuliu/CustomizedListRow/blob/master/src/com/jiahaoliuliu/android/customizedlistview/MainActivity.java

Tôi đã ghi đè phương thức setOnItemClickListener và kiểm tra các trường hợp khác nhau trong mã. Nhưng chắc chắn giải pháp của Marvin tốt hơn nhiều.

listView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position,
        long id) {
    CheckedTextView checkedTextView =
            (CheckedTextView)view.findViewById(R.id.checkedTextView);
    // Save the actual selected row data
    boolean checked = checkedTextView.isChecked();
    int choiceMode = listView.getChoiceMode();
    switch (choiceMode) {
    // Not choosing anything
    case (ListView.CHOICE_MODE_NONE):
        // Clear all selected data
        clearSelection();
        //printCheckedElements();
        break;
    // Single choice
    case (ListView.CHOICE_MODE_SINGLE):
        // Clear all the selected data
        // Revert the actual row data
        clearSelection();
        toggle(checked, checkedTextView, position);
        //printCheckedElements();
        break;
    // Multiple choice
    case (ListView.CHOICE_MODE_MULTIPLE):
    case (ListView.CHOICE_MODE_MULTIPLE_MODAL):
        // Revert the actual selected row data
        toggle(checked, checkedTextView, position);
        //printCheckedElements();
        break;
    }
    }
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.