how to change textview size into all devices in android - android-layout

hi i am doing one app in android for all sizes of mobiles and tablets.imageviews displyed in all sizes good.but i facing problm in textview font size.in my app i need to display textview with that background and text,but different sizes text size is displaying not correctly.any one having idea pls help me. i tried using below code...
MainActivity .class
public class MainActivity extends Activity {
float screenHeight,screenWidth,screendensity;
RelativeLayout alpha_page2;
ImageView alpha_back,alpha_back1;
TextView option121;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
screenHeight = displaymetrics.heightPixels;
screenWidth = displaymetrics.widthPixels;
screendensity = displaymetrics.densityDpi;
Log.i("screenHeight",""+screenHeight);
Log.i("screenWidth",""+screenWidth);
Log.i("screendensity",""+screendensity);
setContentView(R.layout.activity_main);
int letpading=(int)(116*(screenWidth/1024));
int toppading=(int)(79*(screenHeight/600));
int textsiz=(int)(50*(screendensity/600));
option121 = (TextView)findViewById(R.id.text1);
option121.setBackgroundResource(R.drawable.dog_b_blank);
option121.setText("A");
option121.setText(Color.BLACK);
RelativeLayout.LayoutParams layoutoption121 = (RelativeLayout.LayoutParams) option121.getLayoutParams();
layoutoption121.height=(int)(180*(screenHeight/600));
layoutoption121.width=(int)(180*(screenWidth/1024));
layoutoption121.topMargin=(int)(100*(screenHeight/600));
layoutoption121.leftMargin= (int)(250*(screenWidth/1024));
option121.setPadding(letpading, toppading, 0, 0);
option121.setTextSize(textsiz);
}
}

Thats not the way do it. Android takes care of text size for you, use 'sp' (scale-independent pixel) units when specifying text sizes and if you need to configure different sizes for different screens have a read of this:
Supporting Multiple Screens
Basically, you need to define your text sizes in .xml files in the appropriate resource directory:
res/values-large
res/values-xlarge
etc..
Then refer to those constants in your layout xml or your code.

Related

Custom Drawable not generating round corners for CardView's image

I created a list of Cards with the new CardView and RecyclerView that look this way:
I've tried to modify the card with round corners as explained by Mariotti in this post.
PROBLEM: The problem is that, as you can see from the screenshot I am only able to set the card's corner while the image remains squared.
In the example a custom Drawable class extending Drawable draws a rounded rectangle using Canvas.drawRoundRect(), and use a Paint with a BitmapShader to fill the rounded rectangle with a texture instead of a simple color, as also explained here.
In my Adapter I have:
#Override
public ContactViewHolder onCreateViewHolder(final ViewGroup viewGroup, int i) {
final View itemView = LayoutInflater
.from(viewGroup.getContext())
.inflate(R.layout.item_card_view, viewGroup, false);
CardView cardView = (CardView) itemView.findViewById(R.id.card_view);
ImageView imageView = (ImageView) itemView.findViewById(R.id.hImage);
Bitmap mBitmap = BitmapFactory.decodeResource(itemView.getResources(), R.drawable.background);
//Default
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
//Default
imageView.setBackgroundResource(R.drawable.background);
} else {
//RoundCorners
madapps.hellogridview.RoundCornersDrawable round = new madapps.hellogridview.RoundCornersDrawable(
mBitmap,
itemView.getResources().getDimension(R.dimen.cardview_default_radius)
, 5); //or your custom radius
cardView.setPreventCornerOverlap(false); //it is very important
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
imageView.setBackground(round);
else
imageView.setBackgroundDrawable(round);
}
//Set onClick listener
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int tag = (Integer) v.findViewById(R.id.hTitle).getTag();
Toast.makeText(viewGroup.getContext(), "Clickable card no: "+tag, Toast.LENGTH_LONG).show();
}
});
return new ContactViewHolder(itemView);
}
and I've overridden the value of R.dimen.cardview_default_radiusto 8dp, with no result! Any ideas?
I've solved it using this:
https://github.com/pungrue26/SelectableRoundedImageView
and applying a radius of 10dp (same as the card) to the top corners of the image:
<com.joooonho.SelectableRoundedImageView android:id="#+id/headerImage"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/cardbackground3"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
app:sriv_left_top_corner_radius="10dip"
app:sriv_right_top_corner_radius="10dip"
app:sriv_left_bottom_corner_radius="0dip"
app:sriv_right_bottom_corner_radius="0dip"
app:sriv_border_color="#333333"/>
Thanks thats exatly what I need. But you know there is one problem know. There is little space like padding between borders of CardView and Image. But there was no paddings in my case. It seems to mе that this library rounded corners but dont change position of image. Do you have the same think? By the way my layout the same as yours. Do you have any ideas about that?

