사용자 지정 선택기를 통한 ListView 항목 배경


98

목록 선택기를 통해 각 Listview 항목에 사용자 지정 배경을 적용 할 수 있습니까?

기본 선택기 @android:color/transparentstate_focused="false"케이스에 대해 지정 하지만이를 일부 사용자 정의 드로어 블로 변경해도 선택되지 않은 항목에는 영향을주지 않습니다. Romain Guy는 이 답변 에서 이것이 가능하다고 제안하는 것 같습니다 .

저는 현재 각 뷰에서 사용자 정의 배경을 사용하고 항목이 선택 / 초점 / 어떤 것이 든 선택기가 표시 될 때 숨기는 방식으로 동일한 효과를 얻고 있지만,이 모든 것을 한 곳에서 정의하는 것이 더 우아 할 것입니다.

참고로, 이것은 내가이 작업을 시도하고 얻는 데 사용하는 선택기입니다.

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

    <item android:state_focused="false"
        android:drawable="@drawable/list_item_gradient" />

    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
    <item android:state_focused="true" android:state_enabled="false"
        android:state_pressed="true"
        android:drawable="@drawable/list_selector_background_disabled" />
    <item android:state_focused="true" android:state_enabled="false"
        android:drawable="@drawable/list_selector_background_disabled" />

    <item android:state_focused="true" android:state_pressed="true"
        android:drawable="@drawable/list_selector_background_transition" />
    <item android:state_focused="false" android:state_pressed="true"
        android:drawable="@drawable/list_selector_background_transition" />

    <item android:state_focused="true"
        android:drawable="@drawable/list_selector_background_focus" />

</selector>

그리고 이것이 내가 선택기를 설정하는 방법입니다.

<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:listSelector="@drawable/list_selector_background" />    

도움을 주셔서 미리 감사드립니다!

답변:


128

나는 이것 때문에 좌절했고 마침내 그것을 해결했습니다. Romain Guy가 암시했듯이 "android:state_selected"사용해야하는 다른 상태 가 있습니다. 목록 항목의 배경에 상태 드로어 블을 사용하고 목록에 대해 다른 상태 드로어 블을 사용 listSelector합니다.

list_row_layout.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:background="@drawable/listitem_background"
    >
...
</LinearLayout>

listitem_background.xml :

<?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/android:transparent" />
    <item android:drawable="@drawable/listitem_normal" />
</selector>

ListView를 포함하는 layout.xml :

...
<ListView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:listSelector="@drawable/listitem_selector"
   />
...

listitem_selector.xml :

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/listitem_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/listitem_selected" />
</selector>

1
깊이있는 답변에 감사드립니다. 내 질문에서 언급했듯이 이것은 내가 지금하고있는 것과 정확히 일치하며 꽤 잘 작동합니다.
shilgapira

안타깝게도 목록보기를 사용자 지정하는 데 여전히 문제가 있습니다. 내 특정 문제를 여기에 게시했습니다. stackoverflow.com/questions/5426385/… ; 나는 당신이 가질 수있는 모든 의견에 감사드립니다.
LostNomad311 2011 년

패딩이있는 9 패치 드로어 블을 배경으로 사용할 때는 작동하지 않습니다. 나는 궁극적 인 해결책을 찾았다 고 생각한다. 내 대답을 보라
Michał K

이것은 post-ICS에서 작동하지만 Gingerbread의 경우 전체 목록이 눌려 지거나 선택된 드로어 블로 색상이 지정됩니다.
gunar 2013-08-09

pre-ICS에 대한 해결책이 있습니까?
Lonli-Lokli

78

패딩을 배경으로 사용하는 9 패치 드로어 블이있는 경우 dglmtn의 솔루션이 작동하지 않습니다. 이상한 일이 일어나고, 나는 그것에 대해 이야기하고 싶지도 않습니다. 그런 문제가 있으면 알고 있습니다.

이제 다른 상태와 9- 패치 드로어 블 (모든 드로어 블 및 색상과 함께 작동 할 것임)이있는 목록보기를 원한다면 두 가지 작업을 수행해야합니다.

  1. 목록의 항목에 대한 선택기를 설정합니다.
  2. 목록의 기본 선택기를 제거하십시오.

해야 할 일은 먼저 row_selector.xml을 설정하는 것입니다.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_enabled="true" 
     android:state_pressed="true" android:drawable="@drawable/list_item_bg_pressed" />
    <item android:state_enabled="true"
     android:state_focused="true" android:drawable="@drawable/list_item_bg_focused" />
    <item android:state_enabled="true"
     android:state_selected="true" android:drawable="@drawable/list_item_bg_focused" />
    <item
     android:drawable="@drawable/list_item_bg_normal" />
</selector>

잊지 마세요 android:state_selected. android:state_focused목록에서 와 같이 작동 하지만 목록 항목에 적용됩니다.

