Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/197.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何将视图与TextView内的文本垂直对齐?_Android_Textview_Imageview_Android Constraintlayout_Autoresize - Fatal编程技术网

Android 如何将视图与TextView内的文本垂直对齐?

Android 如何将视图与TextView内的文本垂直对齐?,android,textview,imageview,android-constraintlayout,autoresize,Android,Textview,Imageview,Android Constraintlayout,Autoresize,我正在努力实现这个结果: 我现在拥有的是ConstraintLayout,它包括三个视图:文本视图,图像视图,图像视图 设计要求: 文本居中于TextView TextView具有固定大小的80dp 文本大小应为自动调整大小 图像视图应根据文本在文本视图中的位置水平变化。请参见案例#1/#2中的图像以供参考 是否可以用XML实现第4项?如何通过编程实现 [其他信息] 自动调整大小在宽度包裹内容时无法正常工作,请参阅: 注意:如果在XML文件中设置了自动调整大小,则不建议对XML文件的layou

我正在努力实现这个结果:

我现在拥有的是
ConstraintLayout
,它包括三个
视图
文本视图
图像视图
图像视图

设计要求:

  • 文本居中于
    TextView
  • TextView
    具有固定大小的80dp
  • 文本大小应为自动调整大小
  • 图像视图
    应根据文本在
    文本视图
    中的位置水平变化。请参见案例#1/#2中的图像以供参考
  • 是否可以用XML实现第4项?如何通过编程实现

    [其他信息]

    自动调整大小在宽度
    包裹内容时无法正常工作,请参阅:

    注意:如果在XML文件中设置了自动调整大小,则不建议对XML文件的
    layout\u width
    layout\u height
    属性使用值“wrap\u content”。它可能会产生意想不到的结果


    因此,经过调查,我们找到了两种解决方案:

    • 计算文本宽度并将水平偏差应用于
      ImageView
      s
    • 自定义文本视图-
      自动ResizeTextView
    第一种情况下,我们在
    文本视图中获得文本的实际
    宽度

    Rect bounds = new Rect();
    textView.getPaint().getTextBounds(textView.getText().toString(), 0, textView.getText().length(), bounds);
    float width = bounds.width();
    
    然后应用简单的数学计算
    图像视图
    s的
    水平偏差

    第二个选项是添加自定义视图。它不同于。在
    onLayout
    中测量后,它将调整文本大小。在
    onTextChanged
    中,我们重置文本大小而不调整大小。省略它是一个附加功能,在某些情况下可能有用

    /**
     * Text view that auto adjusts text size to fit within the view.
     * If the text size equals the minimum text size and still does not
     * fit, append with an ellipsis.
     */
    public class AutoResizeTextView extends android.support.v7.widget.AppCompatTextView {
    
        // Minimum text size for this text view
        public static final float MIN_TEXT_SIZE = 20;
    
        // Interface for resize notifications
        public interface OnTextResizeListener {
            public void onTextResize(TextView textView, float oldSize, float newSize);
        }
    
        // Our ellipse string
        private static final String mEllipsis = "...";
    
        // Registered resize listener
        private OnTextResizeListener mTextResizeListener;
    
        // Flag for text and/or size changes to force a resize
        private boolean mNeedsResize = false;
    
        // Text size that is set from code. This acts as a starting point for resizing
        private float mTextSize;
    
        // Temporary upper bounds on the starting text size
        private float mMaxTextSize = 0;
    
        // Lower bounds for text size
        private float mMinTextSize = MIN_TEXT_SIZE;
    
        // Text view line spacing multiplier
        private float mSpacingMult = 1.0f;
    
        // Text view additional line spacing
        private float mSpacingAdd = 0.0f;
    
        // Add ellipsis to text that overflows at the smallest text size
        private boolean mAddEllipsis = true;
    
        // Default constructor override
        public AutoResizeTextView(Context context) {
            this(context, null);
        }
    
        // Default constructor when inflating from XML file
        public AutoResizeTextView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        // Default constructor override
        public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            mTextSize = getTextSize();
        }
    
        /**
         * When text changes, set the force resize flag to true and reset the text size.
         */
        @Override
        protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
            mNeedsResize = true;
            // Since this view may be reused, it is good to reset the text size
            resetTextSize();
        }
    
        /**
         * If the text view size changed, set the force resize flag to true
         */
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            if (w != oldw || h != oldh) {
                mNeedsResize = true;
            }
        }
    
        /**
         * Register listener to receive resize notifications
         *
         * @param listener
         */
        public void setOnResizeListener(AutoResizeTextView.OnTextResizeListener listener) {
            mTextResizeListener = listener;
        }
    
        /**
         * Override the set text size to update our internal reference values
         */
        @Override
        public void setTextSize(float size) {
            super.setTextSize(size);
            mTextSize = getTextSize();
        }
    
        /**
         * Override the set text size to update our internal reference values
         */
        @Override
        public void setTextSize(int unit, float size) {
            super.setTextSize(unit, size);
            mTextSize = getTextSize();
        }
    
        /**
         * Override the set line spacing to update our internal reference values
         */
        @Override
        public void setLineSpacing(float add, float mult) {
            super.setLineSpacing(add, mult);
            mSpacingMult = mult;
            mSpacingAdd = add;
        }
    
        /**
         * Set the upper text size limit and invalidate the view
         *
         * @param maxTextSize
         */
        public void setMaxTextSize(float maxTextSize) {
            mMaxTextSize = maxTextSize;
            requestLayout();
            invalidate();
        }
    
        /**
         * Return upper text size limit
         *
         * @return
         */
        public float getMaxTextSize() {
            return mMaxTextSize;
        }
    
        /**
         * Set the lower text size limit and invalidate the view
         *
         * @param minTextSize
         */
        public void setMinTextSize(float minTextSize) {
            mMinTextSize = minTextSize;
            requestLayout();
            invalidate();
        }
    
        /**
         * Return lower text size limit
         *
         * @return
         */
        public float getMinTextSize() {
            return mMinTextSize;
        }
    
        /**
         * Set flag to add ellipsis to text that overflows at the smallest text size
         *
         * @param addEllipsis
         */
        public void setAddEllipsis(boolean addEllipsis) {
            mAddEllipsis = addEllipsis;
        }
    
        /**
         * Return flag to add ellipsis to text that overflows at the smallest text size
         *
         * @return
         */
        public boolean getAddEllipsis() {
            return mAddEllipsis;
        }
    
        /**
         * Reset the text to the original size
         */
        public void resetTextSize() {
            if (mTextSize > 0) {
                super.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
                mMaxTextSize = mTextSize;
            }
        }
    
        /**
         * Resize text after measuring
         */
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            if (changed || mNeedsResize) {
                int widthLimit = (right - left) - getCompoundPaddingLeft() - getCompoundPaddingRight();
                int heightLimit = (bottom - top) - getCompoundPaddingBottom() - getCompoundPaddingTop();
                resizeText(widthLimit, heightLimit);
            }
            super.onLayout(changed, left, top, right, bottom);
        }
    
        /**
         * Resize the text size with default width and height
         */
        public void resizeText() {
            int heightLimit = getHeight() - getPaddingBottom() - getPaddingTop();
            int widthLimit = getWidth() - getPaddingLeft() - getPaddingRight();
            resizeText(widthLimit, heightLimit);
        }
    
        /**
         * Resize the text size with specified width and height
         *
         * @param width
         * @param height
         */
        public void resizeText(int width, int height) {
            CharSequence text = getText();
            // Do not resize if the view does not have dimensions or there is no text
            if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
                return;
            }
    
            if (getTransformationMethod() != null) {
                text = getTransformationMethod().getTransformation(text, this);
            }
    
            // Get the text view's paint object
            TextPaint textPaint = getPaint();
    
            // Store the current text size
            float oldTextSize = textPaint.getTextSize();
            // If there is a max text size set, use the lesser of that and the default text size
            float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;
    
            // Get the required text height
            int textHeight = getTextHeight(text, textPaint, width, targetTextSize);
    
            // Until we either fit within our text view or we had reached our min text size, incrementally try smaller sizes
            while (textHeight > height && targetTextSize > mMinTextSize) {
                targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
                textHeight = getTextHeight(text, textPaint, width, targetTextSize);
            }
    
            // If we had reached our minimum text size and still don't fit, append an ellipsis
            if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
                // Draw using a static layout
                // modified: use a copy of TextPaint for measuring
                TextPaint paint = new TextPaint(textPaint);
                // Draw using a static layout
                StaticLayout layout = new StaticLayout(text, paint, width, Layout.Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
                // Check that we have a least one line of rendered text
                if (layout.getLineCount() > 0) {
                    // Since the line at the specific vertical position would be cut off,
                    // we must trim up to the previous line
                    int lastLine = layout.getLineForVertical(height) - 1;
                    // If the text would not even fit on a single line, clear it
                    if (lastLine < 0) {
                        setText("");
                    }
                    // Otherwise, trim to the previous line and add an ellipsis
                    else {
                        int start = layout.getLineStart(lastLine);
                        int end = layout.getLineEnd(lastLine);
                        float lineWidth = layout.getLineWidth(lastLine);
                        float ellipseWidth = textPaint.measureText(mEllipsis);
    
                        // Trim characters off until we have enough room to draw the ellipsis
                        while (width < lineWidth + ellipseWidth) {
                            lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
                        }
                        setText(text.subSequence(0, end) + mEllipsis);
                    }
                }
            }
    
            // Some devices try to auto adjust line spacing, so force default line spacing
            // and invalidate the layout as a side effect
            setTextSize(TypedValue.COMPLEX_UNIT_PX, targetTextSize);
            setLineSpacing(mSpacingAdd, mSpacingMult);
    
            // Notify the listener if registered
            if (mTextResizeListener != null) {
                mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
            }
    
            // Reset force resize flag
            mNeedsResize = false;
        }
    
        // Set the text size of the text paint object and use a static layout to render text off screen before measuring
        private int getTextHeight(CharSequence source, TextPaint paint, int width, float textSize) {
            // modified: make a copy of the original TextPaint object for measuring
            // (apparently the object gets modified while measuring, see also the
            // docs for TextView.getPaint() (which states to access it read-only)
            TextPaint paintCopy = new TextPaint(paint);
            // Update the text paint object
            paintCopy.setTextSize(textSize);
            // Measure using a static layout
            StaticLayout layout = new StaticLayout(source, paintCopy, width, Layout.Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true);
            return layout.getHeight();
        }
    }
    
    /**
    *自动调整文本大小以适应视图的文本视图。
    *如果文本大小等于最小文本大小,但仍然不等于
    *fit,用省略号追加。
    */
    公共类AutoResizeTextView扩展了android.support.v7.widget.AppCompatTextView{
    //此文本视图的最小文本大小
    公共静态最终浮点最小值\文本\大小=20;
    //调整大小通知的接口
    公共接口OnTextResizeListener{
    public void onTextResize(TextView TextView、float oldSize、float newSize);
    }
    //我们的椭圆弦
    私有静态最终字符串mEllipsis=“…”;
    //注册调整侦听器大小
    私有OnTextResizeListener mTextResizeListener;
    //文本和/或大小更改的标志,以强制调整大小
    私有布尔值mNeedsResize=false;
    //根据代码设置的文本大小。这是调整大小的起点
    私有浮动mTextSize;
    //起始文本大小的临时上限
    私有浮点mMaxTextSize=0;
    //文本大小的下限
    私有浮点mMinTextSize=MIN\u TEXT\u SIZE;
    //文本视图行距倍增器
    私人浮动mSpacingMult=1.0f;
    //文本视图附加行间距
    私人浮动mSpacingAdd=0.0f;
    //将省略号添加到以最小文本大小溢出的文本中
    私有布尔mAddEllipsis=true;
    //默认构造函数重写
    公共AutoResizeTextView(上下文){
    这个(上下文,空);
    }
    //从XML文件膨胀时的默认构造函数
    公共AutoResizeTextView(上下文、属性集属性){
    这(上下文,属性,0);
    }
    //默认构造函数重写
    公共AutoResizeTextView(上下文上下文、属性集属性、int-defStyle){
    超级(上下文、属性、定义样式);
    mTextSize=getTextSize();
    }
    /**
    *文本更改时,请将“强制调整大小”标志设置为true并重置文本大小。
    */
    @凌驾
    受保护的void onTextChanged(最终字符序列文本、最终整数开始、最终整数之前、最终整数之后){
    mNeedsResize=true;
    //由于此视图可以重用,因此最好重置文本大小
    resetTextSize();
    }
    /**
    *如果文字视图大小已更改,请将“强制调整大小”标志设置为true
    */
    @凌驾
    已更改尺寸的受保护空心(整数w、整数h、整数oldw、整数oldh){
    如果(w!=oldw | | h!=oldh){
    mNeedsResize=true;
    }
    }
    /**
    *注册侦听器以接收调整大小通知
    *
    *@param侦听器
    */
    public void setOnResizeListener(AutoResizeTextView.OnTextResizeListener侦听器){
    mTextResizeListener=监听器;
    }
    /**
    *覆盖设置的文本大小以更新内部参考值
    */
    @凌驾
    公共void setTextSize(浮动大小){
    super.setTextSize(大小);
    mTextSize=getTextSize();
    }
    /**
    *覆盖设置的文本大小以更新内部参考值
    */
    @凌驾
    公共void setTextSize(整数单位,浮点大小){
    super.setTextSize(单位,大小);
    mTextSize=getTextSize();
    }
    /**
    *覆盖设置的行距以更新内部参考值
    */
    @凌驾
    公共void设置行间距(浮动添加、浮动多个){
    super.setlinespace(添加,多个);
    mSpacingMult=mult;
    mSpacingAdd=添加;
    }
    /**
    *设置文本大小上限并使视图无效
    *
    *@param maxTextSize
    */
    公共void setMaxTextSize(浮动maxTextSize){
    mmaxtsize=maxTextSize;
    requestLayout();
    使无效();
    }
    /**
    *返回文本大小上限
    *
    *@返回
    */
    公共浮点getMaxTextSize(){
    返回mMaxTextSize;
    }
    /**
    *设置较低的文本大小限制并使视图无效
    *
    *@param minTextSize
    */
    公共void setMinTextSize(浮点minTextSize){
    mMinTextSize=minTextSize;
    requestLayout();
    使无效();
    }
    /**
    *返回较低的文本大小限制
    *
    *@返回
    */
    公共浮点数getMinTextSi
    
        <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context="com.yvettecolomb.myapplication.MainActivity"
        tools:showIn="@layout/activity_main">
    
    
        <RelativeLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/ll1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginLeft="0dp"
            android:layout_marginRight="0dp"
            android:layout_marginTop="10dp"
            android:padding="0dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent">
    
            <TextView
                android:id="@+id/tv1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="10dp"
                android:autoSizeTextType="uniform"
                android:gravity="center"
                android:padding="2dp"
                android:text="TEST"/>
    
            <ImageView
                android:id="@+id/image1"
                android:layout_width="wrap_content"
                android:layout_height="30dp"
                android:layout_margin="-10dp"
                android:layout_toLeftOf="@+id/tv1"
                android:src="@drawable/a"/>
    
            <ImageView
                android:id="@+id/image2"
                android:layout_width="wrap_content"
                android:layout_height="30dp"
                android:layout_toRightOf="@+id/tv1"
                android:src="@drawable/b"/>
    
    
            <ImageView
                android:id="@+id/image3"
                android:layout_width="wrap_content"
                android:layout_height="30dp"
                android:layout_below="@+id/tv1"
                android:layout_margin="-10dp"
                android:layout_toLeftOf="@+id/tv2"
                android:src="@drawable/c"/>
    
            <TextView
                android:id="@+id/tv2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/tv1"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="10dp"
                android:autoSizeTextType="uniform"
                android:gravity="center"
                android:padding="2dp"
                android:text="test test test test test"/>
    
            <ImageView
                android:id="@+id/image4"
                android:layout_width="wrap_content"
                android:layout_height="30dp"
                android:layout_below="@+id/tv1"
                android:layout_toRightOf="@+id/tv2"
                android:src="@drawable/d"/>
        </RelativeLayout>
    
    
    </android.support.constraint.ConstraintLayout>
    
                        <RelativeLayout
                        xmlns:app="http://schemas.android.com/apk/res-auto"
                        android:id="@+id/rl_flashcard_back"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:orientation="vertical">
    
                        <android.support.v7.widget.AppCompatTextView
                            android:id="@+id/tv_text"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:layout_centerInParent="true"
                            android:gravity="center"
                            app:autoSizeMaxTextSize="16sp"
                            app:autoSizeMinTextSize="8sp"
                            app:autoSizeStepGranularity="1sp"
                            app:autoSizeTextType="uniform"
                            />
    
    android.support.v7.widget.AppCompatTextView tv_text = mRootView.findViewById(R.id.tv_text);