কোনও অ্যান্ড্রয়েড টেক্সটভিউতে এইচটিএমএল থেকে ইনলাইন চিত্রগুলি প্রদর্শন করা কি সম্ভব?


87

নিম্নলিখিত এইচটিএমএল দেওয়া হয়েছে:

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

চিত্রটি রেন্ডার করা কি সম্ভব? এই স্নিপেটটি ব্যবহার করার সময়:, mContentText.setText(Html.fromHtml(text));আমি কালো সীমানা সহ একটি সায়ান বাক্স পেয়েছি, এটি আমাকে বিশ্বাস করতে পরিচালিত করে যে কোনও টেক্সটভিউয়ের একটি আইএমজি ট্যাগ কী তা সম্পর্কে কিছু ধারণা রয়েছে।


4
আমার পোস্টটি দেখুন javatechig.com javatechig.com/2013/04/07/how-to-display-html-in-android-view
নীলাঞ্চল

উত্তর:


126

আপনার যদি ডকুমেন্টেশনটিরHtml.fromHtml(text) দিকে নজর রাখেন তবে আপনি এটি দেখতে পাবেন:

কোন <img>HTML এ ট্যাগ একটি জেনেরিক প্রতিস্থাপন ইমেজ যা আপনার প্রোগ্রাম তারপর মধ্য দিয়ে যেতে এবং বাস্তব চিত্র প্রতিস্থাপন করতে পারেন হিসাবে প্রদর্শন করা হবে।

আপনি যদি এই প্রতিস্থাপনটি নিজে করতে না চান তবে আপনি অন্যান্য Html.fromHtml()পদ্ধতিটি ব্যবহার করতে পারেন যা একটি Html.TagHandlerএবং একটি Html.ImageGetterআর্গুমেন্ট হিসাবে লাগে পাশাপাশি পাঠ্যকে বিশ্লেষণ করতে পারে।

আপনার যদি আপনি পার্স পারে nullহিসাবে জন্য Html.TagHandlerকিন্তু আপনি আপনার নিজের বাস্তবায়ন প্রয়োজন চাই Html.ImageGetterসেখানে একটি ডিফল্ট বাস্তবায়ন নয়।

যাইহোক, আপনি যে সমস্যাটি করতে যাচ্ছেন তা হ'ল Html.ImageGetterসিঙ্ক্রোনালি চালানো দরকার এবং আপনি যদি ওয়েব থেকে চিত্রগুলি ডাউনলোড করেন তবে আপনি সম্ভবত এটি অবিচ্ছিন্নভাবে করতে চাইবেন। আপনি যদি আপনার প্রয়োগের উত্স হিসাবে প্রদর্শিত কোনও চিত্র যুক্ত করতে পারেন তবে আপনার ImageGetterপ্রয়োগ অনেক সহজ হয়ে যায়। আপনি যেমন কিছু দিয়ে পালাতে পারেন:

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

যদিও আপনি রিসোর্স আইডিগুলিতে উত্সের স্ট্রিংগুলি ম্যাপিংয়ের জন্য আরও কিছু স্মার্ট কিছু বের করতে চান।


4
ঠিক আছে. আমি এটির পরিবর্তে কেবল একটি ওয়েবভিউ ব্যবহার করা সহজ ছিল বলে মনে করি। যদিও আপনার কৌশলটি অন্যান্য অনুরূপ দৃশ্যের জন্য দরকারী হয়ে উঠছে তা আমি দেখতে পাচ্ছি। ধন্যবাদ!
গুনার লিমিয়াম

4
নাম থেকে রিসোর্স আইডি নেওয়ার স্মার্ট উপায় হ'ল রিসোর্স.জেটআইডিটিফায়ার (স্ট্রিং নাম, স্ট্রিং ডিফটাইপ, স্ট্রিং ডিপপ্যাকেজ) ব্যবহার করা।
টিমুইন

@ গুন্নার লিয়াম ... তবে আই 8 চিত্র ওয়েব ভিউতে দেখানো হচ্ছে না .. !! কোন সাহায্য ??
কেজিঅ্যান্ড্রয়েড

ছবিটি যদি কোনও সার্ভারে থাকে তবে আমরা কীভাবে চিত্রটি পেতে পারি… আমার ক্ষেত্রে চিত্রটি গতিশীল ... আমি অন্য চিত্রের দৃষ্টিভঙ্গি ব্যবহার করতে পারি না কারণ এটি নিশ্চিত নয় যে কোনও চিত্র থাকতে হবে ...
সৌরভ রায় ২

19

আমি আমার অ্যাপ্লিকেশনটিতে প্রয়োগ করেছি, পিএসকিঙ্ক থেকে রেফারেস নিয়েছি। অনেক ধন্যবাদ

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);
        }
    }
}
}

নীচে @rpgmaker মন্তব্য অনুসারে আমি এই উত্তরটি যুক্ত করেছি

