How to increase layout_marginBottom by a number of pixels? - android

In a game I display a custom View and a FAB in a FrameLayout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<de.slova.GameView
android:id="#+id/gameView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:src="#drawable/play_white" />
</FrameLayout>
However the FAB is shown too low and obscures the light blue bar at the bottom:
I need to increase the layout_marginBottom by the height of the light blue bar (indicated by the red arrows at the above screenshot), so that the FAB is moved up.
I do know the height of the bar in pixels (the content of my custom View is scaled by a Matrix) and I think I know the right place for this action (the onSizeChanged method in my custom View) - but my difficulty is getting ahold of the FAB's layout_marginBottom value.
How to access and change it please? I have tried:
#Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
super.onSizeChanged(w, h, oldW, oldH);
int h = mBar.getHeight();
ViewGroup.LayoutParams params = mFab.getLayoutParams();
// how to add h to layout_marginBottom here?
mFab.setLayoutParams(params);
}
By the way I do have two methods to translate between dp and px if needed here:
public static float px2sp(Context context, float px) {
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return px / scaledDensity;
}
public static float sp2px(Context context, float sp) {
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return sp * scaledDensity;
}

Margin property is part of FrameLayout.LayoutParams Class, so you have to cast it to FrameLayout.LayoutParams
FrameLayout.LayoutParams param = (FrameLayout.LayoutParams) fab.getLayoutParams();
param.bottomMargin = mBar.getHeight();
fab.setLayoutParams(param);

Related

CollapsingToolbarLayout image with zoom

I've been reading around all day without any success on this.
Basically want to be able to set an ImageView inside a android.support.design.widget.CollapsingToolbarLayout to change it's height depending on the onOffsetChanged change detected so that it will "zoom-out" when collapsed to fit the whole image width and "zoom-in" when expanded to do normal centerCrop behavior.
I tried setting the ImageView height in the onOffsetChanged but that causes other issues assuming due to the CollapsingToolbarLayout is also repositioning it.
Sample functionality I've seen in ParallaxListView project but wish to use the CollapsingToolbarLayout.
Anyone able to give sample code (if it is possible)?
Also seen this project but again similar limitation. Other projects as well.
You can try using android:scaleType="matrix"for the collapsing image's layout definition.
In the code,
store the initial ImageMatrix in a Matrix using matrix.set(imageView.getImageMatrix());
And depending upon the scroll of collapsing toolbar, you can use matrix.postScale() to scale the image and finally set it back to the ImageView using imageView.setImageMatrix(matrix). That can give you the zoom in / out effect.
I managed to do it in the end with the following code for anyone else out there that it may help. The code will fit to width when expanded and fit to height when collapsed. It can be changed to scale (zoom) further in if needed.
Not sure if optimal code is written, suggestions welcome. To measure the bitmap and the view and calculate the min/max scale I use the first call to onOffsetChanged which seems to work fine.
public class MyActivity extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener {
private float collapsedScale;
private float expandedScale;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity_layout);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setTitle(entry.label);
photoView = (ImageView) findViewById(R.id.photo_image);
AppBarLayout mAppBarLayout = (AppBarLayout) findViewById(R.id.appbar);
mAppBarLayout.addOnOffsetChangedListener(this);
}
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
int maxScroll = appBarLayout.getTotalScrollRange();
float scrollPercent = (float) Math.abs(verticalOffset) / (float) maxScroll;
if (collapsedScale == 0) {
Drawable photo = photoView.getDrawable();
int bitmapWidth = photo.getIntrinsicWidth();
int bitmapHeight = photo.getIntrinsicHeight();
collapsedScale = (float)photoView.getWidth()/(float)bitmapWidth;
expandedScale = (float)photoView.getHeight()/(float)bitmapHeight;
scalePhotoImage(photoView, expandedScale);
} else {
scalePhotoImage(photoView, collapsedScale + (expandedScale - collapsedScale) * (1f - scrollPercent));
}
}
private static void scalePhotoImage(ImageView photoView, float scale) {
Drawable photo = photoView.getDrawable();
int bitmapWidth = photo.getIntrinsicWidth();
int bitmapHeight = photo.getIntrinsicHeight();
float offsetX = (photoView.getWidth() - bitmapWidth) / 2F;
float offsetY = (photoView.getHeight() - bitmapHeight) / 2F;
float centerX = photoView.getWidth() / 2F;
float centerY = photoView.getHeight() / 2F;
Matrix imageMatrix = new Matrix();
imageMatrix.setScale(scale, scale, centerX, centerY);
imageMatrix.preTranslate(offsetX, offsetY);
photoView.setImageMatrix(imageMatrix);
}
}
My layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/menu_background_color"
tools:context="style.donkey.android.EntryDetailsActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:elevation="6dp"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:contentScrim="#android:color/transparent">
<ImageView
android:id="#+id/photo_image"
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="#drawable/demo_photo"
android:fitsSystemWindows="true"
android:scaleType="matrix"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="100dp"
android:theme = "#style/ToolBarStyle"
app:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<include layout="#layout/content_layout" />
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

