Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 更改已可见TextView的文本时,ListView中的第一项不会更新_Android_Listview_Baseadapter - Fatal编程技术网

Android 更改已可见TextView的文本时,ListView中的第一项不会更新

Android 更改已可见TextView的文本时,ListView中的第一项不会更新,android,listview,baseadapter,Android,Listview,Baseadapter,我有一个ListView,它由我的自定义BaseAdapter填充,其中的视图包含两个TextView和ImageButton。如果用户从其中一个列表项的弹出菜单中选择一个项,则会更改该列表项上关联文本视图的文本。这对于我的ListView中的所有项目都非常有效,除了第一个项目。由于某些原因,第一项从不更新TextView。我怀疑这与我的convertView没有重置该项有关,但我不确定如何着手修复它 这是我的设置。我有一个由自定义BaseAdapter填充的ListView。在我的BaseAd

我有一个ListView,它由我的自定义BaseAdapter填充,其中的视图包含两个TextView和ImageButton。如果用户从其中一个列表项的弹出菜单中选择一个项,则会更改该列表项上关联文本视图的文本。这对于我的ListView中的所有项目都非常有效,除了第一个项目。由于某些原因,第一项从不更新TextView。我怀疑这与我的convertView没有重置该项有关,但我不确定如何着手修复它

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

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;
}
用户可以在每个列表项上打开弹出菜单并进行选择。当他们这样做时,上述代码中的TextView将被更改,以用新文本反映所选内容。该代码如下所示:

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中的每一项上都非常有效,除了第一项,它从不更新以反映TextView的更改。我已经进行了测试,以确保TextView文本实际上正在更改,可以在以后调用和查看,并且设置正确。所以看起来数据是正确的,但是视图没有得到更新

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

这个问题看起来很有希望:

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

有什么想法吗?我已经通读了一些关于SO和Google的类似问题,但没有一个与我的具体情况相关。我已经使用ListView和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();
    }
}

我找到了解决这个问题的办法。在研究有关BaseAdapters和
getView()
的随机问题时,我终于遇到了一个问题,他在问题中指出,对于ListView的
layout\u height
,永远不要使用
wrap\u content
,因为它会导致ListView调用适配器的
getView()
创建虚拟视图(用于测量内容高度)需要花费大量时间。原来这是导致我的问题的原因,所以将我的
布局\u高度
更改为
匹配\u父项
就成功了

不幸的是,现在这导致了一个新问题,因为我无法使用
匹配父视图
,因为它将隐藏父布局中的其他视图。但至少第一个列表项现在正在正确更新


更新:

我学习了如何在填充ListView的适配器后手动动态设置其高度。我使用了下面的方法,希望这能帮助一些遇到类似问题的人。这使得我不必使用
wrap\u 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();
}
private void setModListHeight(){
int numberOfItems=modGroups.size();//为我的ListView提供数据的ArrayList
int totalItemsHight=0;
对于(int position=0;position
尝试移动
IMOModGroup=modGroups.get(位置)脱离if Block能否显示整个适配器类?@SebastianRoth-发布了完整的BaseAdapter代码。@mdtuyen-不能这样做,因为无论发生什么情况,每次我都会得到一个新的convertView实例。只是为了好玩,我试了一下,结果它表现得和我预期的一样,而且没有正常工作。
//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();
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();
}