gpt4 book ai didi

android - 当我更改已经可见的 TextView 的文本时,我的 ListView 中的第一项不会更新

转载 作者:行者123 更新时间:2023-11-29 20:15:06 25 4
gpt4 key购买 nike

我有一个 ListView,它由我的自定义 BaseAdapter 填充,其中的 View 包含几个 TextView 和 ImageButton。如果用户从其中一个列表项的 PopupMenu 中选择一个项目,它会更改该列表项上关联的 TextView 的文本。这对我的 ListView 中的所有项目都非常有用,除了第一个。由于某种原因,第一项从不更新 TextView。我怀疑它与我的 convertView 有关,因为该项目没有被重置,但我不确定如何修复它。

这是我的设置。我有一个由自定义 BaseAdapter 填充的 ListView。在我的 BaseAdapter 中,我的 getView() 有这个:

public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
IMOModGroup modGroup = modGroups.get(position);
convertView = modGroup.getConvertView(parent);
}
return convertView;
}

IMOModGroup 是一种特殊的数据结构,它包含每个列表项的所有状态和数据。因此,当 convertView 变为 null 时,BaseAdapter 会从 IMOModGroup 为该位置请求一个新的 convertView。下面是创建新的 convertView 的 IMOModGroup 方法:

public View getConvertView(ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.modifier_list_item, parent, false);

//...

TextView selectedModText = (TextView) convertView.findViewById(R.id.modName);
selectedModText.setText(R.string.no_modifier_selected);
selectedModText.setTextColor(context.getResources().getColor(R.color.grayed_out_text_color));

//...

return convertView;
}

用户可以在每个列表项上打开一个 PopupMenu 并进行选择。当他们这样做时,上面代码中的 TextView 被更改以反射(reflect)新文本的选择。该代码如下所示:

public boolean onMenuItemClick(MenuItem item) {
String selectedMod = item.getTitle().toString();

TextView selectedModText = (TextView) convertView.findViewById(R.id.modName);
selectedModText.setText(selectedMod);
selectedModText.setTextColor(context.getResources().getColor(R.color.imo_blue_light));

//...

return false;
}

除了第一个,所有这些都对 ListView 中的每个项目都非常有效,它永远不会更新以反射(reflect) TextView 的变化。我已经过测试以确保 TextView 文本确实发生了变化,并且可以在以后调用和查看,并且设置正确。所以看起来数据是正确的,但 View 没有得到更新。

我很确定问题是我的 convertView 没有被重置,所以 ListView 只是继续使用旧 View 和旧文本。设置文本后,我尝试在 BaseAdapter 上调用 notifyDataSetChanged(),但这没有用。

这个问题看起来很有希望:First item in list view is not displaying correctly

但我不确定这是否是我的问题,而且我不确定如何将其应用到我的场景中。

有什么想法吗?我已经阅读了一些关于 SO 和谷歌的类似问题,但它们似乎都与我的特定场景无关。我使用 ListViews 和 Adapters 已经有一段时间了,这是我第一次看到这样的东西。感谢您的帮助。


回应评论的编辑

这是完整的 BaseAdapter 代码...

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import java.util.ArrayList;

public class IMOModListAdapter extends BaseAdapter {

private Context context;
private ArrayList<IMOModGroup> modGroups;

public IMOModListAdapter(Context context, ArrayList<IMOModGroup> modGroups) {
this.context = context;
this.modGroups = modGroups;
}

public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
IMOModGroup modGroup = modGroups.get(position);
convertView = modGroup.getConvertView(parent);
}
return convertView;
}

public Object getItem(int position) {
return 0;
}

public long getItemId(int position) {
return 0;
}

public int getCount() {
return modGroups.size();
}
}

进一步测试

随着我深入调试,我意识到当列表中元素 1 的 TextView 发生变化时,甚至根本没有调用 getView()。但是当任何其他元素发生变化时,getView() 将正常调用。

作为健全性检查,我尝试从外部从父 Activity 本身更改第一个列表项的文本。如果我尝试更改第一项,它什么都不做,但如果我尝试更改任何其他列表项,它工作正常!这太奇怪了!这是我尝试过的:

//Set the text of the first item. This does NOTHING and the TextView
//in the item remains unchanged
IMOModGroup modGroup = modGroups.get(0);
modGroup.setTestText("This is some test text");
modList.notifyDataSetChanged();

//Set the text of the second item. This works completely fine!!!!!
IMOModGroup modGroup = modGroups.get(1);
modGroup.setTestText("This is some test text");
modList.notifyDataSetChanged();

最佳答案

好吧,我找到了解决这个问题的方法。只是研究关于 BaseAdapters 和 getView() 的随机 SO 问题,我终于遇到了 this post通过 Romain Guy他在其中声明您永远不应将 wrap_content 用于 ListView 的 layout_height,因为它会导致 ListView 调用适配器的 getView()很多次只是为了创建它用来测量内容高度的虚拟 View 。事实证明这是导致我出现问题的原因,因此将我的 layout_height 更改为 match_parent 就成功了。

不幸的是,现在这导致了一个新问题,因为我不能使用 match_parent,因为它会隐藏我的父布局中的其他 View 。但至少第一个列表项现在正在正确更新。


更新:

我学习了如何在填充适配器后手动和动态设置我的 ListView 的高度。我使用了下面的方法,希望这能帮助遇到类似问题的人。这样我就不必使用 wrap_content 但我仍然可以将 ListView 高度设置为与其内容一样大。

private void setModListHeight() {
int numberOfItems = modGroups.size(); //the ArrayList providing data for my ListView
int totalItemsHeight = 0;

for(int position = 0; position < numberOfItems; position++) {
View item = modListAdapter.getView(position, null, modList);
item.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
totalItemsHeight += item.getMeasuredHeight();
}

int totalDividersHeight = modList.getDividerHeight() * (numberOfItems - 1);

ViewGroup.LayoutParams params = modList.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight;
modList.setLayoutParams(params);
modList.requestLayout();
}

关于android - 当我更改已经可见的 TextView 的文本时,我的 ListView 中的第一项不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34055360/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com