Android AutoResizeTextView - Vertical Gravity off after resize

I'm using the AutoResizeTextView class found here. Auto Scale TextView Text to Fit within Bounds and it works great. However, I have the textview in a RelativeLayout and I have the layout_centerVertical property on the TextView set to true. Works great, unless the TextView doesn't fit and resizes itself. Then the text is no longer vertically centered within the RelativeLayout.
I'm guessing this is because the vertical alignment is performed BEFORE the TextView does its resizing.
How can I fix this? Is there a way to re-trigger the gravity alignment of the View after the text is resized?
Example layout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<com.mypackage.android.AutoResizeTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some Text Here"
android:maxLines="1"
android:ellipsize="end" />
</RelativeLayout>
Try to also trigger resizeText() in
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// trigger here
}
//This is called during layout when the size of this view has changed
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// trigger here
}

Issue with CoordinatorLayout and ImageView that adjusts width while scrolling

I'm attempting to put an ImageView in a CollapsingToolbarLayout in which it takes up the full screen on load and as you scroll the content, the 16x9 resolution image width resizes until the image takes up the full width of the screen. At that point, I'd like the image to parallax with a app:layout_collapseParallaxMultiplier of 0.5
Using this XML Layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="#+id/img_hero"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#drawable/lake"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.5"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="none"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_scrolling"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/fab_margin"
app:layout_anchor="#id/app_bar"
app:layout_anchorGravity="bottom|end"
app:srcCompat="#android:drawable/ic_dialog_email"/>
</android.support.design.widget.CoordinatorLayout>
Accomplishes the following:
Which the following shows what the actual boundaries of the image are:
As I scroll, I would like more of the image width to show as the height of the image shrinks and results in the following:
Once I get to this point, this is where I would like the collapse parallax multiplier of 0.5 to take effect.
I've messed with many different scroll behaviors, tried all of the ImageView scrollTypes, to no avail. Does anybody know if this is possible and if so, can provide any pointers into what I'm either doing wrong or not doing.
Do I need to create my own custom CoordinatorLayout.Behavior to accomplish this?
You can achieve what you want by tracking vertical offset of AppBarLayout. It has beautiful method addOnOffsetChangedListener, so you can scale your image depending on offset of AppBarLayout.
So, there are three things that you have to do to get it working:
You need to place your image into drawable-nodpi folder, to prevent Android from scaling it for different screen sizes.
Change your ImageView's property scaleType to matrix - it's needed as we will change matrix of this ImageView by ourselves.
Implement addOnOffsetChangedListener for you AppBarLayout by next way:
final ImageView imageView = (ImageView) findViewById(R.id.img_hero);
AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.app_bar);
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
Matrix matrix = new Matrix(imageView.getImageMatrix());
//get image's width and height
final int dwidth = imageView.getDrawable().getIntrinsicWidth();
final int dheight = imageView.getDrawable().getIntrinsicHeight();
//get view's width and height
final int vwidth = imageView.getWidth() - imageView.getPaddingLeft() - imageView.getPaddingRight();
int vheight = imageView.getHeight() - imageView.getPaddingTop() - imageView.getPaddingBottom();
float scale;
float dx = 0, dy = 0;
float parallaxMultiplier = ((CollapsingToolbarLayout.LayoutParams) imageView.getLayoutParams()).getParallaxMultiplier();
//maintain the image's aspect ratio depending on offset
if (dwidth * vheight > vwidth * dheight) {
vheight += (verticalOffset); //calculate view height depending on offset
scale = (float) vheight / (float) dheight; //calculate scale
dx = (vwidth - dwidth * scale) * 0.5f; //calculate x value of the center point of scaled drawable
dy = -verticalOffset * (1 - parallaxMultiplier); //calculate y value by compensating parallaxMultiplier
} else {
scale = (float) vwidth / (float) dwidth;
dy = (vheight - dheight * scale) * 0.5f;
}
int currentWidth = Math.round(scale * dwidth); //calculate current intrinsic width of the drawable
if (vwidth <= currentWidth) { //compare view width and drawable width to decide, should we scale more or not
matrix.setScale(scale, scale);
matrix.postTranslate(Math.round(dx), Math.round(dy));
imageView.setImageMatrix(matrix);
}
}
});
What I did here is just get ImageView's source code to determine bounds when it has centerCrop scale type and then just calculate the scale and translation of matrix depending on verticalOffset. If scale value is less than 1.0f then we've just reached the point where our view's aspect ratio is equal to the drawable's aspect ratio, and we don't need to scale more.
Note:
It would work as you wish, only with the image whose width > height, otherwise its behavior would be the same as centerCrop
It would work only if your parallaxMultiplier is in between 0 and 1.
How it looks for me:

