2013-10-18 30 views
0

長時間閱讀器,第一次張貼海報。我對Android開發非常陌生,在使用AsyncTask將ImageViews(包含位圖)插入到LinearLayout中時無法顯示圖像。這一切都是在我所擁有的Activity的onCreate()方法中觸發的。通過AsyncTask的ImageView/Bitmap無法正常顯示

的ImageViews(+位圖)肯定得到通過的AsyncTask添加到我的LinearLayout父。但是,當我開始活動時,圖像無法正確顯示。有時候會顯示一個或兩個圖片(超過3個),有時候不會顯示。所有的圖像顯示正確後,我擺弄着用戶界面,如通過啓動和隱藏鍵盤。我懷疑LinearLayout和/或ImageViews可能無法調整大小以包含並顯示所有新的子項,但我嘗試了很多在我標記爲「LOCATION1」和「LOCATION2」的地方嘗試invalidate()和requestLayout()的組合觸發重繪。

會有人在保證所有圖像都幫助的onCreate(後正常顯示)和後各的AsyncTask完成?謝謝一堆。我會嘗試用我的代碼片段簡潔...

這是我的佈局XML。我加入我的ImageViews到的LinearLayout ID爲 「橫」:

<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; 
    } 
} 
+0

你在膨脹那些ImageViews嗎?顯示你用來膨脹的代碼。還要記住,當你在onBackground中運行代碼時,你不能在UI中進行更改,因爲你在另一個線程中。 – Reinherd

+0

在這裏發佈您的完整PhotoBitmapTask代碼 –

+0

您確定要這樣做嗎? UI線程適用於UI,如圖像視圖。所以你通常不會把這些放到異步任務中。 –

回答

0

經過很多頭痛和心痛,我找到了答案。我以前沒有提及它或專門搜索它,因爲我不認爲它是相關的,但我使用Nuance's 360 SpeechAnywhere developer SDK在我的應用程序中包含語音識別。但願我不是說這打破了我SDK許可協議的條款:

每個活動都應該有以嵌入語音識別控制和功能的自定義視圖爲根「啓用的認可」。事實證明,除非您通過自定義View的synchronize()函數指示它,否則此自定義View並不總是刷新其子項。長話短說,一旦我的AsyncTask完成,onPostExecute()運行並且Bitmap被添加到活動中,我就調用View的synchronize()方法。

-1

在AsynTask您在UI工作changes.you不能做在後臺UI work.Use runOnUIThread總是做UI thread.It計算的變化更好地取決於您輕鬆use.look在here

+0

我正在對AsyncTask.onPostExecute()中的UI進行更改。 API文檔指示它在「後臺計算完成後在UI線程上調用」。無論如何,我的代碼的一部分似乎工作正常,我只需要ImageViews在AsyncTask完成後正確顯示。 – David