#android #android-json
#Android #android-json
Вопрос:
В настоящее время у меня есть программа, которая может анализировать JSONArray и помещать каждый элемент в listview. Но если вы добавите что-то в JSONArray, listview не будет обновляться до тех пор, пока вы снова не запустите приложение. Итак, как бы мне получить возможность обновлять listview при добавлении новых элементов в JSONArray. Вот код, который у меня есть, который анализирует JSONArray:
public class jarray extends Activity {
ArrayList<Actors> actorsList;
ActorAdapter adapter;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jarray);
actorsList = new ArrayList<Actors>();
new JSONAsyncTask().execute("http://bisonsoftware.us/hhs/messages.json");
ListView listview = (ListView) findViewById(R.id.list);
adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList);
listview.setAdapter(adapter);
button = (Button)findViewById(R.id.button);
}
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
ProgressDialog dialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(jarray.this);
dialog.setMessage("Loading, please wait");
dialog.setTitle("Connecting server");
dialog.show();
dialog.setCancelable(false);
}
@Override
protected Boolean doInBackground(String... urls) {
try {
//------------------>>
HttpGet httppost = new HttpGet(urls[0]);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
// StatusLine stat = response.getStatusLine();
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
JSONArray jarray = jsono.getJSONArray("messages");
for (int i = 0; i < jarray.length(); i ) {
Actors actor = new Actors();
String message = jarray.getString(i);
actor.setName(message);
//actorsList.add(actor);
adapter.add(actor);
}
return true;
}
//------------------>>
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
dialog.cancel();
adapter.notifyDataSetChanged();
if (result == false)
Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
}
}
Если вам нужно больше моего кода или просто нужно еще какое-то объяснение, не стесняйтесь спрашивать. Действительно могла бы помочь в этом, спасибо.
Вот код ActorAdapter:
public class ActorAdapter extends ArrayAdapter<Actors> {
ArrayList<Actors> actorList;
LayoutInflater vi;
int Resource;
ViewHolder holder;
@Override
public void add(Actors object) {
super.add(object);
notifyDataSetChanged();
}
public ActorAdapter(Context context, int resource, ArrayList<Actors> objects) {
super(context, resource, objects);
vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Resource = resource;
actorList = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// convert view = design
View v = convertView;
if (v == null) {
holder = new ViewHolder();
v = vi.inflate(Resource, null);
holder.tvName = (TextView) v.findViewById(R.id.tvName);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.tvName.setText(actorList.get(position).getName());
return v;
}
static class ViewHolder {
public TextView tvName;
}
}
Комментарии:
1. что вы подразумеваете под «не обновляется, пока вы не запустите приложение снова?»
2. Если я добавлю что-то в JSONArray, оно не появится в listview, пока я не перезапущу приложение / программу.
3. опубликуйте свой адаптер ActorAdapter
Ответ №1:
Вместо добавления непосредственно в ArrayList попробуйте добавить его из вашего адаптера.
ActorAdapter
Перед запуском вашего AsyncTask
пример:
setContentView(R.layout.activity_jarray);
actorsList = new ArrayList<Actors>();
adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList);
ListView listview = (ListView) findViewById(R.id.list);
listview.setAdapter(adapter);
new JSONAsyncTask().execute("http://bisonsoftware.us/hhs/messages.json");
button = (Button)findViewById(R.id.button);
Когда вы добавляете элементы в адаптер, вызывайте метод add адаптера, а не вашего ArrayList
измените это:
actorsList.add(actor);
Для:
adapter.add(actor);
Добавьте это в ActorAdapter
свой адаптер:
@Override
public void add(Actors object) {
super.add(object);
notifyDataSetChanged();
}
измените ваш oncreate на это:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jarray);
actorsList = new ArrayList<Actors>();
adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList);
ListView listview = (ListView) findViewById(R.id.list);
listview.setAdapter(adapter);
new JSONAsyncTask().execute("http://bisonsoftware.us/hhs/messages.json");
button = (Button)findViewById(R.id.button);
}
Комментарии:
1. Когда я добавил adapter.notifyDataSetChanged(); при запуске приложения произошел сбой. Есть ли у вас какие-либо идеи, почему это будет сделано?
2. @user3358306 попробуйте удалить его и переопределить метод добавления ur адаптера ur
3. Я не уверен, что понимаю, не могли бы вы уточнить?
4. @user3358306 см. Редактирование выше .. и не используйте adapter.notifyDataSetChanged()
5. Подождите, в какую часть actoradapter я должен это добавить?
Ответ №2:
Способ обновления listview заключается в том, чтобы переделать адаптер с обновленной информацией, установить listadapter и затем вызвать NotifyDataSetChanged()
. Это говорит устройству обновить макет.
ListView listview = (ListView) findViewById(R.id.list);
adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList);
listview.setAdapter(adapter);
adapter.NotifyDataSetChanged();
Комментарии:
1. Я добавил это, но, похоже, это не сработало. У меня также был адаптер. NotifDataSetChanged(); в onPostExecute. Может быть, я просто делаю это неправильно, как вы думаете, вы могли бы уточнить это решение?
2. Когда вы создавали новый ActorAdapter, вы создавали его с новыми данными актера? Если нет, вызов ‘notifyDataSetChanged ()’ просто переведет адаптер в состояние, в котором он уже находится.