Get width of CardView in Adapter.onBindViewHolder

I have a list of posts and most of them are pictures (simply put it is posts just like G+ or FB apps). Each post entry has an image aspect ratio, so I can set image height based on it's width even before image was loaded from server, so card layout wouldn't change on load.
The problem is layout_width="match_parent" set for both card and post image. When I get width of cardview it is zero. So i can't calculate height.
For now the only solution I see is to take width of parent container (RecyclerView) and deduct all paddings, but it doesn't look like a good solution.
Is there any other way to do it?
Here is an example of adapter code
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
....
int width = holder.itemView.getWidth();
....
//do some calculations
}
Layouts (without irrelevant parts)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:foreground="?android:attr/selectableItemBackground"
card_view:cardBackgroundColor="#ffffff"
card_view:cardCornerRadius="3dp">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/includedPost"
layout="#layout/post_details" />
</RelativeLayout>
</android.support.v7.widget.CardView>
includedPost:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="wrap_content">
<ImageView
android:id="#+id/postImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/commenterImage"
android:minHeight="120dp"
android:scaleType="centerCrop" />
</RelativeLayout>
when onBind or onViewAttachedToWindow is called, the child is not measured yet so you cannot get the width. Even if these calls were made after child is measured, what you are trying to do would not be a good practice because changing height will require a new measurement.
If you are using LinearLayoutManager, it will give the full width to the child (expect RecyclerView padding and child's margins). It is not great but OK to derive your height from there.
Another (more flexible) approach here is to create a custom ImageView that keeps your aspect ratio. When onBind is called, you'll set the desired aspect ratio of your custom ImageView.
When on measure is called, it will measure depending on your aspect ratio.
class MyImageView extends ImageVIew {
....
private float mScale = 1f;
public void setScale(int scale) {
mScale = scale;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width * mScale);
}
}
So in your onBind method, you call setScale on the ImageView depending on your w/h ratio.
I have not tested but this approach should work as desired.
You can use Picasso Transformation to achieve this.
FitToTargetViewTransformation class:
import android.graphics.Bitmap;
import android.view.View;
import com.squareup.picasso.Transformation;
/**
* Picasso Transformation class to fit image to target View size
*/
public class FitToTargetViewTransformation implements Transformation {
private View view;
public FitToTargetViewTransformation(View view) {
this.view = view;
}
#Override
public Bitmap transform(Bitmap source) {
int targetWidth = view.getWidth();
double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
int targetHeight = (int) (targetWidth * aspectRatio);
if (source.getHeight() >= source.getWidth()) {
return source;
}
Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
if (result != source) {
// Same bitmap is returned if sizes are the same
source.recycle();
}
return result;
}
#Override
public String key() {
return "transformation" + " desiredWidth";
}
}
And somewhere in onBindViewHolder you do something like this:
Picasso.with(context)
.load(AVATAR_ENDPOINT)
.transform(new FitToTargetViewTransformation(feedViewHolder.icAvatar))
.into(feedViewHolder.icAvatar);

