2014-09-30 2 views
4

다음은 question에 따라 이미지 주위에 텍스트를 넣을 수있었습니다. 그러나, 나는 다음과 같은 문제가 있습니다. 이미지 주위의 Android 텍스트 버그

enter image description here

당신이 볼 수 있듯이

은 상단에 이미지의 공간은 오른쪽에있는 모든 단락에 표시됩니다. 질문에 누군가가이 문제가 있었고 '줄'에 대해 'ss.length()'를 변경하도록 제안했습니다. 이것은 첫 단락이 너무 짧다면 다음 단락이 이미지와 겹칠 경우를 제외하고는 효과가있는 것으로 보입니다.

Html의 텍스트를 사용하기 위해 FlowTextHelper 클래스를 약간 수정했습니다. 이것은 내가 사용하고있는 코드입니다 :

public class FlowTextHelper { 
    private static boolean mNewClassAvailable; 

    /* class initialization fails when this throws an exception */ 
    static { 
     try { 
      Class.forName("android.text.style.LeadingMarginSpan$LeadingMarginSpan2"); 
      mNewClassAvailable = true; 
     } catch (Exception ex) { 
      mNewClassAvailable = false; 
     } 
    } 

    public static void tryFlowText(String text, View thumbnailView, TextView messageView, Display display, int addPadding){ 
     // There is nothing I can do for older versions, so just return 
     if(!mNewClassAvailable) return; 

     // Get height and width of the image and height of the text line 
     thumbnailView.measure(display.getWidth(), display.getHeight()); 
     int height = thumbnailView.getMeasuredHeight(); 
     int width = thumbnailView.getMeasuredWidth() + addPadding; 
     messageView.measure(width, height); //to allow getTotalPaddingTop 
     int padding = messageView.getTotalPaddingTop(); 
     float textLineHeight = messageView.getPaint().getTextSize(); 

     // Set the span according to the number of lines and width of the image 
     int lines = (int)Math.round((height - padding)/textLineHeight); 
     //SpannableString ss = new SpannableString(text); 
     //For an html text you can use this line: 
     if(!text.equals("")) { 
      SpannableStringBuilder ss = (SpannableStringBuilder) Html.fromHtml(text); 
      ss.setSpan(new MyLeadingMarginSpan2(lines, width), 0, ss.length(), 0); 
      messageView.setText(ss); 
      messageView.setMovementMethod(LinkMovementMethod.getInstance()); // links 

      // Align the text with the image by removing the rule that the text is to the right of the image 
      RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) messageView.getLayoutParams(); 
      int[] rules = params.getRules(); 
      rules[RelativeLayout.RIGHT_OF] = 0; 
     } 
    } 
} 

public class MyLeadingMarginSpan2 implements LeadingMarginSpan.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) {} 
} 

모든 단락이 반복되는 이유는 무엇이며 어떻게 제거 할 수 있습니까? 어떤 도움을 주셔서 감사합니다.

+0

이 문제가 발생하는 이유가 궁금한 분은 https://code.google.com/p/에있는 버그입니다. android/issues/detail? id = 38003 – Parker

답변

4

: text wrapping around image in android

는 기본적으로 다음과 같이

먼저 당신의 텍스트 뷰에 마진을 추가하고 텍스트를 설정

final RelativeLayout.LayoutParams params = RelativeLayout.LayoutParams)messageView.getLayoutParams(); 
params.setMargins(marginWidth, 0, 0, 0); 
messageView.setText(Html.fromHtml(text)); 

그런 다음 OnGlobalLayoutListener를 추가하고 onGlobalLayout() 호출에서 실제로 여백이 필요한 행 수를 계산합니다. 두 개의 분리 된 줄에 줄을 나누고 첫 번째 줄에만 여백을 추가하십시오.

 messageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 

      @SuppressLint("NewApi") 
      @SuppressWarnings("deprecation") 
      @Override 
      public void onGlobalLayout() { 

       int linesCount = messageView.getLayout().getLineCount(); 
       // restore the margin 
       params.setMargins(0, 0, 0, 0); 
       SpannableString spanS = new SpannableString (Html.fromHtml(text)); 

       if (linesCount <= lines) { 
        spanS.setSpan(new MyLeadingMarginSpan2(lines, width), 0, spanS.length(), 0); 
        messageView.setText(spanS); 
       } else { 
        // find the breakpoint where to break the String. 
        int breakpoint = messageView.getLayout().getLineEnd(lines-1); 

        Spannable s1 = new SpannableStringBuilder(spanS, 0, breakpoint); 
        s1.setSpan(new MyLeadingMarginSpan2(lines, width), 0, s1.length(), 0); 
        Spannable s2 = new SpannableStringBuilder(System.getProperty("line.separator")); 
        Spannable s3 = new SpannableStringBuilder(spanS, breakpoint, spanS.length()); 
        // It is needed to set a zero-margin span on for the text under the image to prevent the space on the right! 
        s3.setSpan(new MyLeadingMarginSpan2(0, 0), 0, s3.length(), 0); 
        messageView.setText(TextUtils.concat(s1, s2, s3)); 
       } 

       // remove the GlobalLayoutListener 
       if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { 
        messageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);       
       } else { 
        messageView.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
       } 
      } 
     }); 
+0

멋지군요. 이 문제로 돌아갈 기회가 있다면, 나는 그것을 시도 할 것이다. – apSTRK

+1

marginWidth 란 무엇입니까? – Umesh

+0

안녕하세요, 어디에 OnGlobalLayoutListener를 추가하셨습니까? FlowTextHelper에 있습니까? –

0

이미지 주위에 텍스트를 줄이려는 경우이 라이브러리 FlowTextView을 사용하십시오.

라이브러리의 성능이 뛰어나며 몇 줄으로 사용할 수 있습니다. 그러나 글꼴의 화면 픽셀 크기는 지원하지 않습니다. 이 answer으로 해결 방법을 찾았으므로 픽셀 크기를 sp로 변환 할 수 있습니다.

나는 이것이 도움이 되었으면 좋겠다. 나는 원래 게시물의 질문을 사용하면서 나만큼 많은 시간을 낭비하지 않기를 바란다. 나는이 문제를 해결하기 위해 시간을 소비했지만, 여기에있는 답변 덕분에 그것을 해결