Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

Как создать плавающий TextView

#java #android


Работаю над приожением в которое пользователь должен вводить информацию. Выглядит
так: идет LinearLayout(horizontal) и в нем TextView затем EditText затем TextView.
Где пользователь должен вводить информацию в EditText. 

Проблема в том, что при реализации, это выглядит так: 

|blabla________tatata|
|              tatata| 


То есть если строка не влазит, перенос строки приосходит под 3-й TextView.

А мне нужно, чтобы это выглядело вот так:

|blabla________tatata|
|tatata              | 


То есть, если строка не влазит, он бы перебрасывал её в начало новой строки.

Второй вариант, я использовал данную реализацию Flow TextView но, как видно из примера
ниже, она больше подходит для картинки.



3-й вариант:

Использую FlowLayout, при этой реализаци вся 3-я часть перепрыгивает на новую строку,
а мне нужно, чтобы перепрыгивала только та часть, которая не уместилась. Помогите плиз
подфиксить!

Как  это выглядит:



public class HorizontalFlowLayout extends RelativeLayout {

    /**
     * Constructor to use when creating View from code.
     */
    public HorizontalFlowLayout(Context context) {
        super(context);
    }

    /**
     * Constructor that is called when inflating View from XML.
     */
    public HorizontalFlowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * Perform inflation from XML and apply a class-specific base style.
     */
    public HorizontalFlowLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // need to call super.onMeasure(...) otherwise get some funny behaviour
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        final int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        // increment the x position as we progress through a line
        int xpos = getPaddingLeft();
        // increment the y position as we progress through the lines
        int ypos = getPaddingTop();
        // the height of the current line
        int line_height = 0;

        // go through children
        // to work out the height required for this view

        // call to measure size of children not needed I think?!
        // getting child's measured height/width seems to work okay without it
        //measureChildren(widthMeasureSpec, heightMeasureSpec);

        View child;
        MarginLayoutParams childMarginLayoutParams;
        int childWidth, childHeight, childMarginLeft, childMarginRight, childMarginTop,
childMarginBottom;

        for (int i = 0; i < getChildCount(); i++) {
            child = getChildAt(i);

            if (child.getVisibility() != GONE) {
                childWidth = child.getMeasuredWidth();
                childHeight = child.getMeasuredHeight();

                if (child.getLayoutParams() != null
                        && child.getLayoutParams() instanceof MarginLayoutParams) {
                    childMarginLayoutParams = (MarginLayoutParams)child.getLayoutParams();

                    childMarginLeft = childMarginLayoutParams.leftMargin;
                    childMarginRight = childMarginLayoutParams.rightMargin;
                    childMarginTop = childMarginLayoutParams.topMargin;
                    childMarginBottom = childMarginLayoutParams.bottomMargin;
                }
                else {
                    childMarginLeft = 0;
                    childMarginRight = 0;
                    childMarginTop = 0;
                    childMarginBottom = 0;
                }

                if (xpos + childMarginLeft + childWidth + childMarginRight + getPaddingRight()
> width) {
                    // this child will need to go on a new line

                    xpos = getPaddingLeft();
                    ypos += line_height;

                    line_height = childMarginTop + childHeight + childMarginBottom;
                }
                else {
                    // enough space for this child on the current line
                    line_height = Math.max(
                            line_height,
                            childMarginTop + childHeight + childMarginBottom);
                }

                xpos += childMarginLeft + childWidth + childMarginRight;
            }
        }

        ypos += line_height + getPaddingBottom();

        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) {
            // set height as measured since there's no height restrictions
            height = ypos;
        }
        else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST
                && ypos < height) {
            // set height as measured since it's less than the maximum allowed
            height = ypos;
        }

        setMeasuredDimension(width, height);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        // increment the x position as we progress through a line
        int xpos = getPaddingLeft();
        // increment the y position as we progress through the lines
        int ypos = getPaddingTop();
        // the height of the current line
        int line_height = 0;

        View child;
        MarginLayoutParams childMarginLayoutParams;
        int childWidth, childHeight, childMarginLeft, childMarginRight, childMarginTop,
