Working on app where user has to put some data in EditText
, but in front and behind this EditText
I have TextViews
. For that I use (horizontal)
LinearLayout
where I put TextView
EditText
TextView
. I faced with problem of line transfer. Please, help me to find a solution.
It looks like this now:
|blabla_______tatata|
| tatata|
I need like this:
|blabla_______tatata|
|tatata |
I tried to use FlowTextView but it didn't help, It looks ugly, usable for pictures only.
The problem is: it moves to the second line if it doesn't have enough space. Please help me to make some correction here:
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.nikolai.app">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Main Activity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
HorizontalFlowLayout
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;
}
}
}
}
My XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.nikolai.app.MainActivity">
<com.example.nikolai.app.HorizontalFlowLayout
android:id="@+id/horizontal_flow_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/size_5"
android:paddingRight="@dimen/size_5">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="blablabla"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:ems="7"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="tatatatatatatatata"/>
</com.example.nikolai.app.HorizontalFlowLayout>
</RelativeLayout>
Here's full source code for FlowLayout
with reference to actual author. I'm using this implementation and it works:
/** @author RAW
* @reference http://nishantvnair.wordpress.com/2010/09/28/flowlayout-in-android/
* Some changes applied, i.e. default horz and vert spacings...
* */
public class FlowLayout extends ViewGroup {
private static int DEFAULT_HORIZONTAL_SPACING=5;
private static int DEFAULT_VERTICAL_SPACING=5;
private int line_height;
public static class LayoutParams extends ViewGroup.LayoutParams {
public final int horizontal_spacing;
public final int vertical_spacing;
/** @param horizontal_spacing Pixels between items, horizontally
* @param vertical_spacing Pixels between items, vertically */
public LayoutParams(int horizontal_spacing, int vertical_spacing) {
super(0, 0);
this.horizontal_spacing = horizontal_spacing;
this.vertical_spacing = vertical_spacing;
}
}
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
assert (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED);
final int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom();
final int count = getChildCount();
int line_height = 0;
int xpos = getPaddingLeft();
int ypos = getPaddingTop();
int childHeightMeasureSpec;
if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
}
else {
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
int horizontal_spacing, vertical_spacing;
final ViewGroup.LayoutParams lp = child.getLayoutParams();
if(lp instanceof LayoutParams) {
horizontal_spacing=((LayoutParams )lp).horizontal_spacing;
vertical_spacing=((LayoutParams )lp).vertical_spacing;
} else {
horizontal_spacing=DEFAULT_HORIZONTAL_SPACING;
vertical_spacing=DEFAULT_VERTICAL_SPACING;
}
child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), childHeightMeasureSpec);
final int childw = child.getMeasuredWidth();
line_height = Math.max(line_height, child.getMeasuredHeight() + vertical_spacing);
if (xpos + childw > width) {
xpos = getPaddingLeft();
ypos += line_height;
}
xpos += childw + horizontal_spacing;
}
}
this.line_height = line_height;
if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) {
height = ypos + line_height;
}
else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
if (ypos + line_height < height) {
height = ypos + line_height;
}
}
setMeasuredDimension(width, height);
}
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(1, 1); // default of 1px spacing
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
if (p instanceof LayoutParams) {
return true;
}
return false;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
final int width = r - l;
int xpos = getPaddingLeft();
int ypos = getPaddingTop();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final int childw = child.getMeasuredWidth();
final int childh = child.getMeasuredHeight();
final ViewGroup.LayoutParams lp = child.getLayoutParams();
if (xpos + childw > width) {
xpos = getPaddingLeft();
ypos += line_height;
}
child.layout(xpos, ypos, xpos + childw, ypos + childh);
if(lp instanceof LayoutParams)
xpos += childw + ((LayoutParams)lp).horizontal_spacing;
else
xpos += childw + DEFAULT_HORIZONTAL_SPACING;
}
}
}
}
Usage kinda:
<com.mydomain.FlowLayout
android:id="@+id/recipientsList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
Try this,
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;
}
}
}
}
And use in XML Layout:
<com.test.widget.HorizontalFlowLayout
android:id="@+id/horizontal_flow_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/size_5"
android:paddingRight="@dimen/size_5">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="5dp"
android:textSize="20sp"
android:text="блабла"
android:id="@+id/textView1"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/name"
android:textSize="20sp"
android:inputType="textCapSentences"
android:ems="5"/>
</LinearLayout>
</com.test.widget.HorizontalFlowLayout>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With