如何用Android中的网址中的图片替换文字?

时间:2016-07-14 15:53:43

标签: java android json textview imageview

我有一个在线阅读json文件的应用程序,其格式如下:

       {
            "title":"Title",
            "introParagraph":"Text for introParagraph",
            "heading1":"Text for heading1",
            "paragraph1":"Text for paragraph1 \n\n image1"
            "heading2":"Text for heading2",
            "paragraph2":"Text for paragraph2 \n\n image2"
            "image1":"http://url.for.image1",
            "image2":"http://url.for.image2",
        },

为简单起见,我缩短了json。每个json对象最多可以有7个标题和段落以及5个图像,尽管它们都没有这个,有些没有任何图像。

我试图找到一种方法来检查是否有任何段落包含文字" image1"," image2"," image3"如果是这样的话,用与该密钥相关的网址中的图像替换它。

我发现了类似的问题,例如How to replace String with an image inside an EditText?,但是它显示了如何用可绘制的文本替换文本而不是从网址中替换图像(我使用毕加索使这更容易但我仍然不知道如何替换文字。

我的布局文件如下所示:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">

    <LinearLayout android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="300dp">

            <TextView
                android:id="@+id/wiki_header_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

        </RelativeLayout>

        <TextView
            android:id="@+id/wiki_intro_paragraph"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:id="@+id/wiki_heading1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:id="@+id/wiki_paragraph1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:id="@+id/wiki_heading2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:id="@+id/wiki_paragraph2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>

</ScrollView>

只需更多格式,标题和段落最多为7。

我无法将imageViews放入我的布局文件中,因为我不知道是否会有来自json的图像或者要更换的文本将出现在json中,即有时候&#34 ; image1的&#34;文本位于段落文本的中间,有时&#34; image1&#34;在&#34;段1和#34;有时它在&#34;段7和#34;等

任何帮助都将不胜感激。

更新:根据以下答案,我现在正在使用此代码:

private WikiItem mWikiItem;
private TextView mHeading1;
private TextView mParagraph1;
private Drawable image0;

@Override
protected void onCreate(Bundle savedInstanceBundle) {
    super.onCreate(savedInstanceBundle);

    mHeading1 = (TextView) findViewById(R.id.wiki_heading1);
    mParagraph1 = (TextView) findViewById(R.id.wiki_paragraph1);

    if (!(mWikiItem.getHeading1() == null)) {
        mHeading1.setText(mWikiItem.getHeading1());
        mParagraph1.setText(mWikiItem.getParagraph1());
    } else {
        mHeading1.setVisibility(View.GONE);
        mParagraph1.setVisibility(View.GONE);
    }

    if (!(mWikiItem.getImage0() == null)) {
        Picasso.with(this)
                .load(Uri.parse(mWikiItem.getImage0()))
                .into(new Target() {
                    @Override
                    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                        image0 = new BitmapDrawable(getResources(), bitmap);
                    }

                    @Override
                    public void onBitmapFailed(Drawable errorDrawable) {

                    }

                    @Override
                    public void onPrepareLoad(Drawable placeHolderDrawable) {

                    }
                });

        ImageSpan span;
        String abc = mParagraph1.getText().toString();
        SpannableString ss = new SpannableString(abc);
        for(int i = 0; i<abc.length();i++){//loop to check presence of other emoji strings.
            if (abc.contains("image0")){
                int startSpan = abc.indexOf("image0");
                image0.setBounds(0, 0, image0.getIntrinsicWidth(), image0.getIntrinsicHeight());
                span = new ImageSpan(image0, ImageSpan.ALIGN_BASELINE);
                ss.setSpan(span, startSpan, startSpan+2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
                abc = abc.replaceFirst("image0","  "); //replace with two blank spaces.
            }
            //to check other types of emoji, use else if ladder and place the similar code.
        }
        mParagraph1.append(ss);
    }
}

但是我一直在drawable&#34; image0&#34;

上出现空指针错误
java.lang.RuntimeException: Unable to start activity ComponentInfo{xyz.jameslester.cryptozoologytoday/xyz.jameslester.cryptozoologytoday.WikiSection.WikiDetailActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.drawable.Drawable.getIntrinsicWidth()' on a null object reference

我无法找出原因。

更新2:似乎修复它的方法是将代码放在内部方法的末尾&#34; onBitmapLoaded&#34;:

Picasso.with(this)
       .load(uri2)
       .into(new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                Drawable image0 = new BitmapDrawable(getResources(), bitmap);

                ImageSpan span;
                String abc = mParagraph1.getText().toString();
                SpannableString ss = new SpannableString(abc);

                for(int i = 0; i<abc.length();i++){//loop to check presence of other emoji strings.
                    if (abc.contains("image0")){
                        int startSpan = abc.indexOf("image0");
                        image0.setBounds(0, 0, image0.getIntrinsicWidth(), image0.getIntrinsicHeight());
                        span = new ImageSpan(image0, ImageSpan.ALIGN_BASELINE);
                        ss.setSpan(span, startSpan, startSpan+2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
                        abc = abc.replaceFirst("image0","  "); //replace with two blank spaces.
                    }

                }
                mParagraph1.append(ss);
            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }
        });

2 个答案:

答案 0 :(得分:0)

从位图创建drawable:

Drawable drawable;
Picasso.with(this)
   .load("youUrl")
   .into(new Target() {
       @Override
       public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
          drawable = new BitmapDrawable(getResources(), bitmap);
       }

       @Override
       public void onBitmapFailed(Drawable errorDrawable) {

       }

       @Override
       public void onPrepareLoad(Drawable placeHolderDrawable) {

       }
   });

然后像你提供的链接一样使用它。

答案 1 :(得分:0)

如果您希望图片与文本视图分开,则需要在textview上设置drawable。一个快速而肮脏的例子是:

TextView txt = (TextView) findViewById(R.id.textview);
Drawable bitmapDrawable = new BitmapDrawable(getResources(), YOURBITMAP FROM PICASSO);
txt.setCompoundDrawablesWithIntrinsicBounds(bitmapDrawable, 0, 0, 0);

drawable可以放在你想要的任何位置。

void setCompoundDrawablesWithIntrinsicBounds (int left, 
            int top, 
            int right, 
            int bottom)

所以基本上是从毕加索创建你的BITMAP。将其转换为drawable,然后在TextView上设置CompoundDrawable,这样您就可以将图像放在任何需要的位置。

资源:https://developer.android.com/reference/android/widget/TextView.html#setCompoundDrawablesWithIntrinsicBounds%28int,%20int,%20int,%20int%29

修改 好吧所以这里是一个更“完整”的例子,说明你将如何做到这一点。首先,我们从毕加索创建我们的drawable,然后将文本和图像设置为我们想要的任何地方。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    txt = (TextView)findViewById(R.id.txt);

    //Load our image with Picasso.
    Picasso.with(this)
            .load(imgUrl)
            .into(new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    //create a drawable from the bitmap. 
                    d = new BitmapDrawable(getResources(), bitmap);

                    //set the main text of the textview. 
                    txt.setText(p1);

                    //now we set the image drawable to the right (left, top, right, bottom)
                    txt.setCompoundDrawablesWithIntrinsicBounds(null, null, d, null);
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {

                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {

                }
            });
}

<强>结果

enter image description here