trying to make a text console with 40 columns or characters

痞子三分冷 提交于 2020-01-16 08:39:10

问题


I am extending a MultiAutoCompleteTextView and I have the font set to this font Unicode font

here is the xml where I declare it

<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"

        />

and here is my class

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
    }

}

I am trying to make the view 40 characters wide for every device and it works on a bunch of different devices but when I run it on an emulator that's resolution is 720X1560 it lets 41 characters per row instead of the desired 40. I am trying to find a way to make the font size so that there are 40 characters per row.

EDIT putting android:paddingRight="35dp" seemed to fix the problem although id like to know for sure also I cannot use newlines because I am already using them for a special kind of parsing

thank you for your time

来源:https://stackoverflow.com/questions/59723679/trying-to-make-a-text-console-with-40-columns-or-characters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!