Frage Ist es möglich, Inline-Bilder aus HTML in einem Android TextView anzuzeigen?


Angesichts der folgenden HTML:

<p>This is text and this is an image <img src="http://www.example.com/image.jpg" />.</p>

Ist es möglich, das Bild rendern zu lassen? Bei Verwendung dieses Snippets: mContentText.setText(Html.fromHtml(text));Ich bekomme eine Cyan-Box mit schwarzen Rahmen, was mich zu der Annahme bringt, dass ein TextView eine Vorstellung davon hat, was ein img-Tag ist.


75
2018-05-19 12:30


Ursprung


Antworten:


Wenn Sie einen Blick auf die Dokumentation für Html.fromHtml(text) Du wirst sehen, es sagt:

Irgendein <img> Tags im HTML werden als generisches Ersatzbild angezeigt, das Ihr Programm dann durchlaufen und durch echte Bilder ersetzen kann.

Wenn Sie diesen Ersatz nicht selbst durchführen möchten, können Sie ihn verwenden das andere Html.fromHtml() Methode was dauert ein Html.TagHandler und ein Html.ImageGetter als Argumente sowie der zu analysierende Text.

In Ihrem Fall könnten Sie analysieren null Wie für die Html.TagHandler aber Sie müssten Ihre eigenen implementieren Html.ImageGetter da es keine Standardimplementierung gibt.

Das Problem, das Sie haben werden, ist, dass die Html.ImageGetter muss synchron ausgeführt werden, und wenn Sie Bilder aus dem Internet herunterladen, möchten Sie das wahrscheinlich asynchron tun. Wenn Sie Bilder, die Sie als Ressourcen in Ihrer Anwendung anzeigen möchten, hinzufügen ImageGetter Implementierung wird viel einfacher. Du könntest mit etwas wie:

private class ImageGetter implements Html.ImageGetter {

    public Drawable getDrawable(String source) {
        int id;

        if (source.equals("stack.jpg")) {
            id = R.drawable.stack;
        }
        else if (source.equals("overflow.jpg")) {
            id = R.drawable.overflow;
        }
        else {
            return null;
        }

        Drawable d = getResources().getDrawable(id);
        d.setBounds(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight());
        return d;
    }
};

Sie möchten wahrscheinlich etwas intelligenteres herausfinden, um Source-Strings zu Ressourcen-IDs zuzuordnen.


114
2018-05-19 13:35



Ich habe in meiner App eine Referenz von der übernommen pskink.vielen Dank

package com.example.htmltagimg;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LevelListDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.text.Html.ImageGetter;
import android.text.Spanned;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends Activity implements ImageGetter {
private final static String TAG = "TestImageGetter";
private TextView mTv;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    String source = "this is a test of <b>ImageGetter</b> it contains " +
            "two images: <br/>" +
            "<img src=\"http://developer.android.com/assets/images/dac_logo.png\"><br/>and<br/>" +
            "<img src=\"http://www.hdwallpapersimages.com/wp-content/uploads/2014/01/Winter-Tiger-Wild-Cat-Images.jpg\">";
    String imgs="<p><img alt=\"\" src=\"http://images.visitcanberra.com.au/images/canberra_hero_image.jpg\" style=\"height:50px; width:100px\" />Test Article, Test Article, Test Article, Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,v</p>";
    String src="<p><img alt=\"\" src=\"http://stylonica.com/wp-content/uploads/2014/02/Beauty-of-nature-random-4884759-1280-800.jpg\" />Test Attractions Test Attractions Test Attractions Test Attractions</p>";
    String img="<p><img alt=\"\" src=\"/site_media/photos/gallery/75b3fb14-3be6-4d14-88fd-1b9d979e716f.jpg\" style=\"height:508px; width:640px\" />Test Article, Test Article, Test Article, Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,v</p>";
    Spanned spanned = Html.fromHtml(imgs, this, null);
    mTv = (TextView) findViewById(R.id.text);
    mTv.setText(spanned);
}

@Override
public Drawable getDrawable(String source) {
    LevelListDrawable d = new LevelListDrawable();
    Drawable empty = getResources().getDrawable(R.drawable.ic_launcher);
    d.addLevel(0, 0, empty);
    d.setBounds(0, 0, empty.getIntrinsicWidth(), empty.getIntrinsicHeight());

    new LoadImage().execute(source, d);

    return d;
}

class LoadImage extends AsyncTask<Object, Void, Bitmap> {

    private LevelListDrawable mDrawable;

    @Override
    protected Bitmap doInBackground(Object... params) {
        String source = (String) params[0];
        mDrawable = (LevelListDrawable) params[1];
        Log.d(TAG, "doInBackground " + source);
        try {
            InputStream is = new URL(source).openStream();
            return BitmapFactory.decodeStream(is);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        Log.d(TAG, "onPostExecute drawable " + mDrawable);
        Log.d(TAG, "onPostExecute bitmap " + bitmap);
        if (bitmap != null) {
            BitmapDrawable d = new BitmapDrawable(bitmap);
            mDrawable.addLevel(1, 1, d);
            mDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
            mDrawable.setLevel(1);
            // i don't know yet a better way to refresh TextView
            // mTv.invalidate() doesn't work as expected
            CharSequence t = mTv.getText();
            mTv.setText(t);
        }
    }
}
}