হ্যাঁ আপনি রেজলভইনফো ক্লাস ব্যবহার করে করতে পারেন

আপনার ফাইলটি ইতিমধ্যে ইনস্টল থাকা অ্যাপ্লিকেশনগুলি সমর্থন করে কিনা তা পরীক্ষা করুন

নীচে কোড ব্যবহার:

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

4
আরে, "অ্যাডলেভেল" এবং "সেটলেভিল" এর উদ্দেশ্য কী?
আইইফায়ার

চিত্রগুলি কেন্দ্রীভূত করার কোনও উপায় আছে? এটি যদি ভাল হয় তবে আমরা সেগুলি ট্যাপ করতে পারি এবং আমরা ইনস্টল করে থাকা যেকোনো চিত্র দর্শকের অ্যাপ্লিকেশনটিতে সেগুলি প্রদর্শন করতে পারি।
আকাঙ্ক্ষিত দেব

আমি মনে করি আপনি আমার প্রশ্নের প্রসঙ্গটি ভুলে গেছেন। আমি জানি কীভাবে একটি চিত্র দর্শকের অ্যাপ্লিকেশন সহ কোনও চিত্র ফাইল খুলতে হয় তবে আপনার উত্তরটি একটি টেক্সটভিউয়ের মধ্যে বিটম্যাপগুলি রাখে এবং যতদূর আমি বলতে পারি যে কোনও ব্যবহারকারী যখন এর অভ্যন্তরে একটি নির্দিষ্ট চিত্রটি ট্যাপ করছেন তখন তা বোঝার কোনও উপায় নেই। আপনার যদি পাঠ্যদর্শনটির ভিতরে অনেকগুলি চিত্র থাকে তবে এটি একটি সমস্যা। এই কাজ করতে একটি উপায় আছে কি?
আকাঙ্ক্ষিত দেব

তবে একটি বিষয় হ'ল এটি খুব ধীরে ধীরে স্ক্রোল করে, আমরা কি সে সম্পর্কে কিছু করতে পারি?
প্রতীক জামারিয়া

মসৃণ স্ক্রোল শ্রোতাদের যুক্ত করার চেষ্টা করুন
madhu527

16

এটি আমি ব্যবহার করি যা আপনার সংস্থানগুলির নামগুলি কঠোর করার দরকার নেই এবং প্রথমে আপনার অ্যাপ্লিকেশন সংস্থানগুলিতে এবং এরপরে স্টক অ্যান্ড্রয়েড সংস্থানগুলিতে ড্রয়যোগ্য সংস্থানগুলির সন্ধান করবে - আপনাকে ডিফল্ট আইকন এবং এ জাতীয় ব্যবহার করার অনুমতি দেয়।

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

 }

যা ব্যবহার করা যেতে পারে (উদাহরণস্বরূপ):

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

এই সংমিশ্রণটি AsyncTask ইন্টারনেট পুনরুদ্ধারের সাথে নিখুঁত হবে।
ফ্রান্সিস রদ্রিগেস

4
ধন্যবাদ! এটি আমার সমস্যার সমাধান করেছে। আমার কেবল স্থানীয় চিত্রের প্রয়োজন, তাই এটিকে কেবল অঙ্কনযোগ্য ফোল্ডারে রেখে দিন এবং এইচটিএমএল থেকে কল করার সময় চিত্রের উপস্থিতি অপসারণের বিষয়টি নিশ্চিত করুন।
ডডি রছমত উইকাকসনো

ধন্যবাদ! তবে সাবধান থাকুন sourceশূন্য হতে পারে getIdentifier()এবং এই ক্ষেত্রে ক্র্যাশ হতে পারে । সুস্পষ্ট চেক যুক্ত করা ভাল।
gmk57

5

আমি একই সমস্যার মুখোমুখি হয়েছি এবং একটি সুন্দর পরিষ্কার সমাধান পেয়েছি: এইচটিএমএল.ফ্রমএইচটিএমএল () এর পরে আপনি একটি অ্যাসিঙ্কটাস্ক চালাতে পারেন যা সমস্ত ট্যাগের উপরে পুনরাবৃত্তি করে, চিত্রগুলি আনে এবং তারপরে সেগুলি প্রদর্শন করে।

আপনি এখানে ব্যবহার করতে পারেন এমন কিছু কোড খুঁজে পেতে পারেন (তবে এটির জন্য কিছু স্বনির্ধারণ প্রয়োজন): https://gist.github.com/1190397


3

আমি ডেভ ওয়েবের উত্তরটি ব্যবহার করেছি তবে এটি কিছুটা সরল করে তুলেছি। আপনার ব্যবহারের ক্ষেত্রে রানটাইম চলাকালীন যতক্ষণ রিসোর্স আইডি একই থাকবে ততক্ষণ আপনার নিজস্ব ক্লাস বাস্তবায়ন Html.ImageGetterএবং উত্স-স্ট্রিংগুলির সাথে জগাখিচুড়ি লিখার দরকার নেই ।

