Soru Android ImageGetter görüntüleri üst üste gelen metin


Resim içeren bir TextView'a bir HTML bloğu yüklemeyi deniyorum.

URLImageParser p = new URLImageParser(articleBody, this);
Spanned htmlSpan = Html.fromHtml(parsedString, p, null);

Bu arada parsedString, HTML'dir. Her neyse, yukariya yukleniyor, ama görüntüler, onlarin oturtulmasi için yaratilmis herhangi bir alan olmuyor, bu yüzden onlarin yukaridaki metin ile örtüşüyorlar. İşte URLImageParser dosyam:

public class URLImageParser implements Html.ImageGetter {
Context c;
View container;

/***
 * Construct the URLImageParser which will execute AsyncTask and refresh the container
 * @param t
 * @param c
 */
public URLImageParser(View t, Context c) {
    this.c = c;
    this.container = t;
}

public Drawable getDrawable(String source) {
    URLDrawable urlDrawable = new URLDrawable();

    // get the actual source
    ImageGetterAsyncTask asyncTask = 
        new ImageGetterAsyncTask( urlDrawable);

    asyncTask.execute(source);

    // return reference to URLDrawable where I will change with actual image from
    // the src tag
    return urlDrawable;
}

public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable>  {
    URLDrawable urlDrawable;

    public ImageGetterAsyncTask(URLDrawable d) {
        this.urlDrawable = d;
    }

    @Override
    protected Drawable doInBackground(String... params) {
        String source = params[0];
        return fetchDrawable(source);
    }

    @Override
    protected void onPostExecute(Drawable result) {
        // set the correct bound according to the result from HTTP call
        Log.d("height",""+result.getIntrinsicHeight());
        Log.d("width",""+result.getIntrinsicWidth());
        urlDrawable.setBounds(0, 0, 0+result.getIntrinsicWidth(), 0+result.getIntrinsicHeight()); 

        // change the reference of the current drawable to the result
        // from the HTTP call
        urlDrawable.drawable = result;

        // redraw the image by invalidating the container
        URLImageParser.this.container.invalidate();
    }

    /***
     * Get the Drawable from URL
     * @param urlString
     * @return
     */
    public Drawable fetchDrawable(String urlString) {
        try {
            URL aURL = new URL(urlString);
            final URLConnection conn = aURL.openConnection(); 
            conn.connect(); 
            final BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); 
            final Bitmap bm = BitmapFactory.decodeStream(bis);
            Drawable drawable = new BitmapDrawable(bm);
            drawable.setBounds(0,0,bm.getWidth(),bm.getHeight());
            return drawable;
        } catch (Exception e) {
            return null;
        } 
    }
}

}

Herhangi bir fikir? Bir ton teşekkürler.


25
2017-10-24 00:28


Menşei


Yük resimlerini tembelleştirmeye mi çalışıyorsunuz? Eğer öyleyse, bu orada sadece sorun olduğunu düşünüyorum. Neden resim ve metni aynı anda birlikte yüklemeye çalışmıyorsunuz? - PH7
Tam olarak "tembel yük" ile ne demek istiyorsun? - Nick
Tembel yük, görüntüleri indirildikleri gibi gösterir. Alternatifler, görüntülerin indirilmesini bekler ve yalnızca görüntülemeleri görüntüler. - Kurtis Nusbaum
Benzer bir şey yapmaya çalışıyorum, lütfen URLDrawable'ın burada neyin olduğunu söyler misiniz? - Abhay Kumar
@AbhayKumar URLDrawable dahil olmak üzere orijinal kodun, stackoverflow.com/a/7442725/262462 - Kuitsi


Cevaplar:


Metin görünümüne yüklemeniz için belirli bir neden var mı? Sadece bir tane kullanır mısın WebView yerine?

Web görüntülemelerini kullanamıyorsanız, en iyi çözüm, görüntüleri metin görünümünüze yerleştirmemenizdir. Görüntüleri bir ImageView'a yerleştirin. TextView'larda, görüntüleri ve metinleri birbirine göre nereye koyacağınızı anlamanız için gereken düzen motoru özelliklerinden hiçbiri yoktur. ViewGroups (LinearLayout veya RelativeLayout gibi) değildirler ve bu nedenle yetenekleri belirten dahili düzenleri yoktur. Gerçekten bir web görünümü (ve sahip olduğu tüm güzel düzen motoru şeyleri) kullanmak istemiyorsanız, bireysel TextViews ve ImageView'leri kendiniz nasıl ayarlayacağınızı belirlemeniz gerekecek.


-2
2017-10-24 01:04



WebViews standart altı deneyim oluşturur. İyi bir yerli uygulama yazmaya çalışıyorum. Resimlerimi zaten görüntüledim, sadece kendilerini doğru bir şekilde yerleştirmek için onlara ihtiyacım var. - Nick
Reasponse düzenledim - Kurtis Nusbaum
Bu mantıklı. Görüntüleri filtreleyip ayrı ayrı yapacağım. - Nick
Lütfen oylamayı unutma :) - Kurtis Nusbaum
@Nick Aşağıdaki cevabı seçmelisiniz. Çünkü problemi metin görünümünde çözüyor. Web görüntülemelerini kullanmaya gerek yok. Web ziyaretleri bu amaç için uygun değildir. Ayrıca, web görüntülemeleri, listelemelerde kullanıldığında sorunlu olabilir. - Timuçin


