来自流动图像的原始文件的文本

时间:2015-03-20 21:15:06

标签: android html stringbuilder spannablestring leadingmarginspan2

这是我的第一个问题。 我正在努力开发一本"书"使用文本和图像,我在显示文本(从原始文件加载)和文本视图中的图像时遇到问题。 我尝试了this,它在字符串资源中定义文本时工作正常。但是,当文本来自外部文件(例如包含断行的.txt文件)时,TextView看起来像这样:

---------  text text text text text 
|       |  text text text text text 
---------  text text text text text 
text text text text 
text text text text
text text text text
text text text text

也就是说,就在图像之后,每一行都向右留下一个空白区域,其大小与图像相同。

我不知道为什么会这样,我错过了什么吗?这是代码:

ImageView page_im_iv = (ImageView) findViewById(R.id.page_image);
TextView page_text = (TextView) findViewById(R.id.page_text);

Drawable page_image getResources().getDrawable(R.drawable.anyname);
page_im_iv.setBackground(page_image);

float left_margin = page_image.getIntrinsicWidth() + 10;
float top_margin = page_image.getIntrinsicHeight() + 10;

float flines = top_margin/page_text.getTextSize();
int ilines = (int) flines;

StringBuilder raw_text = readRaw(this,res_id);//res_id changes dynamically, it is just the name of the .txt file

SpannableString ss = new SpannableString(raw_text.toString());
ss.setSpan(new MyLeadingMarginSpan2(ilines, left_margin), 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

page_text.setText(ss);

这就是布局:

<ScrollView  xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="example.ActivityBookPage"
xmlns:android="http://schemas.android.com/apk/res/android">

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

        <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


          <ImageView
          android:id="@+id/page_image"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"/>


          <TextView
          android:id="@+id/page_text"
          android:layout_width="wrap_content"
          android:layout_height="match_parent"
          android:layout_marginBottom="10dp"/>


      </RelativeLayout>

    <!-- Other stuff 
    ...
    -->
     </LinearLayout>
</ScrollView >

多数人。

如果问题来自readRaw方法,则代码为:

public static StringBuilder readRaw(Context ctx,int res_id) {

        StringBuilder text = new StringBuilder();
        InputStream is = ctx.getResources().openRawResource(res_id);
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr, 8192);

        try {
            String line;
            while ((line = br.readLine()) != null)  {
                text.append(line);
                text.append("\n");

            }
            isr.close();
            is.close();
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return text;
    }

这是MyLeadingMarginSpan2类的代码,从上一个链接复制粘贴

public class MyLeadingMarginSpan2 implements LeadingMarginSpan2 {
    private int margin;
    private int lines;

    public MyLeadingMarginSpan2(int lines, int margin) {
        this.margin = margin;
        this.lines = lines;
    }

    @Override
    public int getLeadingMargin(boolean first) {
        return first ? margin : 0;
    }

    @Override
    public int getLeadingMarginLineCount() {
        return lines;
    }

    @Override
    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, 
            int top, int baseline, int bottom, CharSequence text, 
            int start, int end, boolean first, Layout layout) {}
}

1 个答案:

答案 0 :(得分:0)

最后我找到了一个解决方案(感谢this旧回复)。问题是来自原始文件的文本可能包括断行(\ n),在计算“ilines”时不考虑这些断行。因此,我们需要计算恰好位于图像右侧的字符数,然后包括一个新的折断线,然后是文本的其余部分。这是代码

int charCount = page_text_layout.getLineEnd(Math.min(ilines - 1, page_text_layout.getLineCount() - 1));//see below what page_text_layout is
//in case the image is big enough to have all 
//the text at its right, just use ss.length as 
//the third parameter for setSpan   
if (charCount >= ss.length() || charCount <= 0 ) {
            ss.setSpan(new MyLeadingMarginSpan2(ilines, left_margin), 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                            page_text.setText(ss);                
}  
else { //in case the text is longer, make three blocks
            Spannable s1 = new SpannableStringBuilder(ss, 0, charCount);
            s1.setSpan(new MyLeadingMarginSpan2(ilines, left_margin), 0, charCount, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            Spannable s2 = new SpannableStringBuilder(System.getProperty("line.separator"));
            Spannable s3 = new SpannableStringBuilder(ss, charCount, ss.length());
            page_text.setText(TextUtils.concat(s1, s2, s3));
}

其中page_text_layout先前在onGlobalLayout回调中定义(在我的情况下在onCreate()方法中):

ViewTreeObserver vto = page_text.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
               page_text_layout = page_text.getLayout();  
            }
        });

当然这个代码可以被细化(例如,检查s1是否打破了单词中间的文本),但这将是主要结构。

希望这有助于某人!