How add TextView in middle of SeekBar thumb? [duplicate]

This question already has an answer here:
Combine image and text to drawable
(1 answer)
Closed 9 years ago.
I am working in Android. I want to make a SeekBar. In thumb of SeekBar i want to show progress (probably on a TextView aligned over thumb which moves along with thumb).
This is my XML for SeekBar and TextView.
<SeekBar
android:id="#+id/ProgressBar01"
android:layout_width="fill_parent"
android:paddingLeft="10px"
android:paddingRight ="10px"
android:layout_height="70dp"
android:layout_below="#+id/incentives_textViewBottemLeft"
android:max="10"
android:progressDrawable="#drawable/incentive_progress"
android:secondaryProgress="0"
android:thumb="#drawable/incentives_progress_pin"
android:focusable="false" />
<TextView
android:id="#+id/incentives_textViewAbove_process_pin"
android:layout_width="fill_parent"
android:layout_height="20dp"
android:layout_below="#+id/incentives_textViewBottemLeft"
android:layout_marginTop="11dp"
android:text=""
android:textStyle="bold"
android:textColor="#FFe4e1"
android:textSize="15sp" />
and this my code to make align for text
int xPos = ((mSkbSample.getRight() - mSkbSample.getLeft()) / mSkbSample.getMax()) * mSkbSample.getProgress();
v1.setPadding(xPos+m,0,0,0);
v1.setText(String.valueOf(progress).toCharArray(), 0, String.valueOf(progress).length());
But text is not displaying into center of that thumb. Please suggest me what should i do for this.
If I understand your question right, you want to place text inside of the thumb on a seekbar like so:
The Android Seekbar doesn't expose any public or protected methods that allows you to set a text in the thumb. So you can't implement a solution with the Android SeekBar as is.
As a solution, you can write your own CustomSeekBar.
The Android SeekBar extends AbsSeekBar. It's in AbsSeekBar that the thumb's position is set, like so:
private void setThumbPos(int w, Drawable thumb, float scale, int gap) {
int available = w - mPaddingLeft - mPaddingRight;
int thumbWidth = thumb.getIntrinsicWidth();
int thumbHeight = thumb.getIntrinsicHeight();
available -= thumbWidth;
// The extra space for the thumb to move on the track
available += mThumbOffset * 2;
//Determine horizontal position
int thumbPos = (int) (scale * available);
//Determine vertical position
int topBound, bottomBound;
if (gap == Integer.MIN_VALUE) {
Rect oldBounds = thumb.getBounds();
topBound = oldBounds.top;
bottomBound = oldBounds.bottom;
} else {
topBound = gap;
bottomBound = gap + thumbHeight;
}
//Set the thumbs position
thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);
}
and in AbsSeekBar's onDraw() method, the thumb is drawn:
mThumb.draw(canvas);
To implement your own SeekBar, you first create a CustomSeekBar class that extends AbsSeekBar. You then override AbsSeekBar's setThumPos() method in your CustomSeekBar class, and there set the position of your own custom thumb.
Your custom thumb would be a View or ViewGroup,e.g. LinearLayout, with a background drawable and a TextView for the percentage progress text.
You then have to decide how to write the percentage progress to the custom thumb. You could write the percentage progress text on the thumb in a new writeTextOnThumb method() called inside setThumbPos(), or you could expose it as a public method in your CustomSeekBar's API.
Before getting into the details of a solution, I will just mention something that you have probably already considered: The user, when moving the SeekBar, typically has her finger positioned over the thumb, and therefore would likely cover up any text you might put there, at least while the Seekbar is being moved. Now, perhaps you are moving the SeekBar programmatically, or perhaps you are happy enough for the user to view the SeekBar once she has finished moving it and has removed her finger, or perhaps you can count on your user to slide her finger below the SeekBar after she starts to slide it, so as to reveal the thumb. But if that is not the case, then you might want to position the text somewhere that the user's finger is likely not to be.
The approach described below should allow you to position text anywhere in the SeekBar that you like, including over the thumb. To allow this, it overrides the SeekBar's basic onDraw() method, rather than overriding a method that deals specifically with drawing the thumb.
Here is a rough version of a class that draws text onto a SeekBar using the above approach:
public class SeekBarWithText extends SeekBar {
private static final int textMargin = 6;
private static final int leftPlusRightTextMargins = textMargin + textMargin;
private static final int maxFontSize = 18;
private static final int minFontSize = 10;
protected String overlayText;
protected Paint textPaint;
public SeekBarWithText(Context context) {
super(context);
Resources resources = getResources();
//Set up drawn text attributes here
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
textPaint.setTextAlign(Align.LEFT);
}
//This attempts to ensure that the text fits inside your SeekBar on a resize
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setFontSmallEnoughToFit(w - leftPlusRightTextMargins)));
}
//Finds the largest text size that will fit
protected void setFontSmallEnoughToFit(int width) {
int textSize = maxTextSize;
textPaint.setTextSize(textSize);
while((textPaint.measureText(sampleText) > width) && (textSize > minTextSize)) {
textSize--;
textPaint.setTextSize(textSize);
}
}
//Clients use this to change the displayed text
public void setOverlayText(String text) {
this.overlayText = text;
invalidate();
}
//Draws the text onto the SeekBar
#Override
protected synchronized void onDraw(Canvas canvas) {
//Draw everything else (i.e., the usual SeekBar) first
super.onDraw(canvas);
//No text, no problem
if(overlayText.length() == 0) {
return;
}
canvas.save();
//Here are a few parameters that could be useful in calculating where to put the text
int width = this.getWidth() - leftPlusRightTextMargins;
int height = this.getHeight();
//A somewhat fat finger takes up about seven digits of space
// on each side of the thumb; YFMV
int fatFingerThumbHangover = (int) textPaint.measureText("1234567");
float textWidth = textPaint.measureText(overlayText);
int progress = this.getProgress();
int maxProgress = this.getMax();
double percentProgress = (double) progress / (double) maxProgress;
int textHeight = (int) (Math.abs(textPaint.ascent()) + textPaint.descent() + 1);
int thumbOffset = this.getThumbOffset();
//These are measured from the point textMargin in from the left of the SeekBarWithText view.
int middleOfThumbControl = (int) ((double) width * percentProgress);
int spaceToLeftOfFatFinger = middleOfThumbControl - fatFingerThumbHangover;
int spaceToRightOfFatFinger = (width - middleOfThumbControl) - fatFingerThumbHangover;
int spaceToLeftOfThumbControl = middleOfThumbControl - thumbOffset;
int spaceToRightOfThumbControl = (width - middleOfThumbControl) - thumbOffset;
int bottomPadding = this.getPaddingBottom();
int topPadding = this.getPaddingTop();
//Here you will use the above and possibly other information to decide where you would
// like to draw the text. One policy might be to draw it on the extreme right when the thumb
// is left of center, and on the extreme left when the thumb is right of center. These
// methods will receive any parameters from the above calculations that you need to
// implement your own policy.
x = myMethodToSetXPosition();
y = myMethodToSetYPosition();
//Finally, just draw the text on top of the SeekBar
canvas.drawText(overlayText, x, y, textPaint);
canvas.restore();
}
}
check this put trees of relative layout to put text on top of seekbar
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/relativeLayout0" >
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/button1"
android:layout_alignBottom="#+id/button1"
android:layout_alignParentRight="true"
android:text="Button" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/button1"
android:layout_marginBottom="0dp"
android:layout_toRightOf="#+id/button1" >
<SeekBar
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/seekBar1"
android:layout_alignParentRight="true"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
</RelativeLayout>
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/relativeLayout1"
android:layout_centerHorizontal="true"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
enter code here
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"`enter code here`
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="24dp"
android:text="Button" />
</RelativeLayout>

Categories

Resources