Mục đã chọn của Android ListView luôn được đánh dấu


76

Tôi có một XMLvới hai ListView, một có danh sách các khách hàng được điền bởi một truy vấn chọn ( lv_cli) và một với các chi tiết của khách hàng được chọn ( lv_cli_det). Tôi muốn giữ khách hàng được chọn trong lv_clikhi lv_cli_detchương trình hiển thị chi tiết.

XML:

<ListView
    android:id="@+id/cli_lista"
    android:layout_width="512dp"
    android:layout_height="wrap_content"
    android:fadeScrollbars="false"
    >
</ListView>

<ListView
    android:id="@+id/cli_lista_det"
    android:layout_width="512dp"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@+id/cli_lista"
    android:fadeScrollbars="false" >
</ListView>

Java:

Cursor cursor = db.rawQuery("Select NrCl||';'||Nome From Clientes", null);
final ListView t = (ListView)findViewById(R.id.cli_lista);
ArrayAdapter<String> myarrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems);
t.setAdapter(myarrayAdapter);

final ListView td = (ListView)findViewById(R.id.cli_lista_detalhe);
final ArrayAdapter<String> myarrayAdapter2 = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems2);

t.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        String item = ((TextView)view).getText().toString();
        String[] strArray = item.split("\\;");

        cli.load(strArray[0].toString());
        td.setAdapter(myarrayAdapter2);
        listItems2.clear();
        listItems2.add("Nome: " + cli.getNome());
        listItems2.add("Morada: " + cli.getMorada());
        listItems2.add("Localidade: " + cli.getLoca());
        listItems2.add("Código Postal: " + cli.getCp());
        listItems2.add("Pais: " + cli.getPais());
        listItems2.add("Nif: " + cli.getNif());
        listItems2.add("Tel: " + cli.getTel());
        listItems2.add("Tlm: " + cli.getTlm());
        listItems2.add("Tipo Preço: " + cli.getTipoPvn());
        listItems2.add("Cond. Pagamento: " + cli.getCpg());
        listItems2.add("Obs: " + cli.getObs());
        td.setAdapter(myarrayAdapter2);
        myarrayAdapter2.notifyDataSetChanged(); 
    }
});

hiển thị mã của bạn. bạn đã sử dụng phân mảnh hay gì ??
Avinash Kumar Pankaj

chỉ làm ngược lại. làm thế nào bạn làm mã cho chế độ xem danh sách cao ?? mã đăng ở đây ..
Dhaval Parmar

Câu trả lời:


135

Để giữ màu sắc của mục listview khi bạn nhấn nó, hãy đưa dòng sau vào bố cục mục listview của bạn:

android:background="@drawable/bg_key"

Sau đó xác định bg_key.xmltrong drawablethư mục như sau:

<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item 
        android:state_selected="true"
        android:drawable="@color/pressed_color"/>
    <item
        android:drawable="@color/default_color" />
</selector>

Cuối cùng, bao gồm điều này trong ListView onClickListener:

listView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,long arg3) {
        view.setSelected(true);
        ... // Anything
    }
});

Bằng cách này, chỉ một mục sẽ được chọn màu bất kỳ lúc nào. Bạn có thể xác định các giá trị màu của mình res/values/colors.xmlbằng một cái gì đó như sau:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="pressed_color">#4d90fe</color>
    <color name="default_color">#ffffff</color>
</resources>

error: Lỗi: Không tìm thấy tài nguyên phù hợp với tên đã cho (tại 'drawable' với giá trị '@ drawable / press_color'). error: Lỗi: Không tìm thấy tài nguyên phù hợp với tên đã cho (tại 'drawable' với giá trị '@ color / default_color').
Celta

2
Tên màu chỉ là ví dụ. Nó cho thấy rằng bạn có thể 1) tạo hình ảnh màu 9patch ở định dạng png sau đó đặt nó bên trong thư mục có thể vẽ hoặc 2) bạn có thể xác định màu trong res / values ​​/ Colors.xml, sau đó gọi nó bằng android: drawable = "@ màu sắc / màu của bạn ”. Trước tiên, bạn sẽ cần tạo các color.xml nếu nó không tồn tại.
Neoh