using shared peferences to save colors

I have an app that uses a color picking dialog to change the app background color, and the text color. The color picker works fine, but when the app closes for any reason it reverts back to default.
I have checked: http://developer.android.com/guide/topics/data/data-storage.html#pref
and
Android Shared preferences example
the below code is the result of my research. The problem I'm having is all my text fields start off without text color, when i use the color dialog the colors change just fine, but are not saved.
Any pointers on where I'm going wrong would be greatly appreciated.
public class TipCalculator extends ActionBarActivity implements ColorPickerDialog.OnColorChangedListener {
//UI element objects to be manipulated.
TextView tipper;
TextView diner;
/*few TextView items left out to save space*/
int color;
RelativeLayout RLayout;
private SharedPreferences preferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tip_calculator);
preferences = getSharedPreferences("TipCalculator", MODE_PRIVATE);
//color = preferences.getInt("TipCalculator", color); did not change anything
color = preferences.getInt("bg_color", color);
RLayout = (RelativeLayout) findViewById(R.id.RLayout);//layout object for background color manipulation
bill = (EditText) findViewById(R.id.bill_amount_text);//UI elements placed in objects for text color manipulation
billNtip = (TextView) findViewById(R.id.bill_tip_text);
/*few TextView items left out to save space*/
bill.setSelection(bill.getText().length());
bill.addTextChangedListener(billWatcher);
}
#Override
public void onPause(){// onStop does not seem to change how the app currently runs
super.onPause();
/*preferences = getSharedPreferences("TipCalculator", MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit(); does not work*/
SharedPreferences.Editor editor = getSharedPreferences("TipCalculator", MODE_PRIVATE).edit();
//editor.putInt("TipCalculator", color); does not change anything
editor.putInt("bg_color", color);
editor.commit();
tipper.setTextColor(color);
bill.setTextColor(color);
/*few TextView items left out to save space*/
}
#Override
public void colorChanged(String key, int color) {
color = newColor;
if (decide.equals("font"))
{
tipper.setTextColor(color);
bill.setTextColor(color);
/*few TextView items left out to save space*/
}
else if (decide.equals("background"))
{
RLayout.setBackgroundColor(color);
}
}
Save the color to the SharedPreferences in onPause() instead of onResume(), like this:
#Override
public void onPause() {
SharedPreferences.Editor editor = getSharedPreferences("TipCalculator", MODE_PRIVATE).edit();
editor.putInt("bg_color", color);
editor.commit();
super.onPause();
}
onResume() is called when your app resumes, so if you exit but don't resume, the value won't get saved.
Somewhere in your initialization you will also need to read the color value out of the SharedPreferences e.g:
preferences = getSharedPreferences("TipCalculator", MODE_PRIVATE);
color = preferences.getInt("bg_color", android.R.color.white); // default to white or whatever color you want
tipper.setTextColor(color);
bill.setTextColor(color);
It doesn't look like you are setting the color on the tipper and bill
objects after you load it. In onCreate() after you call getInt() add
these lines: tipper.setTextColor(color); bill.setTextColor(color); You
will need to initialize these objects first obviously. – samgak
This was the final thing I was missing.
Thanks again for the help.

JDialog doesn't size correctly with wrapped JTextArea

