Android 单击ExpandableListView中的视图时禁用视图中的状态更改 出身背景

Android 单击ExpandableListView中的视图时禁用视图中的状态更改 出身背景,android,checkbox,expandablelistview,android-adapter,Android,Checkbox,Expandablelistview,Android Adapter,当您为listView创建自己的自定义视图时,您可以在其内部设置一个复选框(或任何其他视图的可绘制状态为“state_pressed”的视图),该复选框只有在实际被单击时才会显示为已触按,而不是单击listView行上的任何位置 为listView执行此操作的方法是在其适配器上使用下一个代码(如图所示): 问题 此解决方案不适用于ExpandableListView,因为它没有此功能 不仅如此,我认为任何点击ExpandableListView上的项目(即使是那些没有展开的项目)都会触发noti

当您为listView创建自己的自定义视图时,您可以在其内部设置一个复选框(或任何其他视图的可绘制状态为“state_pressed”的视图),该复选框只有在实际被单击时才会显示为已触按,而不是单击listView行上的任何位置

为listView执行此操作的方法是在其适配器上使用下一个代码(如图所示):

问题 此解决方案不适用于ExpandableListView,因为它没有此功能

不仅如此,我认为任何点击ExpandableListView上的项目(即使是那些没有展开的项目)都会触发notifyDataSetChanged(或触发它的布局)

为什么会发生这种情况

我试过的 我试过使用“”、“”甚至“”。这些解决方案都没有起到任何作用

问题 在行中设置复选框并只允许它们自己处理触摸效果的最佳方式是什么


另外,为什么单击项目(即使没有子项)会触发整个ExpandableListView的刷新?

如果我理解正确,您希望在ExpandableListView的每个父行中都有一个复选框。我以前也做过类似的事情(不是使用复选框,而是按钮),我必须实现一个自定义适配器。应该是这样的:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class ExpandableListTest extends BaseExpandableListAdapter {
private Context context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;

public ExpandableListTest(Context context) {
    this.context = context;
}

@Override
public Object getChild(int groupPosition, int childPosititon) {
    if (_listDataChild != null) {
        return this._listDataChild.get(
                this._listDataHeader.get(groupPosition))
                .get(childPosititon);
    } else {
        return null;
    }
}

@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 int position = groupPosition;
    final String childText = (String) getChild(groupPosition, childPosition);

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

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

    txtListChild.setText(childText);

    convertView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View arg0) {
            // do something
        }
    });

    return convertView;
}

@Override
public int getChildrenCount(int groupPosition) {
    if (_listDataChild == null) {
        return 0;
    } else {
        return this._listDataChild.get(
                this._listDataHeader.get(groupPosition)).size();
    }
}

@Override
public Object getGroup(int groupPosition) {
    if (_listDataHeader == null) {
        return null;
    } else {
        return this._listDataHeader.get(groupPosition);
    }

}

@Override
public int getGroupCount() {
    if (_listDataHeader == null) {
        return 1;
    } else {
        return this._listDataHeader.size();
    }

}

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

