zoukankan      html  css  js  c++  java
  • Snippet: align a TextView around an image

    A few weeks ago I discovered the Spans on Android,after reading the wonderful post by Flavien Laurent.

    In this post I will describe how to realize a particular layout not very common on Android: a text around an image.

    This layout is not an Android Pattern, but it can be useful in same cases.
    As always it is just an example, and you should improve some points in your real project.

    Use a simple layout:

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    
                <TextView
                    android:id="@+id/text"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"></TextView>
    
                <ImageView
                    android:id="@+id/icon"
                    android:src="@drawable/rectangle"
                    android:layout_width="150dp"
                    android:layout_height="150dp"></ImageView>
    
            </RelativeLayout>
    
        </ScrollView>

    To achieve our scope, we can use a LeadingMarginSpan.LeadingMarginSpan2.
    This span allows the implementor to specify the number of lines of text to which this object is attached that the "first line of paragraph" margin width will be applied to.

        /**
         *
         */
        class MyLeadingMarginSpan2 implements LeadingMarginSpan.LeadingMarginSpan2 {
    
            private int margin;
            private int lines;
    
            MyLeadingMarginSpan2(int lines, int margin) {
                this.margin = margin;
                this.lines = lines;
            }
    
            /**
             * Apply the margin
             *
             * @param first
             * @return
             */
            @Override
            public int getLeadingMargin(boolean first) {
                if (first) {
                    return margin;
                } else {
                    return 0;
                }
            }
    
            @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) {}
    
    
            @Override
            public int getLeadingMarginLineCount() {
                return lines;
            }
        };

    We only need to calculate the number of lines where we would like applying a margin and the right margin.
    In this case we will get number of lines = height of image and margin = width of image + little extra margin. 

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mTextView = (TextView) findViewById(R.id.text);
            mImageView = (ImageView) findViewById(R.id.icon);
    
    
            final ViewTreeObserver vto = mImageView.getViewTreeObserver();
            vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    mImageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    finalHeight = mImageView.getMeasuredHeight();
                    finalWidth = mImageView.getMeasuredWidth();
                    makeSpan();
                }
            });
        }
    }

    This code can be improved.
    I am using a very simple (and raw) float textLineHeight = mTextView.getPaint().getTextSize(); to calculate the number of lines.
    You can add paddings, margins or you can use a Rect to calculate the text bounds.

        /**
         * This method builds the text layout
         */
        private void makeSpan() {
    
            /**
             * Get the text
             */
            String plainText=getResources().getString(R.string.text_sample);
            
    
            int allTextStart = 0;
            int allTextEnd = htmlText.length() - 1;
    
            /**
             * Calculate the lines number = image height.
             * You can improve it... it is just an example
             */
            int lines;
            Rect bounds = new Rect();
            mTextView.getPaint().getTextBounds(plainText.substring(0,10), 0, 1, bounds);
    
            //float textLineHeight = mTextView.getPaint().getTextSize();
            float fontSpacing=mTextView.getPaint().getFontSpacing();
            lines = (int) (finalHeight/fontSpacing);
    
            /**
             * Build the layout with LeadingMarginSpan2
             */
            MyLeadingMarginSpan2 span = new MyLeadingMarginSpan2(lines, finalWidth +10 );
            mSpannableString.setSpan(span, allTextStart, allTextEnd,
                       Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    
            mTextView.setText(mSpannableString);
        }


    You can get code from GitHub:

  • 相关阅读:
    iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流
    iOS开发之窥探UICollectionViewController(二) --详解CollectionView各种回调
    iOS开发之窥探UICollectionViewController(一) -- Ready Your CollectionViewController
    iOS开发之SQLite--C语言接口规范(五)——iOS开发使用SQLite实例
    iOS开发之SQLite--C语言接口规范(四) —— Result Values From A Query
    iOS开发之SQLite--C语言接口规范(三)——Binding Values To Prepared Statements
    iOS开发之SQLite-C语言接口规范(二) —— Prepared Your SQL Statements
    iOS开发之SQLite-C语言接口规范(一)——Ready And Open Your SQLite
    iOS开发之ImageView复用实现图片无限轮播
    iOS开发之多图片无缝滚动组件封装与使用
  • 原文地址:https://www.cnblogs.com/tt_mc/p/4281752.html
Copyright © 2011-2022 走看看