android - ExpandableListAdapter onClickListener,调用notifyDataSetChanged()

标签 android expandablelistview onclicklistener expandablelistadapter

我有一个自定义适配器,它使用 onclickListener 来更改父文本,我不知道如何让 notifyDataSetChanged 方法在适配器中工作。

应该发生的是我有一个可扩展的 View ,当您单击子项中的按钮时,它会用子项的文本更新父项...

这是应该发生的事情的图片示例。 在点击按钮之前使用这个: enter image description here

点击按钮后使用这个: enter image description here

“选择成分”更改为“米饭、杯子”或点击的任何内容

所以在我显示的代码中,单击按钮后它应该更新父级,然后刷新 View ,但出于某种原因我不能这样做?

这是我的代码,提前致谢!

    package com.example.andrew.mypantry;

import android.content.Context; 
import android.graphics.Typeface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.util.HashMap;
import java.util.List;

/**
 * Created by andrew on 7/1/2015.
 */
public class IngExpandableListAdapter 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 IngExpandableListAdapter(Context context, List<String> listDataHeader,
                                HashMap<String, List<String>> listDataChild) {
    this.context = context;
    this.listDataHeader = listDataHeader;
    this.listDataChild = listDataChild;
}

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

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

private void test() {


    //notifyDataSetChanged();
    //super.notifyDataSetChanged();
    //this.notifyDataSetChanged();
}
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild,
                         View convertView, ViewGroup parent) {
    final String childText = (String) getChild(groupPosition,childPosition);

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

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

    txtListChild.setText(childText);

    //handle button
    Button ingredientButton = (Button)convertView.findViewById(R.id.useIngredient_button);
    ingredientButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //change header to ingredient selected
            listDataHeader.set(groupPosition, childText);
            //test();
        }
    });

    return convertView;
}

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

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

@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 layoutInflater = (LayoutInflater) this.context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
        convertView = layoutInflater.inflate(R.layout.ingredient_list_group, null);
    }

    //handle textView
    final TextView listHeader = (TextView) convertView.findViewById(R.id.ingredientGroupTextView);
    listHeader.setTypeface(null, Typeface.BOLD);
    listHeader.setText(headerTitle);

    //handle button
    Button deleteButton = (Button)convertView.findViewById(R.id.deleteButton);
    deleteButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //remove item from list
            Log.d("TESTING", "item should be removed");

        }
    });


    return convertView;
}

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

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

最佳答案

正如 beworker 提到的,您的问题来自使用错误的数据结构,这就是您的应用程序崩溃的原因。您正在使用 header 标题作为 HashMap 的键,当您修改 listDataHeader 中的标题时,修改会正确应用于它,但不适用于 HashMap 内的键对象。这意味着您的 child 仍然存在于 HashMap 中的旧标题键下,新标题键的值为 null。因此,当您调用

时,您将得到一个 NullPointerException
this.listDataChild.get(this.listDataHeader.get(groupPosition)).get(childPosition);

自从

this.listDataChild.get(this.listDataHeader.get(groupPosition))

返回 Null

解决方案是将 ArrayList 用于标题标题,将 ArrayList> 用于子标题。这两个 arrayList 中的键是您的组索引。

关于android - ExpandableListAdapter onClickListener,调用notifyDataSetChanged(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31212466/

相关文章:

Android ExpandableListView 变量范围

java - Android:如何使 ExpandableListView 中的子行不可点击?

java - 通过单击 ListView 内的按钮从自定义 ListView 获取/存储特定数据

Android 按钮监听器生命周期

android - 数据绑定(bind)错误 : databinding does not exist

java - 在 Java 和 Android 中通过套接字获取服务器响应

android - 如何调用(invoke)可扩展 ListView 的onChildClick方法?

android - 从 Kotlin RecyclerView(cardview) onclick 加载详细信息 View

java - 将整数颜色值转换为 RGB

android - 在android中删除 ListView 中的选定行