While making a program, I noticed a bug with the JOptionPane.showMessageDialog() call. I use a button to create a JTextArea that wraps and then display a dialog containing this text area.
If the text area is too large, however, the dialog does not size itself correctly to the height of the JTextArea. The Dialog cuts off the OK button in this example.
I replicated the bug in the following code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogBug {
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final String text = "looooooooooooooooooooooong text looooooooooooooooooooooooooooooooooooooong text";
JButton button = new JButton();
button.setPreferredSize(new Dimension(30, 30));
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JTextArea area = new JTextArea(text, 0, 50);
area.setEditable(false);
area.setLineWrap(true);
area.setWrapStyleWord(true);
area.append(text);
area.append(text);
area.append(text);
JOptionPane.showMessageDialog(frame, area, "why does it do this", JOptionPane.WARNING_MESSAGE);
}
});
frame.add(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
I would post a picture, but I don't have enough reputation...
Is there a way to fix this without having to use a JScrollPane?
Here's a screenshot:
If you run the pack command on the dialog (a function in the Window class) it will resize based on subcomponents. For your case you will have to rewrite without using the showMessageDialog() to get the resize to work (so make the dialog first, add the text, pack, then show it)
Dialog b = new Dialog();
// add stuff
b.pack();
For my test code it worked perfectly to get the dialogs to be the right sizes
Without pack()
With pack()

Scaling in JavaFX and ScrollPanes

I've been trying to work with the scaling transform in JavaFX, but haven't quite been able to wrap my head around it. Basically, I have a Pane containing a complex graph and would like to be able to rescale it. The scaling part itself works fine, however, the enclosing scroll pane will not adapt to the graph.
For simplicity's sake, i'll post a short example in which my graph is replaced by a label:
public class TestApp extends Application {
#Override public void start(final Stage stage) throws Exception {
final Label label = new Label("Hello World");
label.getTransforms().setAll(new Scale(0.5, 0.5));
label.setStyle("-fx-background-color:blue");
label.setFont(new Font(200));
final ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(label);
stage.setScene(new Scene(scrollPane));
stage.setWidth(200);
stage.setHeight(100);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
The label will scale correctly, but the enclosing scroll pane's bars will still accomodate a component of the original size.
I've tried so far:
Playing around with the labels min and pref size
wrapping the label inside a Group (no scrollbars will appear whatsoever)
scaling the enclosing Group rather than the label
What am I missing? What can I do to make the ScrollPane adapt to the content view?
Thanks for your help.
According to the ScrollPane document you might try to wrap a Pane in a Group so the ScrollPane is scroll by visual bound not the actual layout bound.
ScrollPane layout calculations are based on the layoutBounds rather than the
boundsInParent (visual bounds) of the scroll node. If an application wants the
scrolling to be based on the visual bounds of the node (for scaled content etc.),
they need to wrap the scroll node in a Group.
I implemented scaling in a ScrollPane for Graphs and other nodes in
this example of scrollpane viewports, transforms and layout bounds in JavaFX.
The code was implemented when I was first learning JavaFX, so certainly the code could be cleaner and perhaps there are simpler ways to accomplish this (e.g. using a Group as the container for the scaled node as suggested in the ScrollPane documentation).
One key to getting the solution I wanted (ScrollBars only appearing when you are zoomed in and the node is larger than the visible viewport), was this code:
// create a container for the viewable node.
final StackPane nodeContainer = new StackPane();
nodeContainer.getChildren().add(node);
// place the container in the scrollpane and adjust the pane's viewports as required.
final ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(nodeContainer);
scrollPane.viewportBoundsProperty().addListener(
new ChangeListener<Bounds>() {
#Override public void changed(ObservableValue<? extends Bounds> observableValue, Bounds oldBounds, Bounds newBounds) {
nodeContainer.setPrefSize(
Math.max(node.getBoundsInParent().getMaxX(), newBounds.getWidth()),
Math.max(node.getBoundsInParent().getMaxY(), newBounds.getHeight())
);
}
});
...
// adjust the view layout based on the node scalefactor.
final ToggleButton scale = new ToggleButton("Scale");
scale.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent actionEvent) {
if (scale.isSelected()) {
node.setScaleX(3); node.setScaleY(3);
} else {
node.setScaleX(1); node.setScaleY(1);
}
// runlater as we want to size the container after a layout pass has been performed on the scaled node.
Platform.runLater(new Runnable() {
#Override public void run() {
nodeContainer.setPrefSize(
Math.max(nodeContainer.getBoundsInParent().getMaxX(), scrollPane.getViewportBounds().getWidth()),
Math.max(nodeContainer.getBoundsInParent().getMaxY(), scrollPane.getViewportBounds().getHeight())
);
}
});
}
});

Android getMeasuredHeight returns wrong values !

