0

だから、私はこの写真のようなはずのアプリをやっています:

infocardapp

これには、ユーザーが表示するコンテンツを選択する1つのリストビューと、コンテンツが選択されたときにアニメーション化(スライドイン/スライドアウト)されるコンテンツ領域があります。

コンテンツ領域は動的に構築する必要があり、そのレイアウトはJSONリクエストに含まれる情報に応じて変化し、各アイテムが1つの情報セクションである巨大なリストビューで構成されます(画像を参照)。

問題は、UIスレッドで大量のビューの読み込みが行われているときにコンテンツ領域をアニメーション化すると、アニメーションで大きなラグとちらつきが発生し、UIスレッド以外のスレッドではビューの読み込みを実行できないことです。

アダプターでUIの読み込みをバックグラウンドで実行しようとしAsyncTaskましたが、ViewHolderパターンのインスタンス化とfindviewById呼び出しのみが内部に入る可能性があるため、パフォーマンスが大幅に向上することはありませんでした。実際の問題は .setText().setImageBitmap()呼び出しです。

最後に、本当の問題は、スムーズなアニメーションを作成するために、このUIの読み込みでパフォーマンスを向上させるために何ができるかということです。

注:コンテンツ領域にデータを取り込むために使用されるデータは、テスト目的でハードコーディングされていると考えてください。


編集: 私のコンテンツエリアアダプタで使用されているコード:

public class InfoAdapter extends ArrayAdapter<Info> {

    private final LayoutInflater layoutInflater;
    private final Typeface typeface;

    public InfoAdapter(final Context context, final List<Info> list) {
        super(context, 0, list);
        this.layoutInflater = LayoutInflater.from(context);
        this.typeface = Typeface.createFromAsset(context.getAssets(), "fonts/"
                + Constants.DEFAULT_FONTNAME);
    }

    @Override
    public View getView(final int position, final View convertView,
            final ViewGroup parent) {

        View infoView = convertView;

        ViewHolder holder;
        if (infoView == null) {
            infoView = (RelativeLayout) layoutInflater.inflate(getItem(position).getLayout(), null);
            holder = new ViewHolder(
                    (TextView) infoView.findViewById(R.id.highlight_title),
                    (TextView) infoView.findViewById(R.id.info_title),
                    (TextView) infoView.findViewById(R.id.info_extra_info01),
                    (TextView) infoView.findViewById(R.id.info_extra_info02),
                    (TextView) infoView.findViewById(R.id.info_description),
                    (ImageView) infoView.findViewById(R.id.info_image),
                    (TextView) infoView.findViewById(R.id.info_subtitle),
                    (TextView) infoView.findViewById(R.id.info_subdescription),
                    (ImageView) infoView.findViewById(R.id.info_subimage));
            infoView.setTag(holder);
        } else {
            holder = (ViewHolder) infoView.getTag();
        }

        final String extraInfo01 = String.valueOf((int) (getItem(position).getValue() / 1));
        final String extraInfo02 = String.valueOf((int) ((getItem(position).getValue() % 1) * 100));

        setDataInView(holder.highlight, getItem(position).getFavorite());

        holder.title.setText(getItem(position).getName());
        holder.title.setTypeface(typeface);

        holder.extraInfo01.setText(extraInfo01);
        holder.extraInfo01.setTypeface(typeface);

        holder.extraInfo02.setText("," + extraInfo02);
        holder.extraInfo02.setTypeface(typeface);

        holder.description.setText(getItem(position).getDescription());
        holder.description.setTypeface(typeface);


        if (holder.image != null) {
            if (getItem(position).getImage() == 0) {
                holder.image.setVisibility(View.GONE);
            } else {
                holder.image.setVisibility(View.VISIBLE);
                holder.image.setImageResource(getItem(position).getImage());
            }
        }


        setDataInView(holder.subTitle, getItem(position).getHistoryTitle());
        setDataInView(holder.subDescription, getItem(position).getHistory());

        if (holder.subImage != null) {
            if (getItem(position).getUri() == null) {
                holder.subImage.setVisibility(View.GONE);
            } else {
                final Drawable subDrawable = Drawable.createFromPath(getItem(
                        position).getUri());
                holder.subImage.setVisibility(View.VISIBLE);
                holder.subImage.setImageDrawable(subDrawable);
            }
        }

        return infoView;
    }

    private void setDataInView(final TextView textView, final String data) {
        if (textView != null) {
            if (data.isEmpty()) {
                textView.setVisibility(View.GONE);
            } else {
                textView.setVisibility(View.VISIBLE);
                textView.setTypeface(typeface);
                textView.setText(data);
            }
        }
    }

    private static class ViewHolder {
        private final TextView highlight;
        private final TextView title;
        private final TextView extraInfo01;
        private final TextView extraInfo02;
        private final TextView description;
        private final ImageView image;
        private final TextView subTitle;
        private final TextView subDescription;
        private final ImageView subImage;

        public ViewHolder(final TextView highlight, final TextView title,
                final TextView extraInfo01, final TextView extraInfo02,
                final TextView description, final ImageView image,
                final TextView subTitle, final TextView subDescription,
                final ImageView subImage) {
            this.highlight = highlight;
            this.title = title;
            this.extraInfo01 = extraInfo01;
            this.extraInfo02 = extraInfo02;
            this.description = description;
            this.image = image;
            this.subTitle = subTitle;
            this.subDescription = subDescription;
            this.subImage = subImage;
        }

    }

}
4

1 に答える 1

2

この行が問題になる可能性があると思います。

holder.image.setImageResource(getItem(position).getImage());

setImageResourceドキュメントに書かれていることを確認してください。

これにより、UIスレッドでビットマップの読み取りとデコードが行われるため、遅延が発生する可能性があります。それが懸念される場合は、代わりにsetImageDrawable(android.graphics.drawable.Drawable)またはsetImageBitmap(android.graphics.Bitmap)とBitmapFactoryの使用を検討してください。

画像の遅延読み込みについては、このリンクを確認する必要があります。宣言を変更する必要がありますpublic void download(String url, ImageView imageView)

public void download(int id, ImageView imageView)

id

getItem(position).getImage()
于 2013-01-15T22:19:23.760 に答える