0

サーバーからトラフィック レポートを読み込み、タイムライン (Twitter など) に表示するアプリがあります。アプリは、次のコードを使用して 10 秒ごとにサーバーからデータを読み込むように構成されています。

 @Override
        public void onResume() {
          super.onResume();
          autoUpdate = new Timer();
          autoUpdate.schedule(new TimerTask() {
             @Override
             public void run() {
               runOnUiThread(new Runnable() {
                 public void run() {
                   new DownloadJSON2().execute(); // this is the class that downloads the data from the server.
                 }
               });
             }
           }, 0, 10000); // updates each 10 secs
         }


        @Override
        public void onPause() {
           autoUpdate.cancel();
           super.onPause();
        }

問題は、リストを下にスクロールして古い投稿を読んでいると、リストが更新されて一番上に移動することです。そのデータをajaxのようにダウンロードして先頭に追加したい。または、X 件の新しいレポートとそれを表示するためのボタンを教えてください。

どうすればこれを達成できますか?

ところで、私はAndroidプログラミングに非常に慣れていません。

前もって感謝します。

編集: Vasily Sochinsky のおかげで、以下を追加しました。

public class DownloadJSON extends AsyncTask<Void, Void, Void> {

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                // Create a progressdialog
                mProgressDialog = new ProgressDialog(MainActivity.this);
                // Set progressdialog title
                mProgressDialog.setTitle("Cargando reportes en tiempo real");
                // Set progressdialog message
                mProgressDialog.setMessage("Por favor espere");
                mProgressDialog.setIndeterminate(false);
                // Show progressdialog
                mProgressDialog.show();
            }

            @Override
            protected Void doInBackground(Void... params) {
                // Create an array
                arraylist = new ArrayList<HashMap<String, String>>();
                // Retrieve JSON Objects from the given URL address
                jsonobject = JSONfunctions
                        .getJSONfromURL("http://server.com/timeline.php");

                try {
                    // Locate the array name in JSON
                    jsonarray = jsonobject.getJSONArray("datos");

                    for (int i = 0; i < jsonarray.length(); i++) {
                        HashMap<String, String> map = new HashMap<String, String>();
                        jsonobject  = jsonarray.getJSONObject(i);
                        // Retrive JSON Objects
                       // jsonobject1  = jsonobject.getJSONObject("contenido");
                        map.put("imagen", jsonobject.getString("imagen"));
                        map.put("quien", jsonobject.getString("quien"));
                        map.put("fecha", jsonobject.getString("fecha"));
                        map.put("reporte", jsonobject.getString("reporte"));
                      //  map.put("imgs", jsonobject1.getString("imgs"));
                      //  map.put("video", jsonobject1.getString("video"));
                        // Set the JSON Objects into the array
                        arraylist.add(map);
                    }
                } catch (JSONException e) {
                    Log.e("Error", e.getMessage());
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void args) {
                // Locate the listview in listview_main.xml
                listview = (ListView) findViewById(R.id.listview);
                // Pass the results into ListViewAdapter.java
                adapter = new ListViewAdapter(MainActivity.this, arraylist);
                // Set the adapter to the ListView
                listview.setAdapter(adapter);
                adapter.notifyDataSetChanged();
                // Close the progressdialog
                mProgressDialog.dismiss();
            }
        }

しかし、リストビューは新しいデータで更新されていません。どうすればこれを達成できますか?

編集 2: 解決策を提供してくれた cogentapps に感謝しますが、まだコードに追加できません。どこに追加すればよいですか?

私はこれを試しましたが、Eclipseは多くのエラーを示しています:

protected void onPostExecute(Void args) {
                // Locate the listview in listview_main.xml
                listview = (ListView) findViewById(R.id.listview);
                // Pass the results into ListViewAdapter.java
                adapter = new ListViewAdapter(MainActivity.this, arraylist);
                // Set the adapter to the ListView
                adapter.addAll();
                listview.notifyDataSetChanged();
                // Close the progressdialog
                mProgressDialog.dismiss();
            }

これは私の ListViewAdapter のコードですが、どこに adapter.add() を追加すればよいですか?

public class ListViewAdapter extends BaseAdapter {

    // Declare Variables
    Context context;
    LayoutInflater inflater;
    ArrayList<HashMap<String, String>> data;
    ImageLoader imageLoader;
    HashMap<String, String> resultp = new HashMap<String, String>();
    String coment;
    public String img;
    public int imga;
    public ListViewAdapter(Context context,
            ArrayList<HashMap<String, String>> arraylist) {
        this.context = context;
        data = arraylist;
        imageLoader = new ImageLoader(context);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        // Declare Variables
        TextView quien;
        ImageView imagen;
        TextView reporte;
        TextView fecha;

        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View itemView = inflater.inflate(R.layout.listview_item, parent, false);
        // Get the position
        resultp = data.get(position);

        // Locate the TextViews in listview_item.xml
        // Locate the ImageView in listview_item.xml
        imagen = (ImageView) itemView.findViewById(R.id.imagen);
        fecha = (TextView) itemView.findViewById(R.id.fecha);
        quien = (TextView) itemView.findViewById(R.id.quien);
        reporte = (TextView) itemView.findViewById(R.id.reporte);
        // Capture position and set results to the TextViews
     // Capture position and set results to the ImageView
        // Passes flag images URL into ImageLoader.class
        imageLoader.DisplayImage(resultp.get(MainActivity.IMAGEN), imagen);
        fecha.setText(resultp.get(MainActivity.FECHA));
        reporte.setText(resultp.get(MainActivity.REPORTE));
        quien.setText(resultp.get(MainActivity.QUIEN));
        // Capture ListView item click
        /*
        itemView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // Get the position
                resultp = data.get(position);
                    Intent intent = new Intent(context, SingleItemView.class);
                    // Pass all data rank

                    intent.putExtra("imagen", resultp.get(MainActivity.IMAGEN));

                    intent.putExtra("quien", resultp.get(MainActivity.QUIEN));

                    intent.putExtra("fecha", resultp.get(MainActivity.FECHA));
                    // Start SingleItemView Class
                    context.startActivity(intent);


            }
        });
        */
        return itemView;
    }
}
4

1 に答える 1

1

リストにアイテムを追加した後にスクロール位置を維持する方法の説明/例については、この質問への回答をご覧ください。

基本的に、新しいデータを追加する前に、リスト内の最初の表示項目の位置とスクロール オフセットをメモします。その後、以前の位置とスクロール オフセットを復元します。

ただし、リストの一番上に新しいアイテムを追加しているため、getFirstVisiblePosition()更新後に返される位置が別のアイテムを参照している可能性があります。更新前に位置 0 だったアイテムは、現在位置 10 になっている可能性があります。これを修正するには、次のように、 によって返される新しいアイテムの数を決定し、timeline.phpそれを に追加する必要がありますindex

mList.setSelectionFromTop(index + newItemCount, top);

日付フィールドを比較することで、どのアイテムが新しいかを判断できる可能性があります。

(ちなみに、timeline.php最新のアイテム セットのみを返す場合、 によって返されなくなった古いアイテムにユーザーがスクロールした場合に問題が発生する可能性がありますtimeline.php。新しいデータを設定した後、古いアイテムは存在しなくなります。であるため、スクロールすることはできません。

これを修正するには、古いものを保持し、ArrayList新しいアイテムのみを に追加しdoInBackground()ます。そして、電話notifyDataSetChanged()してdoInBackground()ください。そうすれば、アダプターは引き続き古いアイテムにアクセスできます。)

于 2013-10-23T00:15:02.933 に答える