childMarginBottom;

        for (int i = 0; i < getChildCount(); i++) {
            child = getChildAt(i);

            if (child.getVisibility() != GONE) {
                childWidth = child.getMeasuredWidth();
                childHeight = child.getMeasuredHeight();

                if (child.getLayoutParams() != null
                        && child.getLayoutParams() instanceof MarginLayoutParams) {
                    childMarginLayoutParams = (MarginLayoutParams)child.getLayoutParams();

                    childMarginLeft = childMarginLayoutParams.leftMargin;
                    childMarginRight = childMarginLayoutParams.rightMargin;
                    childMarginTop = childMarginLayoutParams.topMargin;
                    childMarginBottom = childMarginLayoutParams.bottomMargin;
                }
                else {
                    childMarginLeft = 0;
                    childMarginRight = 0;
                    childMarginTop = 0;
                    childMarginBottom = 0;
                }

                if (xpos + childMarginLeft + childWidth + childMarginRight + getPaddingRight()
> r - l) {
                    // this child will need to go on a new line

                    xpos = getPaddingLeft();
                    ypos += line_height;

                    line_height = childHeight + childMarginTop + childMarginBottom;
                }
                else {
                    // enough space for this child on the current line
                    line_height = Math.max(
                            line_height,
                            childMarginTop + childHeight + childMarginBottom);
                }

                child.layout(
                        xpos + childMarginLeft,
                        ypos + childMarginTop,
                        xpos + childMarginLeft + childWidth,
                        ypos + childMarginTop + childHeight);

                xpos += childMarginLeft + childWidth + childMarginRight;
            }
        }
    }
}


XML




    

    
    


    


Ответы

Ответ 1



Ради интереса решил попробовать справиться с данной задачей. Оказалось довольно-таки просто(Если я правильно понял суть проблемы). 1) В разметку я добавил дополнительный LinearLayout с ориентацией по вертикали Установил айдишники для этого Layout-а и для TextView, который находится справа от editText-a. Назвал их addedLayout и textViewRight 2) Уж скину всю простыню кода, если что переделаете под себя. Просто я создал голый проект и в нем всё писал=) Собственно, активити: public class MainActivity extends AppCompatActivity { private TextView textViewRight; private LinearLayout addedLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textViewRight = (TextView) findViewById(R.id.textViewRight); addedLayout = (LinearLayout) findViewById(R.id.addedLayout); } @Override public void onResume() { super.onResume(); textViewRight.post(new Runnable() { @Override public void run() { int lineCount = textViewRight.getLineCount(); if (lineCount == 1) return; String allText = textViewRight.getText().toString(); String firstLine = allText.substring(0, textViewRight.getLayout().getLineEnd(0)); textViewRight.setText(firstLine); TextView textView = new TextView(getApplicationContext()); textView.setTextColor(Color.parseColor("#000000")); textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); textView.setText(allText.substring(firstLine.length())); addedLayout.addView(textView); } }); } } Принцип строится на том, что мы в onResume смотрим, сколько линий занимает текст справа от поля ввода, если линий больше 1, то создаем новый TexView , кладем его в наш дополнительный layout addedLayout. В правый текствью кладем только первую линию. Остальное "отрезаем" и кладем, в новый создавшийся textView. 3) Результат:

Ответ 2



Тебе нужен еще один TextView который будет располагаться на другой строке |text1________text2Part1| |text2Part2Part2Part2Par| |t2Part2..... | заполняешь text2Part1 определенным количеством символов все остальные помещаешь в text2Part2

Ответ 3



Составьте вот такую разметку: В коде вычислите в пикселях ширину последних двух элементов. Делаать это надо уже после отрисовки экрана (в onResume()) После этого в первый TextView добавляйте пробел и измеряйте координату последнего знака текста в нём. Повторяйте пока координата не станет больше ширины из п2 Теперь можно добавлять в главный TextView текст и он будет начинаться после первых двух элементов и продолжаться на новой строке сразу под ними Вот пример цикла добавляющего неразрывные пробелы в текстовое поле и вычисляющее координату получившегося текста: TextView tv = (TextView) findViewById(R.id.text_view); for (int i = 0; i < 10; i++) { tv.append(" "); Rect bounds = new Rect(); Paint tpaint = tv.getPaint(); tpaint.getTextBounds(tv.getText().toString(), 0, tv.getText().length(), bounds); int width = bounds.width(); Log.i(LOG, "width: " + width); }

Комментариев нет:

Отправить комментарий