android - 在 ExpandableListView 中对父项和子项使用自定义选择器

标签 android android-listview android-drawable android-selector

我有可扩展的列表,如下所示:

enter image description here

橙色项目是子项,当您按特定父项时会显示。蓝色项目是 parent 。我使用这个自定义适配器来创建这个:(我在论坛上的某个地方选择了这个源代码)

public class ExpandableListAdapter extends BaseExpandableListAdapter {

private Context context;
private List<String> listDataHeader;
private HashMap<String, List<String>> listDataChild;

public ExpandableListAdapter(Context context, List<String> listDataHeader,
        HashMap<String, List<String>> listChildData) {
    this.context = context;
    this.listDataHeader = listDataHeader;
    this.listDataChild = listChildData;
}

@Override
public Object getChild(int groupPosition, int childPosititon) {
    return this.listDataChild.get(this.listDataHeader.get(groupPosition))
            .get(childPosititon);
}

@Override
public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

@Override
public View getChildView(int groupPosition, final int childPosition,
        boolean isLastChild, View convertView, ViewGroup parent) {

    final String childText = (String) getChild(groupPosition, childPosition);

    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.list_item, null);
    }

    TextView txtListChild = (TextView) convertView
            .findViewById(R.id.lblListItem);

    txtListChild.setText(childText);
    return convertView;
}

@Override
public int getChildrenCount(int groupPosition) {
    return this.listDataChild.get(this.listDataHeader.get(groupPosition))
            .size();
}

@Override
public Object getGroup(int groupPosition) {
    return this.listDataHeader.get(groupPosition);
}

@Override
public int getGroupCount() {
    return this.listDataHeader.size();
}

@Override
public long getGroupId(int groupPosition) {
    return groupPosition;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
        View convertView, ViewGroup parent) {
    String headerTitle = (String) getGroup(groupPosition);
    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.list_group, null);
    }

    TextView lblListHeader = (TextView) convertView
            .findViewById(R.id.lblListHeader);
    lblListHeader.setTypeface(null, Typeface.BOLD);
    lblListHeader.setText(headerTitle);
    return convertView;
}

@Override
public boolean hasStableIds() {
    return false;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}

}

这些是 xml 文件:

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="55dip"
android:orientation="vertical" >

<TextView
    android:id="@+id/lblListItem"
    android:layout_width="fill_parent"
    android:layout_height="50dp"
    android:gravity="center_vertical"
    android:maxLines="1"
    android:background="@drawable/border_orange"
    android:paddingBottom="5dp"
    android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
    android:paddingTop="5dp"
    android:textColor="#f95001"
    android:textSize="18sp" />

</LinearLayout>

list_group.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="wrap_content"
android:orientation="vertical" >

<TextView
    android:id="@+id/lblListHeader"
    android:layout_width="fill_parent"
    android:layout_height="50dp"
    android:background="@drawable/border"
    android:gravity="center_vertical"
    android:maxLines="1"
    android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
    android:textColor="#1e90ff"
    android:textSize="16sp" />

 </LinearLayout>

这就是我指定实际列表的方式:

<ExpandableListView
    android:id="@+id/all_songs"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentTop="true"
    android:choiceMode="singleChoice"
    android:listSelector="@layout/selector_list_item" >
</ExpandableListView>

这是按钮按下的选择器:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
   android:exitFadeDuration="@android:integer/config_mediumAnimTime">

   <item android:drawable="@android:color/holo_blue_bright" android:state_pressed="true"/>
   <item android:drawable="@android:color/holo_blue_light" android:state_selected="true"/>
   <item android:drawable="@android:color/holo_blue_dark" android:state_activated="true"/>

</selector>

最近我更改了整个应用程序的外观,在我在列表中的项目上添加这些边框之前,一切都很好。但现在我想更改选择器对组项的行为方式(仍然使用矩形形状),以及对子项的不同行为(使用某种椭圆形来填充这个橙色椭圆形而不是列表项的整个矩形)

我怎样才能实现这个目标? 我想我可以设法制作带有形状的 xml 可绘制对象以放在选择器上,但是如何分离父选择器和子选择器?

编辑:如果您需要任何其他源代码,请发表评论。

进展:

在@Omar的帮助下,我成功创建了适用于组选择器的代码。 (但是使用两个线程来实现选择器消失的效果有点愚蠢,我必须通过 Activity 中的静态引用来访问它)

//inside getGroupView() method

if (MusicPlayerActivity.all_songs != null) {
        if (isExpanded) {
            MusicPlayerActivity.all_songs
                    .setSelector(R.drawable.child_selector);
        } else {
            MusicPlayerActivity.all_songs
                    .setSelector(R.drawable.group_selector);
        }
        if (MusicPlayerActivity.all_songs != null)
            new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {e.printStackTrace();
                    }
                    if (MusicPlayerActivity.all_songs != null)
                        MusicPlayerActivity.act
                                .runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        MusicPlayerActivity.all_songs
                                                .setSelector(R.drawable.transparent);
                                    }
                                });
                }
            }.start();
    }

我还发现可以通过修改选择器 xml 中的第一项(上面)来实现这一进展。那么有什么方法可以在该 xml 中为选择器指定子选择器吗?

最佳答案

尝试执行以下操作,

  • 添加子状态的 HashMap (选定或未选定)

    私有(private) HashMap> listDataChildStates;

  • 在适配器构造函数中,添加以下代码:

    // Initially, set all child items as not selected
    for(int i = 0;i<listDataHeader.size();i++)
    {
        ArrayList<String> childItems = listChildData.get(listDataHeader.get(i));
        ArrayList<Boolean> childStates;
        for(int j = 0;j<childItems.size();j++)
        {
                childStates = listDataChildStates.get(childItems.get(j));
                if(childStates == null)
                    childStates = new ArrayList<Boolean>();
                childStates.add(false);
        }
    }
    
  • 然后,在你的 onChildClickListener() 中

    expListView.setOnChildClickListener(new OnChildClickListener() {

            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                    int groupPosition, int childPosition, long id) {
                    boolean childState = listDataChildStates.get(listDataHeader.get(groupPosition)).get(childPosition);
      listDataChildStates.get(listDataHeader.get(groupPosition)).remove(childPosition);
      listDataChildStates.get(listDataHeader.get(groupPosition)).add(childPosition,new Boolean(!childState));
    
                 notifyDataSetChanged();
                 return false;
            }
        });
    
  • 最后,在 getChildView() 方法中添加以下内容:

     boolean childState = listDataChildStates.get(listDataHeader.get(groupPosition)).get(childPosition);
     if(childState)
     {
             // Set your child item as selected
     }else
     {
            // Set your child item as not selected
     }
    

关于android - 在 ExpandableListView 中对父项和子项使用自定义选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22259778/

相关文章:

android - 如何避免在 onError 之后出现可观察的停止

java - Android Studio - 资源条目已定义

android - StateListDrawable 在 KeyboardView 的 OnDraw() 方法中不起作用

java - RecyclerView 中的选择器问题

android-如何获得这样的边框

android - 缺少可变性标志 : Android 12 pending intents with NavDeepLinkBuilder

android - 怎么去掉通知栏的短信图标

android - 如何让我的按钮在我的自定义对话框中可见

Android 应用小部件 ListView onclick 监听器

android - 如何使 listview 像 android market 一样。即分为两列