Chế độ xem danh sách đầu tiên có hoạt động bình thường không? Bạn cần phải làm điều tương tự cho xml bố trí listview thứ hai và OnClickListener của nó ()
Neoh

tôi không cần lần xem danh sách thứ hai để hoạt động như lần đầu tiên
Celta

1
Phương pháp này nên viết thành tài liệu chính thức của Android.
Richard

165

Tôi đã tìm thấy cách thích hợp. Nó rất đơn giản. Trong tài nguyên mô tả sau:

android:choiceMode="singleChoice"
android:listSelector="#666666"

(hoặc bạn có thể chỉ định một liên kết tài nguyên thay vì giá trị màu)

Có lập trình:

listView.setSelector(Drawable selector);
listView.setSelector(int resourceId);
listView.setChoiceMode(int mode);

có thể là một trong những chế độ sau: AbsListView.CHOICE_MODE_SINGLE, AbsListView.CHOICE_MODE_MULTIPLE, AbsListView.CHOICE_MODE_NONE (mặc định)

(AbsListView là tổ tiên trừu tượng cho lớp ListView)

Các thao tác PS với onItemClick và nền chế độ xem thay đổi bị phá sản, vì bản thân chế độ xem là một đối tượng tạm thời. Do đó bạn không được theo dõi một lượt xem.

Nếu danh sách của chúng tôi đủ dài, các chế độ xem được liên kết với các mục được cuộn ra sẽ bị xóa khỏi hệ thống phân cấp và sẽ được tạo lại khi các mục đó hiển thị lại (với các tùy chọn hiển thị được lưu trong bộ nhớ cache, chẳng hạn như nền). Vì vậy, chế độ xem chúng tôi đã theo dõi bây giờ không phải là chế độ xem thực tế của mục và việc thay đổi nền của nó không ảnh hưởng gì đến chế độ xem mục thực tế. Kết quả là chúng tôi có nhiều mục được chọn.


15
Điều này nên được chấp nhận câu trả lời. Đơn giản và rất hiệu quả.
Chostakovitch

2
Câu trả lời đơn giản và thanh lịch!
hiệp sĩ bóng đêm

1
Mặc dù các câu trả lời khác là đúng, nhưng câu trả lời này rất rõ ràng và đơn giản.
velval

1
Tôi muốn một trong các mục listView được chọn theo mặc định, làm cách nào để làm điều đó?
Apurva

3
@AJG Nếu tôi thay đổi chế độ thành Đơn thành Nhiều, nó không hoạt động. Nó chỉ hiển thị một mục được chọn cuối cùng có màu. Nhưng tôi muốn rằng Nếu tôi chọn ba mục thì cả ba mục phải được tô màu.
Ajay Sharma

37
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            for (int j = 0; j < adapterView.getChildCount(); j++)
                adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);

            // change the background color of the selected element
            view.setBackgroundColor(Color.LTGRAY);
});

Có lẽ bạn có thể muốn lưu phần tử được chọn hiện tại trong một biến toàn cục bằng cách sử dụng chỉ mục i.


6
Có điều gì đó kỳ lạ xảy ra khi bàn phím được hiển thị. một lựa chọn nhiều xảy ra.
Ricardo

1
Điều này sai vì chế độ xem danh sách, để tiết kiệm bộ nhớ, dường như đang sử dụng các chế độ xem giống nhau cho mỗi 10 mục (hoặc có thể là mỗi n mục trong đó n lớn hơn số mục hiển thị trên màn hình). Đó là lý do tại sao nhiều lựa chọn xảy ra.
marco

13

Cách đơn giản là, nếu bạn đang sử dụng listview trong xml, hãy sử dụng thuộc tính này trên listview của bạn,

android:choiceMode="singleChoice"
android:listSelector="#your color code"

nếu không sử dụng xml, theo chương trình

listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
listview.setSelector(android.R.color.holo_blue_light);

10
Bạn hơi muộn. Câu trả lời của AJG đặt trước câu trả lời của bạn hơn một năm và hoàn thiện hơn.
SMBiggs

5

Bạn cần bộ chọn như thế này:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
<item android:drawable="@color/app_primary_color_light" android:state_pressed="true" />

