ExpandableListView 中重复的 RatingBar 值

RatingBar values duplicated in ExpandableListView

当我在 First ExpandableListView 中评分时:

然后,当我打开 Second ExpandableListView 或任何其他视图时,值会重复:

我得到了 https://www.youtube.com/watch?v=jZxZIFnJ9jE&ab_channel=EDMTDev 的帮助 并通过添加评级栏对其进行了修改。 评分未保存在视图中。

代码:

Java

expListview = (ExpandableListView)findViewById(R.id.expSkills);
    initData();
    expListadapter = new ExpandablelistAdapter(getApplicationContext(),listDataheader,listHash);
    expListview.setAdapter(expListadapter);

  private void initData()
  {
    listDataheader = new ArrayList<>();
    listHash = new HashMap<>();

    listDataheader.add("Communication Skills");
    listDataheader.add("Social Skills");
    listDataheader.add("Music and Movement");
    listDataheader.add("Gross Motor Skills");
    listDataheader.add("Fine Motor Skills");
    listDataheader.add("Healthy Habits");

    List<String> a = new ArrayList<>();
    a.add("Follows Instructions :");
    a.add("Expresses in Words :");
    a.add("Asks Questions :");
    a.add("Answers Questions :");
    a.add("Uses Facial Expressions :");
    a.add("Listens and Enjoys :");

    List<String> b = new ArrayList<>();
    b.add("Shows Feelings and Emotions :");
    b.add("Participates in Group Activities :");
    b.add("Shares with Others :");
    b.add("Plays with Teacher :");
    b.add("Plays with all Friends :");
    b.add("Plays with only one or two Friends :");

    List<String> d = new ArrayList<>();
    d.add("Enjoys Physical Activities :");
    d.add("Enjoys EPL Activities :");
    d.add("Enjoys Playing :");
    d.add("Can Throw a Ball :");
    d.add("Can Catch a Ball :");
    d.add("Can Run,Jump :");
    d.add("Can Climb Equipment :");
    d.add("Can Balance on a Beam :");

    List<String> c = new ArrayList<>();
    c.add("Enjoys Listening Rhymes :");
    c.add("Enjoys Singing RRhymes :");
    c.add("Enjoys Performing Actions :");
    c.add("Enjoys Dancing :");
    c.add("Enjoys Attention of Others :");

    List<String> e = new ArrayList<>();
    e.add("Can String Beads :");
    e.add("Can Colour With Crayons :");
    e.add("Can Paint with Brush :");
    e.add("Can Put Together a Piece of Puzzle :");
    e.add("Can Stack a Net Of Blocks :");

    List<String> f = new ArrayList<>();
    f.add("Greets Everybody :");
    f.add("Eats Healthy Foode :");
    f.add("Drinks Water :");
    f.add("Eats Independently :");
    f.add("Happy to Come to School :");
    f.add("Plays Safely :");

    listHash.put(listDataheader.get(0),a);
    listHash.put(listDataheader.get(1),b);
    listHash.put(listDataheader.get(2),c);
    listHash.put(listDataheader.get(3),d);
    listHash.put(listDataheader.get(4),e);
    listHash.put(listDataheader.get(5),f);

}

适配器

public class ExpandablelistAdapter extends BaseExpandableListAdapter
{
private Context context;
private List<String> listDataheader;
private HashMap<String,List<String>> listHashMap;

public ExpandablelistAdapter(Context context, List<String> listDataheader, HashMap<String, List<String>> listHashMap)
{
    this.context = context;
    this.listDataheader = listDataheader;
    this.listHashMap = listHashMap;
}

@Override
public Object getChild(int i, int i1)
{return (listHashMap.get(listDataheader.get(i)).get(i1));} // i = Group Item , i1 = ChildItem

@Override
public long getChildId(int i, int i1) {
    return i1;
}

@Override // i - group position , i1 - child position b - isLastchild
public View getChildView(final int i, final int i1, boolean b, View view, ViewGroup viewGroup)
{
    final String childText = (String)getChild(i,i1);
    ViewHolder holder;

    if(view==null)
    {
        LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.expandable_list_items, null);

        holder = new ViewHolder(view);
        view.setTag(holder);
    }

    holder = (ViewHolder)view.getTag();
    holder.features.setText(childText);
    holder.ratingbar.setTag(i1);

    holder.ratingbar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener()
    {
        @Override
        public void onRatingChanged(RatingBar ratingBar, float v, boolean b)
        {
            Toast.makeText(context, "Rating : " + ratingBar.getRating() + " Skills : "+ i +" Position : " + i1, Toast.LENGTH_SHORT).show();
        }
    });
    return view;
}

@Override
public int getChildrenCount(int i) { return listHashMap.get(listDataheader.get(i)).size(); }


@Override
public Object getGroup(int i) {
    return listDataheader.get(i);
}

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

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

@Override // i - group position b - isExpanded
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup)
{
    String headerTitle = (String)getGroup(i);
    if(view == null)
    {
        LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.expandable_list_group,null);
    }
    TextView listHeader = view.findViewById(R.id.expListHeader);
    listHeader.setTypeface(null, Typeface.BOLD_ITALIC);
    listHeader.setText(headerTitle);
    return view;
}

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

@Override
public boolean isChildSelectable(int i, int i1) {
    return true;
}

private static class ViewHolder
{
    RatingBar ratingbar;
    TextView features;

    public ViewHolder(View view) {
        ratingbar = view.findViewById(R.id.rate_img);
        features = view.findViewById(R.id.expListItem);
    }
}
}

我在这上面浪费了很多时间..我哪里错了?

ListView 回收您的视图并重复使用它们。检查 RatingBar 并向下滚动后,将重复使用完全相同的视图。您已经检查了评级栏并且没有指示重置它,因此您看到与检查相同的视图 RatingBar

要解决此问题,您必须在某种数据结构中保留选中的评分条值,例如在数组中:


    int[][] arr = new int[groupCount][childCount];

    public View getChildView(final int groupPosition, final int childPosition, boolean b, View view, ViewGroup viewGroup)
    {
        ...
        holder = (ViewHolder) view.getTag();
        holder.ratingBar.setRating(arr[groupPosition][childPosition]);
        ...

        holder.ratingbar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
                arr[groupPosition][childPosition] = (int) ratingBar.getRating();
            }
        });

        return view;
    }

使用 holder 时 :- 始终记得在视图为 new/null 时设置它的标签,在视图不存在时获取它的标签。 @azizbekian 的逻辑是存储和检索也有效的评分值。

代码

  @Override // i - group position , i1 - child position b - isLastchild
  public View getChildView(final int i, final int i1, boolean b, View view, ViewGroup viewGroup)
  {
    final String childText = (String)getChild(i,i1);
    ViewHolder holder;

    if(view==null)
    {
        LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.expandable_list_items, null);

        holder = new ViewHolder(view);
        view.setTag(holder);
    }

    else
    {
        holder = (ViewHolder)view.getTag();
    }

    holder.ratingbar.setOnRatingBarChangeListener(onRatingChangedListener(holder, i, i1));

    holder.features.setText(childText);
    holder.ratingbar.setTag(i1);
    holder.ratingbar.setRating(arr[i][i1]);

    return view;
}