I'm trying to determine the real dimension in pixels of some UI elements !
Those elements are inflated from a .xml file and are initialized with dip width and height so that the GUI will eventually support multiple screen size and dpi (as recommended by android specs).
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="150dip"
android:orientation="vertical">
<ImageView
android:id="#+id/TlFrame"
android:layout_width="110dip"
android:layout_height="90dip"
android:src="#drawable/timeline_nodrawing"
android:layout_margin="0dip"
android:padding="0dip"/></LinearLayout>
This previous xml represent one frame. But I do add many dynamically inside a horizontal layout describe here :
<HorizontalScrollView
android:id="#+id/TlScroller"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_margin="0dip"
android:padding="0dip"
android:scrollbars="none"
android:fillViewport="false"
android:scrollbarFadeDuration="0"
android:scrollbarDefaultDelayBeforeFade="0"
android:fadingEdgeLength="0dip"
android:scaleType="centerInside">
<!-- HorizontalScrollView can only host one direct child -->
<LinearLayout
android:id="#+id/TimelineContent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_margin="0dip"
android:padding="0dip"
android:scaleType="centerInside"/>
</HorizontalScrollView >
The method defined to add one frame inside my java code :
private void addNewFrame()
{
LayoutInflater inflater = (LayoutInflater) _parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.tl_frame, null);
TextView frameNumber = (TextView) root.findViewById(R.id.FrameNumber);
Integer val = new Integer(_nFramesDisplayed+1); //+1 to display ids starting from one on the user side
frameNumber.setText(val.toString());
++_nFramesDisplayed;
_content.addView(root);
// _content variable is initialized like this in c_tor
// _content = (LinearLayout) _parent.findViewById(R.id.TimelineContent);
}
Then inside my code, I try to get the actual real size in pixel because I need this to draw some opengl stuff over it.
LayoutInflater inflater = (LayoutInflater) _parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.tl_frame, null);
ImageView frame = (ImageView) root.findViewById(R.id.TlFrame);
frame.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
frame.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
final int w = frame.getMeasuredWidth();
final int h = frame.getMeasuredHeight();
Everything seems to work fine except that those values are way bigger than the actual pixel size of the ImageView.
Reported infos from getWindowManager().getDefaultDisplay().getMetrics(metrics);
are the following :
density = 1,5
densityDpi = 240
widthPixel = 600
heightPixel = 1024
Now, I know the rule from android is : pixel = dip * (dpi /160). But nothing makes any sense with the value returned. For that ImageView of (90dip X 110dip), the returned values of the measure() method is (270 x 218) which I assumed is in pixel !
Anyone has any idea why ?
Is the value returned in pixel ?
By the way : I've been testing the same code but with a TextView instead than an ImageView and everything seems to be working fine ! Why !?!?
You're calling measure incorrectly.
measure takes MeasureSpec values which are specially packed by MeasureSpec.makeMeasureSpec. measure ignores LayoutParams. The parent doing the measuring is expected to create a MeasureSpec based on its own measurement and layout strategy and the child's LayoutParams.
If you want to measure the way that WRAP_CONTENT usually works in most layouts, call measure like this:
frame.measure(MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST));
If you don't have max values (for example if you're writing something like a ScrollView that has infinite space) you can use the UNSPECIFIED mode:
frame.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
Do that:
frame.measure(0, 0);
final int w = frame.getMeasuredWidth();
final int h = frame.getMeasuredHeight();
Solved!
Ok ! Kind of Answering my own question here...But not completly
1 - It seems that on some devices, The ImageView measuring do not provide with exact values. I've seen lots of reports on this happenning on Nexus and Galaxy devices for example.
2 - A work around that I've come up with :
Set the width and height of your ImageView to "wrap_content" inside xml code.
Inflate the layout inside your code (generally in the UI initialization I suppose).
LayoutInflater inflater = (LayoutInflater)
_parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.tl_frame, null);
ImageView frame = (ImageView) root.findViewById(R.id.TlFrame);
Calculate your own ratio for your image view, based on the typical Android calculation
//ScreenDpi can be acquired by getWindowManager().getDefaultDisplay().getMetrics(metrics);
pixelWidth = wantedDipSize * (ScreenDpi / 160)
Use the calculated size to set your ImageView dynamycally inside your code
frame.getLayoutParams().width = pixeWidth;
And voila ! your ImageView has now the wanted Dip size ;)
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
//now we can retrieve the width and height
int width = view.getWidth();
int height = view.getHeight();
//this is an important step not to keep receiving callbacks:
//we should remove this listener
//I use the function to remove it based on the api level!
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN){
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}else{
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
One should go with How to get width/height of a View
Unfortunately, in Activity lifecycle methods such as Activity#onCreate(Bundle), a layout pass has not yet been performed, so you can't yet retrieve the size of views in your view hierarchy. However, you can explicitly ask Android to measure a view using View#measure(int, int).
As #adamp's answer points out, you have to provide View#measure(int, int) with MeasureSpec values, but it can be a bit daunting figuring out the correct MeasureSpec.
The following method tries to determine the correct MeasureSpec values and measures the passed in view:
public class ViewUtil {
public static void measure(#NonNull final View view) {
final ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
final int horizontalMode;
final int horizontalSize;
switch (layoutParams.width) {
case ViewGroup.LayoutParams.MATCH_PARENT:
horizontalMode = View.MeasureSpec.EXACTLY;
if (view.getParent() instanceof LinearLayout
&& ((LinearLayout) view.getParent()).getOrientation() == LinearLayout.VERTICAL) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
horizontalSize = ((View) view.getParent()).getMeasuredWidth() - lp.leftMargin - lp.rightMargin;
} else {
horizontalSize = ((View) view.getParent()).getMeasuredWidth();
}
break;
case ViewGroup.LayoutParams.WRAP_CONTENT:
horizontalMode = View.MeasureSpec.UNSPECIFIED;
horizontalSize = 0;
break;
default:
horizontalMode = View.MeasureSpec.EXACTLY;
horizontalSize = layoutParams.width;
break;
}
final int horizontalMeasureSpec = View.MeasureSpec
.makeMeasureSpec(horizontalSize, horizontalMode);
final int verticalMode;
final int verticalSize;
switch (layoutParams.height) {
case ViewGroup.LayoutParams.MATCH_PARENT:
verticalMode = View.MeasureSpec.EXACTLY;
if (view.getParent() instanceof LinearLayout
&& ((LinearLayout) view.getParent()).getOrientation() == LinearLayout.HORIZONTAL) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
verticalSize = ((View) view.getParent()).getMeasuredHeight() - lp.topMargin - lp.bottomMargin;
} else {
verticalSize = ((View) view.getParent()).getMeasuredHeight();
}
break;
case ViewGroup.LayoutParams.WRAP_CONTENT:
verticalMode = View.MeasureSpec.UNSPECIFIED;
verticalSize = 0;
break;
default:
verticalMode = View.MeasureSpec.EXACTLY;
verticalSize = layoutParams.height;
break;
}
final int verticalMeasureSpec = View.MeasureSpec.makeMeasureSpec(verticalSize, verticalMode);
view.measure(horizontalMeasureSpec, verticalMeasureSpec);
}
}
Then you can simply call:
ViewUtil.measure(view);
int height = view.getMeasuredHeight();
int width = view.getMeasuredWidth();
Alternatively, as #Amit Yadav suggested, you can use OnGlobalLayoutListener to have a listener called after the layout pass has been performed. The following is a method that handles unregistering the listener and method naming changes across versions:
public class ViewUtil {
public static void captureGlobalLayout(#NonNull final View view,
#NonNull final ViewTreeObserver.OnGlobalLayoutListener listener) {
view.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
final ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
viewTreeObserver.removeOnGlobalLayoutListener(this);
} else {
//noinspection deprecation
viewTreeObserver.removeGlobalOnLayoutListener(this);
}
listener.onGlobalLayout();
}
});
}
}
Then you can:
ViewUtil.captureGlobalLayout(rootView, new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int width = view.getMeasureWidth();
int height = view.getMeasuredHeight();
}
});
Where rootView can be the root view of your view hierarchy and view can be any view within your hierarchy that you want to know the dimensions of.
You have to create Custom Textview and use it in your layouts and use getActual height function to set the height at runtime
public class TextViewHeightPlus extends TextView {
private static final String TAG = "TextViewHeightPlus";
private int actualHeight=0;
public int getActualHeight() {
return actualHeight;
}
public TextViewHeightPlus(Context context) {
super(context);
}
public TextViewHeightPlus(Context context, AttributeSet attrs) {
super(context, attrs);
setCustomFont(context, attrs);
}
public TextViewHeightPlus(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
actualHeight=0;
actualHeight=(int) ((getLineCount()-1)*getTextSize());
}
}
Probably, because of what you have in AndroidManifest.xml (link) file and from which drawable-XXX directory the xml file comes, Android loads resources with scaling operation. You decide to use "dip" (link) dimension unit which is virtual and the real value (px) can be different.

Resources