Страницы

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

вторник, 25 декабря 2018 г.

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

Работаю над приожением в которое пользователь должен вводить информацию. Выглядит так: идет 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) В разметку я добавил дополнительный 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) Результат:

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

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