试图使文本控制台具有40列或40个字符

问题描述 投票:0回答:1

我正在扩展MultiAutoCompleteTextView,并且将字体设置为此字体Unicode font

这里是我声明的xml

<jacs.apps.jacs.CustomViews.Console
        android:id="@+id/auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:dropDownAnchor="@id/content_frame"
        android:dropDownHeight="100dp"
        android:layout_weight="1"
        android:gravity="bottom"
        android:inputType="textMultiLine|textNoSuggestions"
        android:fontFamily="@font/unifont"
        android:imeOptions="actionDone"
        android:scrollbars="vertical"
        android:scrollHorizontally="false"
        android:singleLine="false"
        android:typeface="monospace"

        />

这是我的课程

class Console : AppCompatMultiAutoCompleteTextView {
    private var mCharHeight = 0
    private var h: Int = 0
    private var mIsSearchEnabled = true
    protected val heightVisible: Int
        get() {
            val rect = Rect()
            getWindowVisibleDisplayFrame(rect)
            return rect.bottom - rect.top
        }

    constructor(context: Context) : super(context) {}

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}

    private fun refitText(text: String, textWidth: Int) {
        val mTestPaint = Paint()
        mTestPaint.set(this.paint)
        if (textWidth <= 0)
            return
        val targetWidth = textWidth - this.paddingLeft - this.paddingRight
        var hi = 100f
        var lo = 2f
        val threshold = 0.5f // How close we have to be

        mTestPaint.set(this.paint)

        while (hi - lo > threshold) {
            val size = (hi + lo) / 2
            mTestPaint.textSize = size
            if (mTestPaint.measureText(text) >= targetWidth)
                hi = size // too big
            else
                lo = size // too small
        }
        // Use lo so that we undershoot rather than overshoot
        this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo)
        Log.d("baseline", "textsize: $textSize")

    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val parentWidth = MeasureSpec.getSize(widthMeasureSpec)
        val height = measuredHeight
        refitText("mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm", parentWidth)
        this.setMeasuredDimension(parentWidth, height)

    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        onDropDownChangeSize(w, h)
    }

    protected fun onDropDownChangeSize(w: Int, h: Int) {
        val rect = Rect()
        getWindowVisibleDisplayFrame(rect)
        //Logger.debug(TAG, "onDropdownChangeSize: " + rect);
        // 1/2 width of screen
        dropDownWidth = (w * 0.5f).toInt()
        // 0.5 height of screen
        //setDropDownHeight((int) (h * 1f));
        dropDownHeight = 300
        this.h = h
        Log.d("suggestions", "h : $h")
        //change position
        onPopupChangePosition()
    }

    fun setSearchEnabledTrue() {
        mIsSearchEnabled = true
        setSearchEnabled(true)

    }

    fun setSearchEnabled(isEnabled: Boolean) {
        mIsSearchEnabled = isEnabled
    }

    override fun performFiltering(text: CharSequence, keyCode: Int) {
        if (mIsSearchEnabled) {
            super.performFiltering(text, keyCode)
        }
    }

    override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
        val conn = super.onCreateInputConnection(outAttrs)
        outAttrs.imeOptions = outAttrs.imeOptions and EditorInfo.IME_FLAG_NO_ENTER_ACTION.inv()
        return conn
    }

    override fun showDropDown() {
        if (mIsSearchEnabled) {
            onPopupChangePosition()

            super.showDropDown()
        }

    }

    protected fun invalidateCharHeight() {
        mCharHeight = Math.ceil(paint.fontSpacing.toDouble()).toInt()
        mCharHeight = paint.measureText("M").toInt()
    }

    protected fun onPopupChangePosition() {
        try {
            val layout = layout
            invalidateCharHeight()
            if (layout != null) {

                val pos = selectionStart
                val line = layout.getLineForOffset(pos)
                val baseline = layout.getLineBaseline(line)
                val ascent = layout.getLineAscent(line)

                val bounds = Rect()
                val textPaint = paint
                val sample = "A"
                textPaint.getTextBounds(sample, 0, sample.length, bounds)
                val width = bounds.width() / sample.length


                val x = layout.getPrimaryHorizontal(pos)
                val y = (baseline + ascent).toFloat()

                val offsetHorizontal = x.toInt() + getWidth()
                dropDownHorizontalOffset = offsetHorizontal

                val heightVisible = heightVisible
                val offsetVertical = (y + mCharHeight - scrollY).toInt()

                val tmp = -h + offsetVertical + dropDownHeight + mCharHeight

                //if (tmp < heightVisible) {
                //tmp = -h + ((offsetVertical*2 / (mCharHeight)) * (mCharHeight / 2))+(mCharHeight/2);
                dropDownVerticalOffset = tmp
                Log.d("suggestions", "tmp : $tmp")
                //((Activity)(mContext)).setTitle("ov :"+offsetVertical +" ch "+mCharHeight+" tmp"+tmp +"h "+h+"p:"+pos);
                //                } else {
                //                    tmp = offsetVertical - getDropDownHeight() - mCharHeight;
                //                    setDropDownVerticalOffset(tmp);
                //                    ((Activity)(mContext)).setTitle(" 2 tmp :"+tmp);
                //                }


                //                int pos = getSelectionStart();
                //                int line = layout.getLineForOffset(pos);
                //                int baseline = layout.getLineBaseline(line);
                //                int ascent = layout.getLineAscent(line);
                //
                //                float x = layout.getPrimaryHorizontal(pos);
                //                float y = baseline + ascent;
                //
                //                int offsetHorizontal = (int) x + mGutterWidth;
                //                setDropDownHorizontalOffset(offsetHorizontal);
                //
                //                //    int heightVisible = getHeightVisible();
                //                int offsetVertical = (int) ((y + mCharHeight) - getScrollY());
                //
                //                int tmp = offsetVertical + getDropDownHeight() + mCharHeight;
                ////                if (tmp < heightVisible) {
                //                tmp = -(offsetVertical + mCharHeight) + ((offsetVertical / mCharHeight) * (mCharHeight / 2));
                //                setDropDownVerticalOffset(tmp);
                ////                } else {
                ////                    tmp = offsetVertical - getDropDownHeight() - mCharHeight;
                ////                    setDropDownVerticalOffset(tmp);
                ////                }

            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    companion object {
        private val MINIMAL_HEIGHT = 100
    }

}

我正在尝试使每个设备的视图宽40个字符,并且它可以在许多不同的设备上运行,但是当我在分辨率为720X1560的仿真器上运行该视图时,它使每行41个字符而不是所需的40个字符。我是试图找到一种方法来设置字体大小,以便每行有40个字符。

编辑放置android:paddingRight="35dp"似乎可以解决问题,尽管id想要确定也不能使用换行符,因为我已经在使用它们进行特殊的解析了]

感谢您的时间

我正在扩展MultiAutoCompleteTextView,并且将字体设置为此字体Unicode字体,这是我在其中声明

android kotlin view fonts textview
1个回答
1
投票

我修改了refitText方法如下:

private fun refitText(columns: Int, textWidth: Int) {
    val mTestPaint = Paint()
    mTestPaint.set(this.paint)
    if (textWidth <= 0)
        return
    val targetWidth = textWidth - this.paddingLeft - this.paddingRight
    val maxTextSize = 1000000f
    mTestPaint.textSize = maxTextSize
    val maxCharWidth = mTestPaint.measureText("m")
    var size = targetWidth * maxTextSize / (maxCharWidth * columns)
    do {
        mTestPaint.textSize = size
        val realCharWidth = mTestPaint.measureText("m")
        val requiredPadding = targetWidth - realCharWidth * columns;
        if (requiredPadding >= 0) {
            this.setPadding(this.paddingLeft + requiredPadding.toInt() / 2, this.paddingTop, this.paddingRight + requiredPadding.toInt() / 2, this.paddingBottom)
            break
        }
        size *= 1 - (Math.abs(requiredPadding) / targetWidth)
    } while (requiredPadding < 0)
    this.setTextSize(TypedValue.COMPLEX_UNIT_PX, size)

    Log.d("baseline", "textsize: $textSize")

}
© www.soinside.com 2019 - 2024. All rights reserved.