0

长期读者,第一次海报。我对 Android 开发非常陌生,并且在使用 AsyncTask 将 ImageViews(包含位图)插入 LinearLayout 时无法显示图像。这都是在我拥有的 Activity 的 onCreate() 方法中触发的。

ImageViews (+Bitmaps) 肯定会通过 AsyncTask 添加到我的 LinearLayout 父级。但是,当我开始我的活动时,图像无法正确显示。有时会显示一两个图像(超过 3 个),有时不会显示。在我摆弄 UI 后,所有图像都能正常显示,例如通过调出和隐藏键盘。我怀疑 LinearLayout 和/或 ImageViews 可能没有调整大小以包含和显示所有新子项,但我在我标记为“LOCATION1”和“LOCATION2”的地方尝试了许多 invalidate() 和 requestLayout() 组合尝试触发重绘。

有人会帮助确保在 onCreate() 之后和每个 AsyncTask 完成后正确显示所有图像吗?谢谢一堆。我会尽量用我的代码片段简洁...

这是我的布局 XML。我将 ImageViews 添加到 ID 为“horizo​​ntal”的 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 回答