@Override
public View getGroupView(int pos, boolean isExpanded, View view,
        ViewGroup parent) {

    if (view == null) {
        LayoutInflater infalInflater = (LayoutInflater) this.context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = infalInflater.inflate(R.layout.layout_with_checkbox, null);
    }
    getGroup(pos);

    CheckBox checkBox=(CheckBox)view.findViewById(R.id.checkBox);
    checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
            if(arg1){
                //the checkBox is checked
            }
        }
    });

    return view;
}

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

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return false;
}
import java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入android.content.Context;
导入android.content.Intent;
导入android.graphics.Typeface;
导入android.net.Uri;
导入android.os.Bundle;
导入android.util.Log;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.view.OnClickListener;
导入android.view.ViewGroup;
导入android.widget.BaseExpandableListAdapter;
导入android.widget.CheckBox;
导入android.widget.CompoundButton;
导入android.widget.CompoundButton.OnCheckedChangeListener;
导入android.widget.ImageView;
导入android.widget.TextView;
导入android.widget.Toast;
公共类ExpandableListTest扩展了BaseExpandableListAdapter{
私人语境;
私有列表_listDataHeader;//头标题
//标题标题、子标题格式的子数据
私有HashMap_listDataChild;
公共可扩展列表测试(上下文){
this.context=上下文;
}
@凌驾
公共对象getChild(int-groupPosition、int-ChildPosition){
如果(_listDataChild!=null){
返回此。\u listDataChild.get(
此._listDataHeader.get(groupPosition))
.get(childpositionon);
}否则{
返回null;
}
}
@凌驾
公共长getChildId(int-groupPosition,int-childPosition){
返回子位置;
}
@凌驾
公共视图getChildView(int groupPosition,final int childPosition,
布尔值isLastChild、视图转换视图、视图组父级){
最终int位置=groupPosition;
最终字符串childText=(字符串)getChild(groupPosition,childPosition);
if(convertView==null){
LayoutInflater infalInflater=(LayoutInflater)this.context
.getSystemService(上下文布局\充气机\服务);
convertView=infalInflater.充气(R.layout.child_布局,null);
}
TextView txtListChild=(TextView)convertView.findViewById(R.id.text);
setText(childText);
setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图arg0){
//做点什么
}
});
返回视图;
}
@凌驾
公共整数getChildrenCount(整数组位置){
如果(_listDataChild==null){
返回0;
}否则{
返回此。\u listDataChild.get(
这是.u listDataHeader.get(groupPosition)).size();
}
}
@凌驾
公共对象getGroup(int-groupPosition){
如果(_listDataHeader==null){
返回null;
}否则{
返回此。\u listDataHeader.get(groupPosition);
}
}
@凌驾
public int getGroupCount(){
如果(_listDataHeader==null){
返回1;
}否则{
返回此值。_listDataHeader.size();
}
}
@凌驾
公共长getGroupId(int-groupPosition){
返回组位置;
}
@凌驾
公共视图getGroupView(int-pos、布尔值isExpanded、视图、,
视图组(父级){
如果(视图==null){
LayoutInflater infalInflater=(LayoutInflater)this.context
.getSystemService(上下文布局\充气机\服务);
视图=infalInflater.flate(R.layout.layout_,带_复选框,空);
}
getGroup(pos);
CheckBox=(CheckBox)view.findViewById(R.id.CheckBox);
setOnCheckedChangeListener(新的OnCheckedChangeListener(){
@凌驾
已更改复选框时的公共无效(复合按钮arg0,布尔值arg1){
如果(arg1){
//选中该复选框
}
}
});
返回视图;
}
@凌驾
公共布尔表ID(){
返回false;
}
@凌驾
公共布尔值isChildSelectable(int-groupPosition,int-childPosition){
返回false;
}
}

如果要将复选框放在子行中,只需切换getGroupView()和getChildView()中使用的代码和布局即可

父布局xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="10dp"
        android:paddingRight="10dp" >

        <CheckBox
            android:id="@+id/checkBox"
            android:layout_width="30dp"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="40dp"
            android:layout_toRightOf="@+id/imageView1"
            android:text="Text goes here"
            android:textSize="18sp" />
    </RelativeLayout>

</LinearLayout>


复选框只处理自身的触摸事件?在我的例子中,它们实际上是可检查的图像视图(但对于任何可检查的视图,在按下状态下都会出现这种情况),我在它们上使用setOnClickListener。问题是,当您触摸行本身时,似乎您也触摸了它们,因此它们获得了“state_pressed”的可绘制效果。您尝试过此代码吗?我刚刚又测试了一次,效果很好。我没有使用“Checkable ImageView”,但我使用了一个复选框、一个togglebutton以及两种带有可绘制的样式(用于按下状态)对其进行了测试。他们对行上的触摸事件没有反应。好的,我试过你的样本(和
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="10dp"
        android:paddingRight="10dp" >

        <CheckBox
            android:id="@+id/checkBox"
            android:layout_width="30dp"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="40dp"
            android:layout_toRightOf="@+id/imageView1"
            android:text="Text goes here"
            android:textSize="18sp" />
    </RelativeLayout>

</LinearLayout>