ArrayAdapter 无法更新内容

ArrayAdapter unable to update contents

我正在尝试更新我的 ArrayAdapter 的内容。我已尝试在适配器上调用方法 notifyDataSetChanged() 并在 ListView 上调用方法 invalidate() 但我没有看到适配器中的数据被更改。我花了两个小时搜索关于这个主题的每个 Whosebug post,但 none 的答案有效。

这是我扩展的 ArrayAdapter class

public class ChannelAdapter extends ArrayAdapter<ChannelRow> {

Context context;
int layoutResourceId;
ChannelRow[] data;

public ChannelAdapter(Context context, int layoutResourceId, ChannelRow[] data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    ChannelRowHolder holder = null;

    if(row == null)
    {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new ChannelRowHolder();
        holder.userName = (TextView)row.findViewById(R.id.userNameTextView);
        holder.channelName = (TextView)row.findViewById(R.id.channelNameTextView);

        row.setTag(holder);
    }
    else
    {
        holder = (ChannelRowHolder)row.getTag();
    }

    ChannelRow channelRow = data[position];
    holder.userName.setText(channelRow.getUserName());
    holder.channelName.setText(channelRow.getChannelName());

    return row;
}

static class ChannelRowHolder
{
    TextView userName;
    TextView channelName;
}

}

下面是我的Activity我处理的适配器。

public class ChannelNameActivity extends Activity {

private ListView channelListView ;
private ChannelRow[] channelData;
private ChannelAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ...

    this.setContentView(R.layout.activity_channelname);

    // create ListView of channels
    grabSessions();
    channelData = new ChannelRow[]{ // default data
        new ChannelRow("user1", "channel1"),
        new ChannelRow("user2", "channel2")
    };

    // attach ListView adapters/views
    adapter = new ChannelAdapter(this, R.layout.channel_row, channelData);
    channelListView = (ListView) findViewById(R.id.channelListView);
    final View contentView = (View)getLayoutInflater().inflate(R.layout.activity_channelname, null);
    channelListView.addHeaderView(contentView);
    channelListView.setAdapter(adapter);

....
}

private void grabSessions() {
    ParseQuery<ParseObject> query = ParseQuery.getQuery("Session");
    query.findInBackground(new FindCallback<ParseObject>() {
        public void done(List<ParseObject> objects, ParseException e) {
            if (e == null) {
                createSessionsList((ArrayList<ParseObject>) objects);
            } else {
                // error with query
            }
        }
    });
}

/**
 * Called from grabSessions()
 * Initializes channelData with the queried ParseObject Sessions
 * @param objects the queried Sessions
 */
private void createSessionsList(ArrayList<ParseObject> objects){
    ArrayList<ChannelRow> channels = new ArrayList<>();
    ChannelRow newRow = null;

    for (ParseObject o : objects){
        newRow = new ChannelRow((String)o.get("hostName"), (String)o.get("chatTitle"));
        channels.add(newRow);
    }

    channelData = channels.toArray(new ChannelRow[channels.size()]);
    adapter.notifyDataSetChanged();
    channelListView.invalidate();
}

}

先生;

看看这个 private ChannelRow[] channelData; 这是你的实例变量,你在你的 onCreate() 中实例化它

channelData = new ChannelRow[]{ // default data
    new ChannelRow("user1", "channel1"),
    new ChannelRow("user2", "channel2")
}; // channelData is holding is reference to the object being created with the `new` keyword

例如,如果您向 channelData 添加一个对象并调用您的 notifyDataSetChanged(),它将在您的 createSessionsList(ArrayList<ParseObject> objects) 方法中刷新 but您将 channelData 分配给一个像这样的新对象 channelData = channels.toArray(new ChannelRow[channels.size()]); 而这个引用不是 ListViewAdapter 数据所指向的,所以您的 notifyDataSetChanged()不起作用,因为它没有改变。你所要做的就是回忆实例化行,这是完整的代码

private void createSessionsList(ArrayList<ParseObject> objects){
ArrayList<ChannelRow> channels = new ArrayList<>();
ChannelRow newRow = null;

for (ParseObject o : objects){
    newRow = new ChannelRow((String)o.get("hostName"), (String)o.get("chatTitle"));
    channels.add(newRow);
}

channelData = channels.toArray(new ChannelRow[channels.size()]);
adapter = new ChannelAdapter(this, R.layout.channel_row, channelData);
//edit started here   
// set your Listview to the adapter    
channelListView.setAdapter(adapter); // you set your list to the new adapter
adapter.notifyDataSetChanged();// you can remove it if you like
}

编辑 1

如果你讨厌一直调用这条线 adapter = new ChannelAdapter(this, R.layout.channel_row, channelData); 的想法,我建议你使用 ArrayList 并使用 ArrayList.add(Object o) 功能来更新你的项目,那么你可以notifyDataSetChanged() ..

希望对您有所帮助..