Wie unten unter @rpgmaker kommentiert, habe ich diese Antwort hinzugefügt

Ja, du kannst es benutzen ResolveInfo Klasse

Überprüfen Sie, ob Ihre Datei von bereits installierten Apps unterstützt wird oder nicht

unter dem folgenden Code verwenden:

private boolean isSupportedFile(File file) throws PackageManager.NameNotFoundException {
    PackageManager pm = mContext.getPackageManager();
    java.io.File mFile = new java.io.File(file.getFileName());
    Uri data = Uri.fromFile(mFile);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(data, file.getMimeType());
    List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

    if (resolveInfos != null && resolveInfos.size() > 0) {
        Drawable icon = mContext.getPackageManager().getApplicationIcon(resolveInfos.get(0).activityInfo.packageName);
        Glide.with(mContext).load("").placeholder(icon).into(binding.fileAvatar);
        return true;
    } else {
        Glide.with(mContext).load("").placeholder(R.drawable.avatar_defaultworkspace).into(binding.fileAvatar);
        return false;
    }
}

12
2018-02-11 18:25



Dies ist, was ich benutze, die Sie nicht braucht, um Ihre Ressourcennamen zu hardcore und sucht nach den ziehbaren Ressourcen zuerst in Ihren Apps-Ressourcen und dann in den Lager-Android-Ressourcen, wenn nichts gefunden wurde - so dass Sie Standardsymbole und dergleichen verwenden können.

private class ImageGetter implements Html.ImageGetter {

     public Drawable getDrawable(String source) {
        int id;

        id = getResources().getIdentifier(source, "drawable", getPackageName());

        if (id == 0) {
            // the drawable resource wasn't found in our package, maybe it is a stock android drawable?
            id = getResources().getIdentifier(source, "drawable", "android");
        }

        if (id == 0) {
            // prevent a crash if the resource still can't be found
            return null;    
        }
        else {
            Drawable d = getResources().getDrawable(id);
            d.setBounds(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight());
            return d;
        }
     }

 }

Welches kann als solches verwendet werden (Beispiel):

String myHtml = "This will display an image to the right <img src='ic_menu_more' />";
myTextview.setText(Html.fromHtml(myHtml, new ImageGetter(), null);

9
2018-03-10 11:25



Ich hatte das gleiche Problem und habe eine ziemlich saubere Lösung gefunden: Nach Html.fromHtml () können Sie eine AsyncTask ausführen, die über alle Tags iteriert, die Bilder abruft und dann anzeigt.

Hier finden Sie Code, den Sie verwenden können (aber einige Anpassungen benötigen): https://gist.github.com/1190397


5
2017-09-03 02:03



Ich benutzte die Antwort von Dave Webb, vereinfachte sie aber ein wenig. Solange die Ressourcen-IDs während der Laufzeit in Ihrem Anwendungsfall gleich bleiben, ist es nicht wirklich notwendig, Ihre eigene implementierende Klasse zu schreiben Html.ImageGetter und mit Source-Strings herumspielen.

Was ich getan habe, war die Ressourcen-ID als Quell-String:

final String img = String.format("<img src=\"%s\"/>", R.drawable.your_image);
final String html = String.format("Image: %s", img);

und benutze es direkt:

Html.fromHtml(html, new Html.ImageGetter() {
  @Override
  public Drawable getDrawable(final String source) {
    Drawable d = null;
    try {
      d = getResources().getDrawable(Integer.parseInt(source));
      d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
    } catch (Resources.NotFoundException e) {
      Log.e("log_tag", "Image not found. Check the ID.", e);
    } catch (NumberFormatException e) {
      Log.e("log_tag", "Source string not a valid resource ID.", e);
    }

    return d;
  }
}, null);

3
2018-01-17 14:52



Sie könnten auch einen eigenen Parser schreiben, um die URL aller Bilder zu ziehen und dann dynamisch neue Bildansichten zu erstellen und die URLs weiterzuleiten.


1
2018-06-25 04:41



Wenn du den Ersatz selbst machen willst, ist der Charakter, nach dem du suchen musst, [].

Aber wenn Sie Eclipse verwenden, wird es ausflippen, wenn Sie diesen Buchstaben in eine [replace] -Anweisung eingeben, die Ihnen mit Cp1252 widerspricht - dies ist ein Eclipse-Fehler. Um es zu beheben, gehen Sie zu

Fenster -> Einstellungen -> Allgemein -> Arbeitsbereich -> Textdateikodierung,

und wählen Sie [UTF-8]


1
2018-06-25 04:20