Реализация «кнопки обновления» для синтаксического анализа JSONArray

#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 ()’ просто переведет адаптер в состояние, в котором он уже находится.