이제 항목 (row.xml)에 선택기를 적용합니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/row_selector"
>
...
</RelativeLayout>

목록에 대한 투명한 선택기를 만듭니다.

<ListView
    android:id="@+id/android:list"
    ...
    android:listSelector="@android:color/transparent"
    />

이것은 일을해야합니다.


1
+1, 나는 전에 당신의 대답을 보지 못했으며, 나 혼자서 같은 결과를 보았습니다. 하지만 9 패치 드로어 블에 대해 언급 해주셔서 감사합니다. 향후 구현에 유용 할 것이라고 확신합니다. 이 방법은 더 깨끗하고 유지 관리가 가능하기 때문에 이것이 최선의 답이되어야합니다.
IsaacCisneros

28
미안하지만이게 왜 이런 망할 UI API가 왜 그렇게 엉망이되어야 하는지를 생각하게 만드는 일입니다. 안드로이드는 여전히해야 할 일이 많습니다. 그런 기본적인 것들이 그렇게 PITA가되어서는 안됩니다.
Gubatron 2012 년

2
+1 감사합니다, 감사합니다, 감사합니다. 이 모든 농구를 뛰어 넘어 매우 기본적인 것을 달성하십시오. 이 모든 상태는 매우 혼란 스럽습니다.
Moritz 2013 년

3
android : listSelector = "@ drawable / list_selector"대신 android : listSelector = "@ android : color / transparent"를 작성하십시오. 추가 list_selector.xml이 필요하지 않습니다.
Sofi Software LLC

1
맞습니다. 비파괴 목록 선택기는 자체 xml 선택기 대신 @android : color / transparent 일 수 있습니다. 방금 시도했습니다. 작동하지 않는 것은 @ null입니다. "no list selector"라고 말해야하고 목록 선택기가 항목 뒤에 그려 지므로 아무것도 그려서는 안됩니다. 하지만 작동하지 않습니다. 기본 선택기는 당시입니다 ...
Zordid

17

목록보기 행에 "배경색"을 사용하지 마십시오.

이것은 모든 선택기 작업을 차단합니다 (내 문제였습니다!)

행운을 빕니다!


3
이것은 사실이 아닙니다. 그냥 배경이 아닌 정적 색상이나 당김 등의 선택기를 사용
마이클 K

이것은 "배경색"을 의미합니다. 당신의 말을 완전히 받아들이십시오.
cV2

이제 setBackgroundColor"색상"과 함께 사용한 선택기가 필요하기 때문에 여기에 왔습니다 . 한숨 ... 사용 setBackground또는 setBackgroundDrawable선택기와 API 버전에 따라.
EpicPandaForce 2015 년

5