আমি যা করেছি তা হ'ল উত্স আইডিটি উত্স-স্ট্রিং হিসাবে ব্যবহার করা হয়েছিল:

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

এবং এটি সরাসরি ব্যবহার করুন:

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);

1

আপনি সমস্ত চিত্রের ইউআরএল টানতে নিজের পার্সার লিখতে পারেন এবং তারপরে গতিশীলভাবে নতুন চিত্রদর্শন তৈরি করতে এবং urlগুলিতে পাস করতে পারেন।


1

এছাড়াও, আপনি যদি প্রতিস্থাপনটি নিজে করতে চান তবে আপনার যে চরিত্রটি সন্ধান করা উচিত তা হ'ল []।

তবে আপনি যদি Eclipse ব্যবহার করছেন, আপনি যখন চিঠিটি [প্রতিস্থাপন] বিবৃতিতে টাইপ করবেন তখন এটি সিপ 1252 এর সাথে সাংঘর্ষিক হবে - এটি একটি Eclipse বাগ ip এটি ঠিক করতে, এখানে যান

উইন্ডো -> পছন্দসমূহ -> সাধারণ -> কর্মক্ষেত্র -> পাঠ্য ফাইল এনকোডিং,

এবং নির্বাচন করুন [UTF-8]


1

কোটলিন

ব্যবহার করার সম্ভাবনাও রয়েছে sufficientlysecure.htmltextview.HtmlTextView

গ্রেড ফাইলগুলিতে নীচের মত ব্যবহার করুন:

প্রকল্প গ্রেড ফাইল:

repositories {
    jcenter()
}

অ্যাপ গ্রেড ফাইল:

dependencies {
implementation 'org.sufficientlysecure:html-textview:3.9'
}

এক্সএমএল ফাইলের অভ্যন্তরে আপনার পাঠ্য ভিউ এর সাথে প্রতিস্থাপন করুন:

<org.sufficientlysecure.htmltextview.HtmlTextView
      android:id="@+id/allNewsBlockTextView"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_margin="2dp"
      android:textColor="#000"
      android:textSize="18sp"
      app:htmlToString="@{detailsViewModel.selectedText}" />

উপরের শেষ লাইনটি হ'ল আপনি যদি বাইন্ডিং অ্যাডাপ্টার ব্যবহার করেন তবে কোডটি এর মতো হবে:

@BindingAdapter("htmlToString")
fun bindTextViewHtml(textView: HtmlTextView, htmlValue: String) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    textView.setHtml(
        htmlValue,
        HtmlHttpImageGetter(textView, "n", true)
    );
    } else {
        textView.setHtml(
        htmlValue,
        HtmlHttpImageGetter(textView, "n", true)
        );
    }
}

গিথুব পৃষ্ঠা থেকে আরও তথ্য এবং একটি বড় লেখক আপনাকে ধন্যবাদ !!!!!


0

যদি কেউ মনে করেন যে সংস্থানগুলি অবশ্যই ঘোষণামূলক হতে হবে এবং একাধিক ভাষার জন্য স্প্যানিয়েবল ব্যবহার করা গোলযোগ, আমি কিছু কাস্টম ভিউ করেছি

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.Html.ImageGetter;
import android.text.Spanned;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * XXX does not support android:drawable, only current app packaged icons
 *
 * Use it with strings like <string name="text"><![CDATA[Some text <img src="some_image"></img> with image in between]]></string>
 * assuming there is @drawable/some_image in project files
 *
 * Must be accompanied by styleable
 * <declare-styleable name="HtmlTextView">
 *    <attr name="android:text" />
 * </declare-styleable>
 */

public class HtmlTextView extends TextView {

    public HtmlTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HtmlTextView);
        String html = context.getResources().getString(typedArray.getResourceId(R.styleable.HtmlTextView_android_text, 0));
        typedArray.recycle();

        Spanned spannedFromHtml = Html.fromHtml(html, new DrawableImageGetter(), null);
        setText(spannedFromHtml);
    }

    private class DrawableImageGetter implements ImageGetter {
        @Override
        public Drawable getDrawable(String source) {
            Resources res = getResources();
            int drawableId = res.getIdentifier(source, "drawable", getContext().getPackageName());
            Drawable drawable = res.getDrawable(drawableId, getContext().getTheme());

            int size = (int) getTextSize();
            int width = size;
            int height = size;

//            int width = drawable.getIntrinsicWidth();
//            int height = drawable.getIntrinsicHeight();

            drawable.setBounds(0, 0, width, height);
            return drawable;
        }
    }
}

https://gist.github.com/logcat/64234419a935f1effc67 এ আপডেটগুলি ট্র্যাক করুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.