I have a textView which I want to remove every padding and extra space at the top and bottom of the text. This is my XML:
<TextView
android:id="#+id/stid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/quicksand"
android:gravity="center_horizontal"
android:includeFontPadding="false"
android:maxLines="1"
android:text="#string/st"
android:textSize="40sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.538"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
I am wrapping content and removing font padding but there is still a large padding at the top and at the bottom of the text which I want to remove. (on the sides it is fine just top and bottom)
this is a screenshot as requested
Did you try?
android:includeFontPadding="false"
android:lineSpacingExtra="-5dp"
Use this class and compile your project.
public class NoPaddingTextView extends TextView {
private int mAdditionalPadding;
public NoPaddingTextView(Context context) {
super(context);
init();
}
public NoPaddingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setIncludeFontPadding(false);
}
#Override
protected void onDraw(Canvas canvas) {
int yOff = -mAdditionalPadding / 6;
canvas.translate(0, yOff);
super.onDraw(canvas);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
getAdditionalPadding();
int mode = MeasureSpec.getMode(heightMeasureSpec);
if (mode != MeasureSpec.EXACTLY) {
int measureHeight = measureHeight(getText().toString(), widthMeasureSpec);
int height = measureHeight - mAdditionalPadding;
height += getPaddingTop() + getPaddingBottom();
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private int measureHeight(String text, int widthMeasureSpec) {
float textSize = getTextSize();
TextView textView = new TextView(getContext());
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
textView.setText(text);
textView.measure(widthMeasureSpec, 0);
return textView.getMeasuredHeight();
}
private int getAdditionalPadding() {
float textSize = getTextSize();
TextView textView = new TextView(getContext());
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
textView.setLines(1);
textView.measure(0, 0);
int measuredHeight = textView.getMeasuredHeight();
if (measuredHeight - textSize > 0) {
mAdditionalPadding = (int) (measuredHeight - textSize);
Log.v("NoPaddingTextView", "onMeasure: height=" + measuredHeight + " textSize=" + textSize + " mAdditionalPadding=" + mAdditionalPadding);
}
return mAdditionalPadding;
}
}
Replace TextView with NoPaddingTextView Class Name in your XML file
<YourPackage.NoPaddingTextView
android:id="#+id/stid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/quicksand"
android:gravity="center_horizontal"
android:includeFontPadding="false"
android:maxLines="1"
android:text="#string/st"
android:textSize="40sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.538"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Source : Github
StackOverFlow
Related
I want to remove image which was recently added if anyone click minus button.
I have added image one by one on plus button click.
can see in snapshot
On plus button click images are going to add one by one.
want to remove on click of minus button recently added image.
image.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onClick(View v) {
ImageView image = new ImageView(Water.this);
image.setBackgroundResource(R.drawable.glass);
predicate.addView(image);
}
});
ImageView minus=(ImageView)findViewById(R.id.minus);
minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ImageView image = new ImageView(Water.this);
image.setImageBitmap(null);
predicate.removeView(image);
//image.setBackgroundResource(R.drawable.glass);
//((ViewGroup) image.getParent()).removeView(image);
//predicate.removeView(image);
}
});
xml
<TextView
android:id="#+id/waterdescription"
android:text="Water Intake"
android:textSize="16dp"
android:layout_weight="1"
android:layout_marginLeft="20dp"
android:layout_width="wrap_content"
android:textColor="#283D65"
android:textStyle="bold"
android:layout_height="wrap_content"
/>
<ImageView
android:id="#+id/minus"
android:layout_weight="1"
android:layout_toRightOf="#+id/waterdescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/minus"
/>
<ImageView
android:id="#+id/image"
android:layout_weight="1"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/plus"
/>
predicate Layout
public class PredicateLayout extends ViewGroup {
private int line_height;
public PredicateLayout(Context context) {
super(context);
}
public PredicateLayout(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);
// The next line is WRONG!!! Doesn't take into account requested MeasureSpec mode!
int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom();
final int count = getChildCount();
int line_height = 0;
int xpos = getPaddingLeft();
int ypos = getPaddingTop();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final LayoutParams lp = child.getLayoutParams();
child.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
final int childw = child.getMeasuredWidth();
line_height = Math.max(line_height, child.getMeasuredHeight() + lp.height);
if (xpos + childw > width) {
xpos = getPaddingLeft();
ypos += line_height;
}
xpos += childw + lp.width + 8;
}
}
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 + 20);
}
#Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(2, 2); // default of 1px spacing
}
#Override
protected boolean checkLayoutParams(LayoutParams p) {
return (p instanceof LayoutParams);
}
#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 LayoutParams lp = child.getLayoutParams();
if (xpos + childw > width) {
xpos = getPaddingLeft();
ypos += line_height;
}
child.layout(xpos, ypos, xpos + childw, ypos + childh);
xpos += childw + lp.width + 8;
}
}
}
}
You're not referencing the imageView you added in plus button's onClick() method.
minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ImageView image = new ImageView(Water.this);
image.setImageBitmap(null);
predicate.removeView(image);
//image.setBackgroundResource(R.drawable.glass);
//((ViewGroup) image.getParent()).removeView(image);
//predicate.removeView(image);
}
});
ImageView image = new ImageView(Water.this); in this line, you're creating a new ImageView with water and trying to remove it from parent layout. But you didn't even add this.
What you need to do is to keep a reference to the the views you are adding in plus button's onClick() method.
You can do something like:
public class PredicateLayout extends ViewGroup {
private LinkedList<ImageView> imageViews;
//other parts are omitted...
public PredicateLayout(Context context, AttributeSet attrs) {
super(context, attrs);
imageViews = new LinkedList();
}
//...some other code...
public LinkedList<ImageView> getImageViews(){
return imageViews;
}
}
and when adding:
Plus Button:
...onClick() {
//..
predicate.addView(image);
predicate.getImageViews().add(image);
}
Minus Button:
...onClick(){
//pollLast returns last element in the list
ImageView lastAddedImageView = predicate.getImageViews().pollLast()
predicate.removeView(lastAddedImageView);
}
Add view like:
ImageView image = new ImageView(Water.this);
image.setId(Integer.parseInt("1234"));
image.setBackgroundResource(R.drawable.glass);
predicate.addView(image);
And remove it:
View rView=(ImageView)view.findViewById(Integer.parseInt("1234"));
predicate.removeView(rView);
I would like to create a custom RelativeLayout that has two views in one row: one on the left side of the screen (android:layout_alignParentStart="true") and one on the right (android:layout_alignParentEnd="true"). The view on the right will grow toward the left view until it takes up all the space between the two views. Then it will move to a new line under the view on the left.
I have implemented a slightly modified version of Romain Guy's FlowLayout that extends RelativeLayout. However, this class seems to ignore the RelativeLayout's align properties and just sticks the views right next to each other. Is there a way to implement a such a layout that will anchor the views to the left and right?
FlowLayout class:
public class FlowLayout extends RelativeLayout {
private int mHorizontalSpacing;
private int mVerticalSpacing;
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout);
mHorizontalSpacing = attributes.getDimensionPixelSize(R.styleable
.FlowLayout_horizontalSpacing, 0);
mVerticalSpacing = attributes.getDimensionPixelSize(R.styleable
.FlowLayout_verticalSpacing, 0);
attributes.recycle();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int width = 0;
int height = getPaddingTop();
int currentWidth = getPaddingStart();
int currentHeight = 0;
final int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
measureChild(child, widthMeasureSpec, heightMeasureSpec);
if (currentWidth + child.getMeasuredWidth() > widthSize) {
height += currentHeight + mVerticalSpacing;
currentHeight = 0;
width = Math.max(width, currentWidth);
currentWidth = getPaddingEnd();
}
int spacing = mHorizontalSpacing;
if (lp.spacing > -1) {
spacing = lp.spacing;
}
lp.x = currentWidth + spacing;
lp.y = currentHeight;
currentWidth += child.getMeasuredWidth();
currentHeight = Math.max(currentHeight, child.getMeasuredHeight());
}
width += getPaddingEnd();
height += getPaddingBottom();
setMeasuredDimension(resolveSize(width, widthMeasureSpec), resolveSize(height,
heightMeasureSpec));
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y + child
.getMeasuredHeight());
}
}
#Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
#Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout
.LayoutParams.WRAP_CONTENT);
}
#Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p.width, p.height);
}
#Override
public RelativeLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
public static class LayoutParams extends RelativeLayout.LayoutParams {
public int spacing;
public int x;
public int y;
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable
.FlowLayout_LayoutParams);
spacing = attributes.getDimensionPixelSize(R.styleable
.FlowLayout_LayoutParams_layoutSpacing, -1);
attributes.recycle();
}
public LayoutParams(int width, int height) {
super(width, height);
}
}
}
It turns out that rather than calculating the right view's new position yourself, you can change its LayoutParams and have the OS handle positioning for you. I created a custom layout that extends RelativeLayout and overrides the onMeasure() method. This will adjust the LayoutParams accordingly.
More specifically:
Call the super method then find the widths of the two views and their parent in onMeasure(). Use these to figure out if the right view will overlap the left view. If so, change the right view's layout_alignParentEnd="true" property to be layout_alignParentStart="true" and give it the layout_below="#id/left_view" property. Do the opposite when there will be no overlap. Call the super method again to have the OS remeasure the views for you.
The layout class:
public class WrappingLayout extends RelativeLayout {
private TextView leftView;
private EditText rightView;
//Use this to prevent unnecessarily adjusting the LayoutParams
//when the right view is already in the correct position
private boolean isMultiline = false;
public WrappingLayout(Context context) {
super(context);
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.wrapping_layout, this);
leftView = (TextView) findViewById(R.id.left_view);
rightView = (EditText) findViewById(R.id.right_view);
}
public WrappingLayout(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.wrapping_layout, this);
leftView = (TextView) findViewById(R.id.left_view);
rightView = (EditText) findViewById(R.id.right_view);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//Call first to make sure the views' initial widths have been set
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int screenWidth = getMeasuredWidth();
int leftViewWidth = getPaddingStart() + leftView.getMeasuredWidth() + leftView.getPaddingEnd();
int rightViewWidth = getPaddingEnd() + rightView.getMeasuredWidth() + rightView.getPaddingStart();
LayoutParams rightViewParams = (LayoutParams) rightView.getLayoutParams();
if (!isMultiline && rightViewWidth + leftViewWidth > screenWidth) {
isMultiline = true;
rightViewParams.addRule(BELOW, R.id.left_view);
rightViewParams.removeRule(ALIGN_PARENT_END);
rightViewParams.addRule(ALIGN_PARENT_START);
//Call again here to adjust dimensions for new params
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} else if (isMultiline && rightViewWidth + leftViewWidth < screenWidth) {
isMultiline = false;
rightViewParams.removeRule(BELOW);
rightViewParams.addRule(ALIGN_PARENT_END);
rightViewParams.removeRule(ALIGN_PARENT_START);
//Call again here to adjust dimensions for new params
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
The layout XML:
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#id/left_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"/>
<EditText
android:id="#id/right_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:gravity="center"
android:text="#string/hello"/>
</merge>
I want to display multiple text view in a layout dynamically.
Suppose,User selects 10 items from drop down menu then I can display it to layout one after another.I need same view as attached image -
I have selected item in a list,now I am not getting how to display data in desire manner.When I try list view all data are display one after other vertically.
When I use Linearlayout data can be either added in horizontal or vertical order.So I am not getting correct way to display data.
Please help me in solving this issue.
Thanks in advance.
what you are looking for is called chips.why not use material design chips, you can refer it here. http://www.google.com/design/spec/components/chips.html#
you can implement like using grid view if you are not interested using chips just have one row of gridview and populate it there with one cell
Normally if you use LinearLayout with horizontal orientation, it will put your items as you want.
try this one..i used to acheive using custom view.if you are ok with this just give a try..
Custom View class is.
public class WrapLayout extends ViewGroup {
private int paddingHorizontal;
private int paddingVertical;
public WrapLayout(Context context) {
super(context);
init();
}
public WrapLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WrapLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
paddingHorizontal = getResources().getDimensionPixelSize(10);
paddingVertical = getResources().getDimensionPixelSize(10);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childLeft = getPaddingLeft();
int childTop = getPaddingTop();
int lineHeight = 0;
// 100 is a dummy number, widthMeasureSpec should always be EXACTLY for FlowLayout
int myWidth = resolveSize(100, widthMeasureSpec);
int wantedHeight = 0;
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
if (child.getVisibility() == View.GONE) {
continue;
}
// let the child measure itself
child.measure(
getChildMeasureSpec(widthMeasureSpec, 0, child.getLayoutParams().width),
getChildMeasureSpec(heightMeasureSpec, 0, child.getLayoutParams().height));
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
// lineheight is the height of current line, should be the height of the heightest view
lineHeight = Math.max(childHeight, lineHeight);
if (childWidth + childLeft + getPaddingRight() > myWidth) {
// wrap this line
childLeft = getPaddingLeft();
childTop += paddingVertical + lineHeight;
lineHeight = childHeight;
}
childLeft += childWidth + paddingHorizontal;
}
wantedHeight += childTop + lineHeight + getPaddingBottom();
setMeasuredDimension(myWidth, resolveSize(wantedHeight, heightMeasureSpec));
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int childLeft = getPaddingLeft();
int childTop = getPaddingTop();
int lineHeight = 0;
int myWidth = right - left;
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
if (child.getVisibility() == View.GONE) {
continue;
}
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
lineHeight = Math.max(childHeight, lineHeight);
if (childWidth + childLeft + getPaddingRight() > myWidth) {
childLeft = getPaddingLeft();
childTop += paddingVertical + lineHeight;
lineHeight = childHeight;
}
child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
childLeft += childWidth + paddingHorizontal;
}
}
}
and my xml is :
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText_sample"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add It"
android:id="#+id/addit"
/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- i mean where you put the WrapLayout class in your project that package name -->
<your.package.name.WrapLayout
android:id="#+id/flow_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"/>
</ScrollView>
</LinearLayout>
And finally in MainActivity
ViewGroup flowContainer;
In OnCreate
flowContainer= (ViewGroup) findViewById(R.id.flow_container);
final EditText text=(EditText)findViewById(R.id.editText_sample);
Button addIT=(Button)findViewById(R.id.addit);
addIT.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String data=text.getText().toString();
flowContainer.addView(createTextView(data),
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
});
Copy this function within mainactivity
private View createTextView(String text) {
TextView textView = new TextView(this);
textView.setText(text);
textView.setGravity(Gravity.CENTER);
textView.setCompoundDrawablesWithIntrinsicBounds(0,0,R.mipmap.ic_launcher,0);
return textView;
}
I have one HorizontalScrollView and one GridLayout inside with 3 images. It never scrolls as I thought it should, no matter what I do - with gestures, touch - nothing would make the horizontal scroll.
My XML:
<com.app4u.borala.atividades.layout.GridEventoPesqGeo
android:id="#+id/horizontalScroll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:background="#color/azulActionBarTransparente"
android:fillViewport="true"
android:scrollbars="horizontal" >
<GridLayout
android:id="#+id/gridEventos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rowCount="1" >
<com.app4u.borala.atividades.layout.ImageViewEventoPesqGeo
android:id="#+id/imageEvento1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/background_evento_temp" />
<com.app4u.borala.atividades.layout.ImageViewEventoPesqGeo
android:id="#+id/imageEvento2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/background_evento_temp" />
<com.app4u.borala.atividades.layout.ImageViewEventoPesqGeo
android:id="#+id/imageEvento3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/background_evento_temp" />
</GridLayout>
</com.app4u.borala.atividades.layout.GridEventoPesqGeo>
My class GridEventoPesqGeo:
public class GridEventoPesqGeo extends HorizontalScrollView {
public GridEventoPesqGeo(Context context) {
super(context);
}
public GridEventoPesqGeo(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridEventoPesqGeo(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth, (int) (parentHeight * 0.225));
}
}
My class ImageViewEventoPesqGeo:
public class ImageViewEventoPesqGeo extends ImageView{
public ImageViewEventoPesqGeo(Context context) {
super(context);
}
public ImageViewEventoPesqGeo(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ImageViewEventoPesqGeo(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
//int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
MarginLayoutParams lpimgFooter = (MarginLayoutParams) getLayoutParams();
lpimgFooter.bottomMargin = (int) (parentWidth * 0.015);
lpimgFooter.leftMargin = (int) (parentWidth * 0.015);
lpimgFooter.rightMargin = (int) (parentWidth * 0.015);
lpimgFooter.topMargin = (int) (parentWidth * 0.015);
setLayoutParams(lpimgFooter);
this.setMeasuredDimension((int) (parentWidth * 0.33), (int) (parentWidth * 0.33));
}
}
My Java classes just make the width and height proportional depending on the phone's screen size..
Here is the source of HorizontalScrollView onMeasure():
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!mFillViewport) {
return;
}
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode == MeasureSpec.UNSPECIFIED) {
return;
}
if (getChildCount() > 0) {
final View child = getChildAt(0);
int width = getMeasuredWidth();
if (child.getMeasuredWidth() < width) {
final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, mPaddingTop
+ mPaddingBottom, lp.height);
width -= mPaddingLeft;
width -= mPaddingRight;
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
}
Notice that if mFillViewPort is true, it'll return without ever reaching your code. Since you set it to true in xml, no wonder your code is not executed.
historically i have stupid problems with layouts, and now i try to fill this blank in my brain. Watch this example, i try to do some axis for graphic, and i want to pack them like this:
Vertical line by left side
Horizontal line by bottom
Spacer between Vert & Horiz in left bottom corner
Other place fill by graph
(Sorry not allowed to post images.I hope you see graphics axis before, no need to explain.)
And this what i got at now:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<com.example.graphicformatting.Axis
android:id="#+id/yaxis"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="40dp"
android:background="#color/backpanel_dark"
custom:ishorizontal="false" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textMultiLine"
android:text="This text field mean my own graphic widget, which not have any OnMeasured function or any specific and it's painting with size, which assigment by parent/ Just use getHeight and getWeight" >
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<View
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#color/backpanel_dark" />
<com.example.graphicformatting.Axis
android:id="#+id/yaxis"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:background="#color/backpanel_dark"
custom:ishorizontal="true" />
</LinearLayout>
And this is code of my axises:
package com.example.graphicformatting;
public class Axis extends View {
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
public static final int DP_SIZE = 40;
int type = -1;
int size;
Paint painter;
public Axis(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.com_example_graphicformatting_Axis);
final int N = a.getIndexCount();
for (int i = 0; i < N; ++i) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.com_example_graphicformatting_Axis_ishorizontal:
if (a.getBoolean(attr, true)) {
type = HORIZONTAL;
} else
type = VERTICAL;
break;
default:
Log.d("axis", "Found unexpected state");
}
}
a.recycle();
final float scale = getContext().getResources().getDisplayMetrics().density;
size = (int) (DP_SIZE * scale + 0.5f);
painter = new Paint();
painter.setColor(Color.RED);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
if (type == HORIZONTAL) {
this.setMeasuredDimension(parentWidth, size);
this.setLayoutParams(new LinearLayout.LayoutParams(parentWidth, size));
// Log.d("axis", "Size of horizontal calc: " + (parentWidth) + " "
// + size);
} else if (type == VERTICAL) {
this.setMeasuredDimension(size, parentHeight);
this.setLayoutParams(new LinearLayout.LayoutParams(size, parentHeight));
// Log.d("axis", "Size of vertical calc: " + size + " "
// + (parentHeight));
} else { // Для нормального отображения в конструкторе
this.setMeasuredDimension(size, size);
this.setLayoutParams(new LinearLayout.LayoutParams(size, size));
}
}
#Override
protected void onDraw(Canvas canvas) {
if (type == VERTICAL) {
canvas.drawRect(0, 0, size, getHeight(), painter);
} else {
canvas.drawRect(0, getHeight() - size, getWidth(), getHeight(), painter);
}
super.onDraw(canvas);
}
}
How to custom my Layouts to get right pic?
Ou, this using for set horizontal/vertical attribute (value/attrs.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="com.example.graphicformatting.Axis">
<attr name="ishorizontal" format="boolean"></attr>
</declare-styleable>
</resources>