2015-02-28 6 views
1

Я пытаюсь обновить содержимое моего ArrayAdapter. Я попытался вызвать метод notifyDataSetChanged() на адаптере и invalidate() на ListView, но я не вижу данных в изменяющемся адаптере. Я потратил два часа на поиск в каждом сообщении StackOverflow об этой теме, но ни один из ответов не работал.ArrayAdapter не удалось обновить содержимое

Вот ArrayAdapter класс, который я продлил

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(); 
} 

} 
+0

не видит ничего плохого в вашем коде. Но три момента: вы уверены, что ваши данные действительно изменились? Во-вторых, 'invalidate' в listView абсолютно бесполезен и может быть даже хуже (я не думаю, что это ваша проблема, но я удалю его). В-третьих, попробуйте вызвать 'notifyDataSetInvalidated()' вместо 'notifydataSetChanged'. Я посмотрю глубже. –

+0

@LaurentMeyer Я думаю, что ваш первый пункт попал в проблему. Я установил отладчик для остановки в строке notifyDataSetChanged и проверил данные адаптера. Оказывает, что данные внутри него остались неизменными, что не имеет смысла, поскольку предыдущая строка изменила данные в channelData. –

ответ

2

Сэр;

проверить это 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) вы присваиваете свой 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 
} 

EDIT 1

если вы ненавидите идею вызова этой линии adapter = new ChannelAdapter(this, R.layout.channel_row, channelData); все время я хотел бы предложить вам использовать ArrayList и использовать функцию ArrayList.add(Object o) для обновления элемента, то вы можете все notifyDataSetChanged() ..

Надеется, что это помогает ..

+0

Я создаю новый объект адаптера, как вы заявили, но он по-прежнему показывает данные по умолчанию. –

+0

Вы установили адаптер в свой список? 'channelListView.setAdapter (адаптер);' проверить мое редактирование, я добавляю его, чтобы сделать его полностью завершенным. @ clever_trevor – Elltz

+0

Да. Как только я это сделал, все сработало! –

Смежные вопросы