Bozuk parantezinizi c (view) bir textView olarak değiştirebilir ve onPostExecute'unuzu şöyle yapabilirsiniz:

@Override 
protected void onPostExecute(Drawable result) { 
    // set the correct bound according to the result from HTTP call 
    Log.d("height",""+result.getIntrinsicHeight()); 
    Log.d("width",""+result.getIntrinsicWidth()); 
    urlDrawable.setBounds(0, 0, 0+result.getIntrinsicWidth(), 0+result.getIntrinsicHeight());  

    // change the reference of the current drawable to the result 
    // from the HTTP call 
    urlDrawable.drawable = result; 

    // redraw the image by invalidating the container 
    URLImageParser.this.container.invalidate();

    // For ICS
    URLImageParser.this.container.setHeight((URLImageParser.this.container.getHeight() 
    + result.getIntrinsicHeight()));

    // Pre ICS
    URLImageParser.this.textView.setEllipsize(null);
} 

Bu, önce görüntüyü çizecek ve ardından TextView'un yüksekliğini, çekilebilirliğin yüksekliğine + TextViews yüksekliğine ayarlayacaktır.


53
2018-04-18 11:35



Bu mükemmel çalışıyor! Görüntülerin çakıştığı aynı sorun vardı. Bu çözüm ile görüntüler mükemmel bir şekilde görüntülenir! - Siggy
container.setText(container.getText()) ayrıca çalışır (sağlanan kap bir TextView'dir). Bununla birlikte, bir TextView'in yerleşimini yeniden düzenlemenin en iyi yolunun ne olduğunu merak ediyorum. - dcow
Aman Tanrım! Çözümü bulana kadar bu sorunu çözmek için yaklaşık 6 saat harcadım. Şimdi uyuyabilirim. - Nantaphop
setHeight çalışmıyor :( Eclipse setMinimumHeight'ı kullanmasını söyler, ancak bu yardımcı olmaz - Groosha
@ Kondra007 Eğer t tarafından Martin tarafından belirtildiği gibi bir cümle c (görünümü) değiştirmek için teneke tutulması gerekir sonra tutulması setMinimumHeight kullanmanızı istemez - Najeebullah Shah


Martin S için oy vermek için yeterli saygınlığım yok, ama cevabı gerçekten çok yardımcı oldu. Eğer TextView yüklemeden önce varsayılan bir görüntü gösterseydi, setHeight () yöntemini şu şekilde değiştirebiliriz:

    URLImageParser.this.container.setHeight((URLImageParser.this.container.getHeight() 
+ result.getIntrinsicHeight()-mDefaultDrawable.getInstrinsicHeight()));

2
2018-05-06 04:42





View from TextView'den konteyner değiştirmemize gerek olmayabilir.

   @Override
    protected void onPostExecute(Drawable result) {
        // set the correct bound according to the result from HTTP call
        urlDrawable.setBounds(0, 0, 0 + result.getIntrinsicWidth(), 0
                + result.getIntrinsicHeight());

        // change the reference of the current drawable to the result
        // from the HTTP call
        urlDrawable.drawable = result;

        // redraw the image by invalidating the container
        URLImageParser.this.container.setMinimumHeight((URLImageParser.this.container.getHeight()+ result.getIntrinsicHeight()));
        URLImageParser.this.container.requestLayout();
        URLImageParser.this.container.invalidate();
    }

0
2018-03-22 03:03





Bu çözümlerle ilginç bir davranış buldum: Bir görüntünün yüklenmesi hızlıysa ve metin görünümü henüz oluşturulmamışsa (ör. önbelleğe alma ile Okhttp kullanıyorum, böylece ikinci arama oldukça hızlıdır), metin görüntüleme boyutu 0'dır.

Bu sorunu gidermek için, ImageGetter'ı AsyncTask'tan geri döndürdüm ve bunun yerine TextView'um için Spanned'i yaratan ve daha sonra metni ayarlayan bir AsyncTask'ı başlattım.

Bu çözümle, bir Resim her yüklendiğinde TextView'i yeniden boyutlandırmak gerekmez.

new AsyncTask<TextView, Void, Spanned>() {
      TextView tv;
      @Override
      protected Spanned doInBackground(TextView... params) {
        tv = params[0];
        return Html.fromHtml(feedEntry.getContent(),
                new HttpImageGetter(getActivity(), HttpLoaderImpl.getInstance(getActivity())),
                new Html.TagHandler() {

                  @Override
                  public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
                    //do nothing...
                  }
                });
      }

      @Override
      protected void onPostExecute(final Spanned result) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {

          @Override
          public void run() {
            tv.setText(result);
          }
        });
      }
    }.execute(textView);

0
2017-08-22 20:34