<!-- Used when the view is "activated". -->
<item android:drawable="@color/app_primary_color" android:state_activated="true" />

<!-- Default, "just hangin' out" state. -->
<item android:drawable="@android:color/transparent" /></selector>

Và sau đó đặt thành android:choiceMode="singleChoice"ListView của bạn.


Đừng quên thêm dòng: android:listselector="@drawable/my_selector"trong ListView của bạn!
SMBiggs

Giải pháp này phù hợp với tôi trong Android Kitkat 19 Cảm ơn rất nhiều
DoctorDoom

2

Từ ví dụ của Avinash Kumar Pankaj

View v;

sau đó tại phương pháp oncreate

v = new View(getActivity());

và sau đó phương pháp onlistitemclick tôi đã viết

public void onListItemClick(ListView listView, View view, int position,
       long id) {
   v.setBackgroundResource(0);
   view.setBackgroundResource(R.color.green);
   v = view;
}

Nó đã làm việc cho tôi. Cảm ơn bạn.

tôi đã thay thế

v = new View(getActivity());

đến

v = new View(this);

và mã hoạt động tốt.

Cũng cần các tệp xml 'color' và 'bg_key' từ các ví dụ trước, cũng như thuộc tính ListView android: background = "@ drawable / bg_key"

Mauro


2

* hãy chắc chắn rằng không có Ripple ở bố cục gốc của vùng chứa chế độ xem danh sách

thêm dòng này vào chế độ xem danh sách của bạn

android:listSelector="@drawable/background_listview"

đây là tệp "background_listview.xml"

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/white_background" android:state_pressed="true" />
<item android:drawable="@color/primary_color" android:state_focused="false" /></selector>

các màu được sử dụng trong tệp background_listview.xml:

<color name="primary_color">#cc7e00</color>
<color name="white_background">#ffffffff</color>

sau những điều này

(mục đã nhấp chứa màu cam cho đến khi bạn nhấp vào mục khác)


1

Một cách bạn có thể làm điều này là Theo dõi vị trí đã chọn hiện tại trong hoạt động của bạn:

@Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position,
            long arg3) {
        currentPosition = position
        lv_cli.notifyDataSetChanged();
    }

Bây giờ, hãy chắc chắn rằng bạn chỉ định một ID cho bố cục mẹ (linearLayout, boxLayout, relativeLayout, .. Bất cứ điều gì bạn muốn) của mục danh sách của bạn.

Sau đó, trong ListView của bạn, bạn có thể làm như thế này:

layoutBackground = (LinearLayout) convertView.findViewById(R.id.layout_background);

if (YourActivity.this.currentPosition == position) {
    layoutBackground.setBackgroundColor(YourActivity.this.getResources().getColor(R.color.hilight_color));
} else{
    layoutBackground.setBackgroundResource(R.drawable.list_item_drawable);
}

Về cơ bản, bạn chỉ cần đặt màu nổi bật cho bố cục làm nền khi nó bằng với vị trí đã chọn hiện tại của bạn. Lưu ý cách tôi đặt tài nguyên nền có thể vẽ khi mục không được chọn. Điều này có thể khác trong trường hợp của bạn (vì bạn không đăng mã). Trong trường hợp của tôi, có thể kéo này là một bộ chọn đảm bảo mục được phát sáng khi nhấn.

LƯU Ý: Mã đơn giản này không sử dụng trình giữ chế độ xem, nhưng tôi thực sự khuyên bạn nên sử dụng.


0

Sử dụng id thay thế:

Đây là phương pháp dễ nhất có thể xử lý ngay cả khi danh sách dài:

public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    Holder holder=new Holder();
    View rowView;
    rowView = inflater.inflate(R.layout.list_item, null);
    //Handle your items.
    //StringHolder.mSelectedItem is a public static variable.
    if(getItemId(position)==StringHolder.mSelectedItem){
        rowView.setBackgroundColor(Color.LTGRAY);

    }else{
        rowView.setBackgroundColor(Color.TRANSPARENT);
    }
    return rowView;
}

Và sau đó trong onclicklistener của bạn:

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            StringHolder.mSelectedItem = catagoryAdapter.getItemId(i-1);
            catagoryAdapter.notifyDataSetChanged();
.....
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.