Android 개발자 블로그의 "내 목록이 검은 색인 이유는 무엇입니까? Android 최적화" 기사 에는 스크롤 할 때 목록 배경이 검은 색으로 변하는 이유에 대한 자세한 설명이 있습니다. 간단한 대답 : 목록의 cacheColorHint를 투명 (# 00000000)으로 설정합니다.


1
예시적인 단순성이지만 매우 잘 작동합니다. Romain Guy에게 감사드립니다 ... <ListView ... android : cacheColorHint = "# 00000000"> </ ListView> 전부입니다!
Eric JOYÉ 2014

Romain Guy에게 감사하지 마십시오. 그는 문제의 일부입니다. 이와 같은 OS에는 "숨겨진 트릭"이나 기타 해킹이 너무 많으면 안됩니다. 내가 Android를 좋아하지만 다른 SDK와 비교할 때 (더 새롭거나 덜 성숙한 SDK!)
StackOverflowed

5

다음을 넣으면 충분합니다 list_row_layout.xml.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="@drawable/listitem_background">... </LinearLayout>

listitem_selector.xml :

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

2
굉장한 ... 간단한 예
Shihab Uddin 2015

1
또한 목록보기 선택을 투명하게
Sayka

4

대신에:

android:drawable="@color/transparent" 

쓰다

android:drawable="@android:color/transparent"

4

테마를 작성할 수 있습니다.

<pre>

    android:name=".List10" android:theme="@style/Theme"

theme.xml

<style name="Theme" parent="android:Theme">
        <item name="android:listViewStyle">@style/MyListView</item>
</style>

styles.xml

 <style name="MyListView" parent="@android:style/Widget.ListView">
<item name="android:listSelector">@drawable/my_selector</item>

my_selector는 사용자 지정 선택기를 원합니다. 죄송합니다. 코드 작성 방법을 모르겠습니다.


도움을 주셔서 감사합니다. 그러나 이것은 선택기를 통해 기본 목록 항목 배경을 설정하는 데 직접적인 도움이되지 않습니다.
shilgapira 2010

2

선택기 자체를 통해 원하는 효과를 얻는 방법을 잘 모르겠습니다. 결국 전체 목록에 대해 하나의 선택기가 있습니다.

그러나 선택 변경을 제어하고 원하는 것을 그릴 수 있습니다. 에서 이 샘플 프로젝트 , 내가 선택을 투명하게하고 선택한 항목에 줄을 그립니다.


실제로 최대 하나의 선택 자만있는 것이 합리적입니다. 나는 <item android:state_focused="false" android:drawable="@android:color/transparent" />기본 선택기에 절이 있다는 사실로 인해 약간 혼란스러워하거나 혼란스러워 했다고 생각합니다.
shilgapira 2010

Mark, 놀아 (Gil과 같은 문제가 있음) 솔루션을 시도했지만 트랙 볼에만 부분적이며 터치 만 사용하여 항목을 터치하면 nothingSeelected가 호출되고 그런 종류의 것을 원한다면 onItemClicked가 실행됩니다. ListView 내에서 선택 및 눌린 위치를 추적하고 항목 자체 (사용자 정의보기로 설정) 및 ListView의 dispatchDraw에서 필요한 것을 그려야합니다.
codeScriber 2011 년

@codeScriber : "터치 만 사용하여 항목을 터치하고 onItemClicked가 실행되면 nothingSeelected가 호출됩니다."터치가 선택과 관련이 없기 때문에 이것은 완벽하게 정상적인 동작입니다.
CommonsWare

2

저는 항상 동일한 방법을 사용하며 매번, 어디서나 작동합니다. 간단히 이와 같은 선택기를 사용합니다.

<item android:state_activated="true"  android:color="@color/your_selected_color" />
<item android:state_pressed="true" android:color="@color/your_pressed_color" />
<item android:color="@color/your_normal_color"></item>

ListView에 속성을 설정하십시오 (이것은 작동하는 데 매우 중요합니다).

android:choiceMode="singleChoice"

textColor의 경우 색상 폴더 (중요, 드로어 블 폴더가 아닙니다!)에 다음과 같은 선택기를 넣으십시오.

<item android:state_activated="true"  android:color="@color/your_selected_textColor" />
<item android:state_pressed="true" android:color="@color/your_pressed_textColor" />
<item android:color="@color/your_normal_textColor"></item>

이것은 샘플 행 템플릿

<ImageView
    android:id="@+skinMenu/lblIcon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:src="@drawable/menu_catalog" />

<TextView
    android:id="@+skinMenu/lblTitle"
    style="@style/superlabelStyle"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_marginLeft="20dp"
    android:gravity="center_vertical"
    android:text="test menu testo"
    android:textColor="@color/menu_textcolor_selector"
    android:textSize="20dp"
    android:textStyle="bold" />

모든 것이 지루한 해결 방법없이 작동합니다. 이 도움을 바랍니다


-3

여기 FrostWire 팀입니다.

모든 선택기 쓰레기 API가 예상대로 작동하지 않습니다. 이 스레드에 제시된 모든 솔루션을 시도한 후 ListView 항목을 확장하는 순간 문제를 해결했습니다.

  1. 항목이 상태를 유지하는지 확인하십시오. MenuItem의 멤버 변수로 수행했습니다 (부울 선택됨).

  2. 부 풀릴 때 기본 항목이 선택되어 있는지 물어보고, 그렇다면 원하는 드로어 블 리소스를 배경으로 설정하십시오 (9 패치 등). 어댑터가이를 인식하고 무언가가 선택되었을 때 notifyDataChanged ()를 호출하는지 확인하십시오.

        @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView = convertView;
        if (rowView == null) {
            LayoutInflater inflater = act.getLayoutInflater();
            rowView = inflater.inflate(R.layout.slidemenu_listitem, null);
            MenuItemHolder viewHolder = new MenuItemHolder();
            viewHolder.label = (TextView) rowView.findViewById(R.id.slidemenu_item_label);
            viewHolder.icon = (ImageView) rowView.findViewById(R.id.slidemenu_item_icon);
            rowView.setTag(viewHolder);
        }
    
        MenuItemHolder holder = (MenuItemHolder) rowView.getTag();
        String s = items[position].label;
        holder.label.setText(s);
        holder.icon.setImageDrawable(items[position].icon);
    
        //Here comes the magic
        rowView.setSelected(items[position].selected);
    
        rowView.setBackgroundResource((rowView.isSelected()) ? R.drawable.slidemenu_item_background_selected : R.drawable.slidemenu_item_background);
    
        return rowView;
    }

선택기가 실제로 작동한다면 정말 좋을 것입니다. 이론적으로는 훌륭하고 우아한 솔루션이지만 깨진 것처럼 보입니다. 키스.


이 솔루션을 시도하고 싶습니다. 자세한 설명이나 완전한 솔루션을 제공해 주시겠습니까? 감사합니다
Andrew Lam
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.