1

ListViewにアニメーションを追加しようとしています。これにより、HTTP GETリクエストから結果が届くと、テキストが別々の行にフェードインします。フェードイン効果を実行する方法を知っていて、カスタムListViewアダプターを既に持っていますが、問題は、結果が入るたびにListViewがすべての行を更新するため、リスト全体に対して毎回フェードイン効果がトリガーされることです。

ListViewがデータの変更ごとにすべての行をアニメーション化しないように、単一の行を制御するにはどうすればよいですか?

これは、ListViewを埋めるために使用するコードです。

    private class CustomAdapter extends ArrayAdapter<Row> {

    public CustomAdapter() {
        super(Results.this, R.layout.row, dataList);
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        RowHolder holder = null;
        if (row == null) {
            LayoutInflater inflater = getLayoutInflater();

            row = inflater.inflate(R.layout.row, parent, false);
            holder = new RowHolder(row);
            row.setTag(holder);
        } else {
            holder = (RowHolder) row.getTag();
        }
        try {
            holder.populateRow(dataList.get(position));
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
        return row;
    }

}

    private class RowHolder {
        private TextView label = null;
        private TextView count = null;
        private TextView result = null;

        public RowHolder(View row) {
            label = (TextView) row.findViewById(R.id.list_label);
            count = (TextView) row.findViewById(R.id.list_count);
            result = (TextView) row.findViewById(R.id.list_result);
        }

        public void populateRow(Row r) {
            label.setText(r.getLabel());
            count.setText(r.getCount());
            result.setText(r.getResult());
            label.startAnimation(fadeIn);
            count.startAnimation(fadeIn);
            result.startAnimation(fadeIn);
        }
    }

どんな助けでもありがたいです、前もってありがとう!

編集1:

私のAsyncTask:

    private class CheckSource extends AsyncTask<String, Void, String> {

    protected void onPreExecute() {
        results.setUnixTime(getUnixTime());
        results.setLabel(getString(R.string.label));
        results.setCount(null);
        results.setResult(null);
        results.setResultLabel("");
        results.setShowProgress(true);
        results.setIconType(null);
        results.setShowIcon(false);
        results.setHasResults(false);
        adapter.notifyDataSetChanged();
    }

    @Override
    protected String doInBackground(String... params) {

        String query = params[0];
        String httpResults = null;

        try {
            httpResults = getResults(query, "source");
            jsonObject = new JSONObject(httpResults);
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return httpResults;
    }

    protected void onPostExecute(String results) {
        try {
            parseJSON(results);
        } catch (JSONException e) {
            e.printStackTrace();
            results.setResultLabel("<br />"
                    + getString(R.string.source_not_available) + "<br />");
        }
        results.setShowProgress(false);
        adapter.notifyDataSetChanged();
    }

    // Parse the retrieved json results
    private void parseJSON(String jsonResults) throws JSONException {
        if (jsonResults == null) {
            results.setResult(null);
            results.setHasResults(false);
            results.setResultLabel("<br />"
                    + getString(R.string.source_not_available) + "<br />");
            return;
        }
        jsonObject = new JSONObject(jsonResults);
        String result = null;
        String resultLabel = null;
        switch (jsonObject.getInt("count")) {
        case -1:
            results.setCount(null);
            results.setHasResults(false);
            resultLabel = getString(R.string.no_results);
            break;
        case 0:
            results.setCount(null);
            results.setHasResults(false);
            resultLabel = getString(R.string.no_results);
            break;
        case 1:
            results.setHasResults(true);
            results.setCount(jsonObject.get("count").toString() + " "
                    + getString(R.string.one_result));
            result = jsonObject.get("url").toString();
            resultLabel = getString(R.string.hyperlink_text);
            break;
        default:
            results.setHasResults(true);
            results.setCount(jsonObject.get("count").toString() + " "
                    + getString(R.string.multiple_results));
            result = jsonObject.get("url").toString();
            resultLabel = getString(R.string.hyperlink_text);
            break;
        }
        results.setResult(result);
        results.setResultLabel("<br />" + resultLabel + "<br />");
    }
}

HTTPリクエストを実行するメソッド:

private String getResults(String query, String source)
        throws IllegalStateException, IOException, URISyntaxException {

    /* Method variables */
    StringBuilder builder = new StringBuilder();
    String URL = "url";
    URI uri;
    String phrase = "phrase";
    List<NameValuePair> params = new ArrayList<NameValuePair>();

    /* HTTP variables */
    HttpGet httpGet;
    DefaultHttpClient httpClient;
    HttpResponse httpResponse;
    HttpEntity httpEntity;
    HttpParams httpParams;

    int socketTimeout = 10000;
    int connectionTimeout = 10000;

    // Set the socket and connection timeout values
    httpParams = new BasicHttpParams();
    HttpConnectionParams
            .setConnectionTimeout(httpParams, connectionTimeout);
    HttpConnectionParams.setSoTimeout(httpParams, socketTimeout);
    httpClient = new DefaultHttpClient(httpParams);
    // Add parameters to the GET request
    params.add(new BasicNameValuePair("query", query));
    params.add(new BasicNameValuePair("type", source));
    String paramString = URLEncodedUtils.format(params, "utf-8");
    uri = new URI(URL + paramString);
    httpGet = new HttpGet(uri);
    // Execute the GET request
    httpResponse = httpClient.execute(httpGet);

    /* Read http response if http status = 200 */
    if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
        httpEntity = httpResponse.getEntity();
        InputStream content = httpEntity.getContent();
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                content));
        String line;
        while ((line = reader.readLine()) != null) {
            builder.append(line);
        }
    }
    return builder.toString();
}
4

2 に答える 2

5

Romain Guy が Google I/O セッションでしばらく前に説明したように、リスト ビュー内の 1 つのビューのみを更新する最も効率的な方法は次のようなものです (これはビュー データ全体を更新します)。

ListView list = getListView();
int start = list.getFirstVisiblePosition();
for(int i=start, j=list.getLastVisiblePosition();i<=j;i++)
    if(target==list.getItemAtPosition(i)){
        View view = list.getChildAt(i-start);
        list.getAdapter().getView(i, view, list);
        break;
    }

想定targetはアダプターの1品です。

このコードは を取得し、現在表示されているビューを参照し、探しているアイテムを表示されている各ビュー アイテムとListView比較します。ターゲットがそれらの中にある場合は、囲んでいるビューを取得し、そのビューでアダプターを実行して表示を更新します。targetgetView

補足として、invalidate一部の人々が期待するように機能せず、getView のようにビューを更新せず、notifyDataSetChangedリスト全体を再構築し、getview表示されたすべてのアイテムを呼び出すことにinvalidateViewsなり、多数に影響を与えます。

最後に、行ビューの子のみを変更する必要があり、行全体を変更する必要がない場合は、パフォーマンスを向上させることもできますgetView。その場合、次のコードで置き換えることができます(テキストlist.getAdapter().getView(i, view, list);を変更する例)。TextView

((TextView)view.findViewById(R.id.myid)).setText("some new text");

コードでは信頼します。

于 2012-04-03T05:50:26.907 に答える
0

メソッドは、のすべての表示要素に対してメソッドnotifyDataSetChangedを呼び出すように強制します。の特定のアイテムを1つだけ更新する場合は、このアイテムをにパスする必要があります。getViewListViewListViewAsynhTask

于 2012-03-19T15:01:35.033 に答える