0

長年の読者、初めてのポスター。私は Android 開発に非常に慣れておらず、AsyncTask を使用して ImageViews (ビットマップを含む) を LinearLayout に挿入するときに画像を表示するのに問題があります。これはすべて、私が持っているアクティビティの onCreate() メソッドでトリガーされます。

ImageViews (+Bitmaps) は、AsyncTask を介して LinearLayout の親に確実に追加されています。ただし、アクティビティを開始すると、画像が正しく表示されません。1 つまたは 2 つの画像 (3 つ以上のうち) が表示される場合と、まったく表示されない場合があります。キーボードを表示したり隠したりするなど、UI をいじると、すべての画像が適切に表示されます。LinearLayout および/または ImageViews は、すべての新しい子を含めて表示するようにサイズ変更されていない可能性があると思われますが、「LOCATION1」および「LOCATION2」としてマークした場所で、invalidate() と requestLayout() の多くの組み合わせを試しました。再描画をトリガーします。

onCreate() の後、および各 AsyncTask が完了した後に、すべての画像が適切に表示されるようにするのを手伝ってくれる人はいますか? 本当にありがとう。コードスニペットを簡潔にしようと思います...

これは私のレイアウト XML です。ID「水平」で ImageViews を LinearLayout に追加しています。

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<EditText
    ... />

<HorizontalScrollView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <LinearLayout
        android:id="@+id/horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
    </LinearLayout>
</HorizontalScrollView>

これは私の onCreate() コードの一部です。表示するすべての画像に対して AsyncTask を作成する場所。

protected void onCreate(Bundle savedInstanceState) {
...
LinearLayout horizontal = (LinearLayout) findViewById(R.id.horizontal);
...
//an array of absolute file paths to JPGs in storage
ArrayList<String> images = report.getImageMain();
PhotoBitmapTask task = null; //extension of AsyncTask
for (int i = 0; i < images.size(); i++) {
    task = new PhotoBitmapTask(getApplicationContext(), horizontal, images);
    task.execute(i);
    //LOCATION1
}
...
}

これは私の AsyncTask の拡張機能です。

//a bunch of imports
public class PhotoBitmapTask extends AsyncTask<Integer, Void, Bitmap> {

    private Context context;
    private WeakReference<ViewGroup> parent;
    private ArrayList<String> images;
    private int data;

    public PhotoBitmapTask(Context context, ViewGroup parent, ArrayList<String> images) {
        super();

        this.context = context;
        this.parent = new WeakReference<ViewGroup>(parent);
        this.images = images;
        this.data = 0;
    }

    @Override
    protected Bitmap doInBackground(Integer... params) {
        data = params[0];
        return getBitmapFromFile(images.get(params[0]), 600, 600);
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);

        if (context != null && parent != null && result != null) {
            ViewGroup viewGroup = parent.get();
            if (viewGroup != null) {
                ImageView imageView = PhotoBitmapTask.getImageView(context);
                imageView.setImageBitmap(result);
                viewGroup.addView(imageView);
                //LOCATION2
            }
        }
    }

    public static Bitmap getBitmapFromFile(String filePath, int maxHeight,
            int maxWidth) {
        // check dimensions for sample size
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);

        // calculate sample size
        options.inSampleSize = getSampleSize(options, maxHeight, maxWidth);

        // decode Bitmap with sample size
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }

    public static int getSampleSize(BitmapFactory.Options options,
            int maxHeight, int maxWidth) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int sampleSize = 1;

        if (height > maxHeight || width > maxWidth) {
            // calculate ratios of given height/width to max height/width
            final int heightRatio = Math.round((float) height / (float) maxHeight);
            final int widthRatio = Math.round((float) width / (float) maxWidth);

            // select smallest ratio as the sample size
            if (heightRatio > widthRatio)
                return heightRatio;
            else
                return widthRatio;
        } else
            return sampleSize;
    }

    public int getData() {
        return this.data;
    }

    public static ImageView getImageView(Context context) {
        // width and height
        final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        // margins
        params.setMargins(20, 20, 20, 20);
        final ImageView view = new ImageView(context);
        view.setLayoutParams(params);
        // scale type
        view.setScaleType(ScaleType.CENTER);
        return view;
    }
}
4

2 に答える 2

0

多くの頭痛と心痛の後、私は答えを見つけました。関連性があるとは思わなかったため、以前は言及したり、具体的に検索したりしませんでしたが、Nuance の 360 SpeechAnywhere 開発者 SDKを使用して、アプリに音声認識を含めています。次のように言って、SDK ライセンスの条項に違反しないことを願っています。

すべての「認識が有効な」アクティビティには、音声認識のコントロールと機能を埋め込むために、ルートとしてカスタム ビューが必要です。カスタム ビューの synchronize() 関数を介して指示しない限り、このカスタム ビューは常にその子を更新するとは限りません。簡単に言うと、AsyncTask が終了し、onPostExecute() が実行され、Bitmap がアクティビティに追加されたら、View の synchronize() メソッドを呼び出しました。

于 2013-10-25T01:49:45.907 に答える
-1

AsynTask では、UI の変更に取り組んでいます。バックグラウンド作業で UI を変更することはできません。runOnUIThread を使用すると、常に UI スレッドで計算が行われます。使いやすさに依存する方がよいでしょう。ここを見てください。

于 2013-10-18T06:49:39.040 に答える