2011-12-20 4 views
1

Я только начинаю экспериментировать с MonoDroid с помощью Visual Studio.MonoDroid Загрузить изображение в ImageView

Пытается загрузить изображение из Интернета и отобразить его в элементе управления ImageView.

К сожалению, по какой-то странной причине изображение не отображается в ImageView. Хотя изображение, кажется, загружено успешно, элемент управления остается пустым.

Все, что я делаю неправильно здесь?

Код выглядит следующим образом:

private void DoClick(object sender, EventArgs e) 
{ 

    WebClient web = new WebClient(); 
    web.DownloadDataCompleted += new DownloadDataCompletedEventHandler(web_DownloadDataCompleted); 
    web.DownloadDataAsync(new Uri(@"http://upload.wikimedia.org/wikipedia/commons/d/d9/Test.png")); 


    Toast.MakeText(this, "Image downloaded!", ToastLength.Short).Show(); 
} 


void web_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) 
{ 

    if (e.Error != null) 
    { 
     Toast.MakeText(this, e.Error.Message, ToastLength.Short).Show(); 
    } 

    else 
    { 

     Bitmap bm = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length); 

     ImageView imgView = FindViewById<ImageView>(Resource.Id.MyImageView); 
     imgView.SetImageBitmap(bm); 


    } 


} 

С Main.axml определяется следующим образом:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
<Button 
    android:id="@+id/MyButton" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/Hello" 
    /> 


    <ImageView 
    android:id="@+id/MyImageView" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:layout_below="@+id/MyButton"/> 



</LinearLayout> 

ответ

4

Есть две проблемы, я вижу здесь:

  1. Ваше «изображение скачанный "тост будет вызываться сразу же после запуска загрузки, так как загрузка будет асинхронной. Вы должны поместить его в метод web_DownloadDataCompleted, если хотите, чтобы он показывался после завершения загрузки.
  2. Основная проблема заключается в том, что вы пытаетесь обновить пользовательский интерфейс из фонового потока. Поскольку загрузка является асинхронной, она обрабатывается в фоновом потоке, включая ваш обратный вызов. Однако вы не можете обновлять пользовательский интерфейс из фонового потока. Если вы заключаете содержимое этого метода в вызове RunOnUiThread(), код работает, как ожидалось:

    void web_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) 
    { 
    
        if (e.Error != null) 
        { 
         RunOnUiThread(() => 
          Toast.MakeText(this, e.Error.Message, ToastLength.Short).Show()); 
        } 
        else 
        { 
    
         Bitmap bm = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length); 
    
         RunOnUiThread(() => 
         { 
          ImageView imgView = FindViewById<ImageView>(Resource.Id.MyImageView); 
          imgView.SetImageBitmap(bm); 
         }); 
        } 
    }