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


98

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

기본 선택기 @android:color/transparent는 state_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.