How to find layout_marginTop - android

I have an XML file with the following attritubes:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/al_cs_layout1"
android:gravity="center_vertical">
<ImageView android:id="#+id/cs_track"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/fader_background5"
android:layout_marginLeft="0dp"
android:layout_marginTop="20dp" >
</ImageView>
...
and here is my java code:
public void initialize(Context context)
{
Log.d("initialize (MySeekBar)","initialize");
setWillNotDraw(false);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view1 = inflater.inflate(R.layout.custom_seekbar, this);
layout1 = (RelativeLayout)view1.findViewById(R.id.al_cs_layout1);
track = (ImageView)layout1.findViewById(R.id.cs_track);
thumb = (ImageView)layout1.findViewById(R.id.cs_thumb);
...
I am working on a custom seekbar which determines the top by using a variable marginTop = 20; however this was oringally made on a phone much older by a different programmer. The 20 suppose to represent the margin top defined in the XML however it is using dp and not pixels. how can I find the marginTop attribute of R.id.cs_track? It works great on the old phone but on any phone does doesn't have the same screen size of dp it will create an undesired offset.

Use MarginLayoutParams to get value in pixels:
track = (ImageView)layout1.findViewById(R.id.cs_track);
MarginLayoutParams params = (MarginLayoutParams)track.getLayoutParams();
int marginTopPixelSize = params.topMargin;

Related

Layout setVisibility() in java no effect

this is the floagingview.It can drag...
I need to set the layout to hide or show in the code.
problem : listview_left、listview_left no way to hide or show
FloatingView.java
This code has hidden settings but has no effect.
listview_left.setVisibility(View.GONE) and listview_right.setVisibility(View.GONE)
public FloatingView(Context context, FloatingViewConfig config) {
this.mContext = context;
mWindowManager = (WindowManager) context.getSystemService(WINDOW_SERVICE);
rootView = LayoutInflater.from(context).inflate(R.layout.playground_float_view, null, false);
this.config = config;
if (config.displayWidth == Integer.MAX_VALUE) {
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
config.displayWidth = metrics.widthPixels;
}
if (config.displayHeight == Integer.MAX_VALUE) {
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
config.displayHeight = (int) (metrics.heightPixels - 25 * metrics.density);
}
config.paddingLeft = dp2px(config.paddingLeft);
config.paddingTop = dp2px(config.paddingTop);
config.paddingRight = dp2px(config.paddingRight);
config.paddingBottom = dp2px(config.paddingBottom);
rootView.measure(0, 0);
width = rootView.getMeasuredWidth();
height = rootView.getMeasuredHeight();
screen_widht = mWindowManager.getDefaultDisplay().getWidth();
screen_height = mWindowManager.getDefaultDisplay().getHeight();
mFloatLayout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.playground_float_view, null);
listview_left = mFloatLayout.findViewById(R.id.listview_left);
listview_right = mFloatLayout.findViewById(R.id.listview_right);
x = 0;
y = 0;
listview_left.setVisibility(View.GONE);
listview_right.setVisibility(View.GONE);
Log.d(TAG,"初始化(left,right) : " + listview_left.getVisibility() + ", " + listview_right.getVisibility());
}
float_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/float_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/floating_layout_shape"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/listview_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/floating_view_list2" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/floating_view_list3" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/floating_view_list1" />
</LinearLayout>
<ImageView
android:id="#+id/float_image"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/floating_view_menu"/>
<LinearLayout
android:id="#+id/listview_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/float_image"
android:visibility="visible">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/floating_view_list1" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/floating_view_list3" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/floating_view_list2" />
</LinearLayout>
</LinearLayout>
This is the complete code and it is run!!!
link: https://github.com/sheng855174/Test
How can i solve?
The answer here is good, but maybe it was misinterpreted. I will try to explain it differently here https://stackoverflow.com/a/60161868/910718
mFloatLayout should be completely replaceable with rootView, inflating the layout twice means you have 2 completely separate versions of that layout, one in mFloatLayout and another in rootView. Changes to mFloatLayout would not change anything to the Views in rootView.
I see that the view is added here:
public void showOverlayActivity() {
if (isShowing) {
return;
}
type = TYPE.OVERLAY_ACTIVITY;
initParams();
initPosition();
initWindowView();
isShowing = true;
mWindowManager.addView(rootView, mParamsWindowManager);
}
So the View that is rendered on the screen is not the View where you have extracted the listview_left and listview_right from, because as stated, the second inflate is creating a completely new instance of the layout with no association with the layout that is being added to the screen in this code.
I would encourage that FloatingView extend LinearLayout, that the outer LinearLayout is replaced with a merge tag, and that View.inflate like this: inflate(context, R.layout.playground_float_view, this). This makes the FloatingView equal the float_view layout and the mFloatLayout and rootView become unnecessary.
you don't need to inflate playground_float_view 2 times.
just remove below line from your code -
mFloatLayout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.playground_float_view, null);
and get listview_left and listview_left like below -
listview_left = (LinearLayout)rootView.findViewById(R.id.listview_left);
listview_right = (LinearLayout)rootView.findViewById(R.id.listview_right);
hope this will help!!

Android: how to configure sizing of a custom layout

I've been trying to create a custom horizontal layout with the goal to have a TextView to the left of an ImageView, containing a icon which depicts a certain status. The ImageView is to kept in a square dimension, with it's height and width equal to the height of the text in the TextView. Issues continue to persist, however, such as the text height not being set as specified in the layout xml file and an unknown padding existing after the ImageView. These problem can be seen in this image, with the red indicating the unknown padding and the blue indicating the text size inconsistency where both where set to 12sp. The font sizing and padding issues need to be fixed so the layout can be properly added to a grid layout, which will contain a grid of these custom layouts.
StatusIcon.java
//This is part of the java class that extends ImageView to resize the Icon
#Override
protected void onMeasure(int width, int height) {
super.onMeasure(width, height);
int measuredHeight = getMeasuredHeight();
setMeasuredDimension(measuredHeight, measuredHeight);
}
StatusIndicator.java
//This is the java class for the custom layout.
public class StatusIndicator extends LinearLayout {
private TextView label;
private StatusIcon statusLed;
private CharSequence labelText;
private float labelTextSize;
public enum Status {
GOOD,
WARNING,
CRITICAL
}
/*
* Removed the basic required class constructors to save space.
*/
private void getAttributes(Context context, AttributeSet attrs){
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StatusIndicator);
labelText = typedArray.getString(R.styleable.StatusIndicator_label);
labelTextSize = typedArray.getDimensionPixelSize(R.styleable.StatusIndicator_labelSize, 0);
typedArray.recycle();
}
private void initializeViews(Context context){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.view_status_indicator, this);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
//Setup UI elements in layout
label = (TextView) findViewById(R.id.textView_statusIndicatorLabel);
statusLed = (StatusIcon) findViewById(R.id.imageView_statusIndicatorLed);
label.setText(labelText);
if(labelTextSize > 0){
label.setTextSize(TypedValue.COMPLEX_UNIT_SP, labelTextSize);
}
}
public void setStatus(StatusIndicator.Status status){
switch (status){
case GOOD:
statusLed.setImageResource(R.mipmap.ic_status_panel_good);
break;
case WARNING:
statusLed.setImageResource(R.mipmap.ic_status_panel_warning);
break;
case CRITICAL:
statusLed.setImageResource(R.mipmap.ic_status_panel_critical);
break;
}
}
}
view_status_indicator.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"
xmlns:tools="http://schemas.android.com/tools"
tools:parentTag="LinearLayout"
tools:orientation="horizontal">
<TextView
android:id="#+id/textView_statusIndicatorLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|start"
android:layout_marginEnd="2dp"
android:text="#string/default_title"
android:textAppearance="#style/TextAppearance.AppCompat.Title"
android:textSize="12sp"/>
<com.css_design.android_quickbridge.ui.home.status_panel.StatusIcon
android:id="#+id/imageView_statusIndicatorLed"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="center_vertical|end"
app:srcCompat="#mipmap/ic_status_panel_critical"/>
</merge>
I would solve this problem by using ConstraintLayout instead of creating a custom view implementation.
ConstraintLayout allows you to specify an aspect ratio for its children, which takes care of wanting to make sure your ImageView is always exactly square. ConstraintLayout also allows you to specify height or width based on sibling views (by combining a dimension of 0dp with top and bottom (or left and right) constraints).
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ccf">
<ImageView
android:id="#+id/image"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="#drawable/circle"
app:layout_constraintTop_toTopOf="#+id/text"
app:layout_constraintLeft_toRightOf="#+id/text"
app:layout_constraintBottom_toBottomOf="#+id/text"
app:layout_constraintDimensionRatio="1"/>
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40sp"
android:text="hello world"/>
</android.support.constraint.ConstraintLayout>
(Background color added to the ConstraintLayout to show that it's not any larger than its contents).

android fill all screen by gridview

I have a gridview and make a custom adapter for fill it, user can set by spinner rows and columns of my grid. In each cell of grid I set a videoview.
So I need to set dinamically the size for each videoview in my custom Adapter in order to fill the remaining part of the screen. Following this I can do the task, I take display size and set layout for my view dividing by the number of rows and columns.
The problem is that principal layout has action-bar and a textview . So, windows size is not correct. I need to subtract action-bar and textview size.
I find a solution for know action-bar size, but when get height of my textview it is always 0.
As suggest here I should take textview size after rendering, but for render my gridview I need to know this size !!
There are other ways to do it ? It's necessary to manually calculate view size ??
this is my layout
<?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="fill_parent"
android:layout_height="fill_parent"
tools:context="it.nexera.visiamobile.ViewLiveMultiActivity"
>
<TextView
android:id="#+id/txt_grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="#454545"
android:gravity="left"
android:text="#string/sel_grid" />
<Spinner
android:id="#+id/grid_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/gridview"
android:layout_toRightOf="#+id/txt_grid" />
<GridView
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchMode="columnWidth"
android:layout_below="#+id/txt_grid"
android:gravity="center"
/>
</RelativeLayout>
and this is my getView method for custom adapter :
// create a new VideoView for each item referenced by the Adapter
#SuppressLint("NewApi")
public View getView(int position, View convertView, ViewGroup parent) {
VideoView videoView;
if (convertView == null) { // if it's not recycled, initialize some attributes
videoView = new VideoView(mContext);
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int width=0;
int height=0;
if (android.os.Build.VERSION.SDK_INT >= 13){
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
else{
width = display.getWidth();
height = display.getHeight();
}
// Calculate ActionBar height
TypedValue tv = new TypedValue();
int actionBarHeight=0;
if (mContext.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
{
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,mContext.getResources().getDisplayMetrics());
}
TextView textview = (TextView) ((Activity) mContext).findViewById (it.nexera.visiamobile.R.id.txt_grid);
int textview_height=textview.getHeight();
height=height-actionBarHeight-textview_height;
AbsListView.LayoutParams param = new AbsListView.LayoutParams(
(width/COL_NUMBER),
(height/ROW_NUMBER));
videoView.setLayoutParams(param);
Uri video = Uri.parse(mvideoSrc[position]);
videoView.setVideoURI(video);
videoView.start();
} else {
videoView = (VideoView) convertView;
}
return videoView;
}
Your problem is that you retrieve at the beginning the size of the whole screen of your device.
So ActionBar must be substracted, but any other views if your layout doesn't take all the remaining space. So your method contradicts android modularity, for example, if your view is used in different ways depending on the size of the device.
I think what you need instead is using ViewTreeObserver, like this :
final View myView = ... // The RelativeLayout that's declared as root of your layout file
myView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// You can here use View.getMeasuredWidth() or View.getMeasuredHeight() which correspond to the available space for the view containing your GridView and your TextView and then set your TextView's size
}
}
Edit : To make the gridview fill all remaining space you can instead use a LinearLayout, using its weight attribute :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:weightSum="1"
tools:context="it.nexera.visiamobile.ViewLiveMultiActivity"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/txt_grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="#454545"
android:gravity="left"
android:text="#string/sel_grid" />
<Spinner
android:id="#+id/grid_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<GridView
android:id="#+id/gridview"
android:layout_width="0dp"
android:layout_height="0dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:layout_weight="1"
/>
</LinearLayout>
Have you tried by adding a RelativeLayout under the Grid, and adding two hidden views on it, one in the topleft corner, and another one in the bottoright corner (1dip height/width, for example). Then, from code you can findViewById them, and call getLocationOnScreen. It's just the first dirty idea that came to my mind. That way you can get the exact size in pixels (or dpi) of the Grid.

Accurate way to determine the measured height of a view, even before it changed from GONE to VISIBLE

Currently, I have a layout which looks like this. It contains.
Title text view, and Price text view, which is visible always.
Description Text View, which can be visible or gone, depending expanding or collapsing.
Collapsing (During app startup)
Expanding (When user taps on it)
I want to have some nice animation around it. So, I referred to https://stackoverflow.com/a/13381228/72437
One of the key element, is to know the exact height of Description Text View, even before it is visible.
However, I realize a few type of code. They are't accurate
// v is description text view.
v.measure(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
final int targtetHeight = v.getMeasuredHeight();
// v is description text view.
v.measure(MeasureSpec.makeMeasureSpec(LayoutParams.MATCH_PARENT, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.EXACTLY));
final int targtetHeight = v.getMeasuredHeight();
This will return value 32. (The correct measured height suppose to be 92). This is the height for first line of text. This ends up my animation is ended at
May I know, what is the correct way to determine the measured height of a view, even before it changed from GONE to VISIBLE?
My layout code is as followed :
<LinearLayout
android:clickable="true"
android:id="#+id/chart_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#drawable/dummy"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:width="0dp"
android:layout_weight="0.6"
android:layout_height="match_parent"
android:gravity="left"
android:textSize="20sp"
android:textColor="#ff000000"
android:text="Summary chart" />
<TextView
android:id="#+id/chart_price_text_view"
android:layout_width="0dp"
android:width="0dp"
android:layout_weight="0.4"
android:layout_height="match_parent"
android:gravity="right"
android:textSize="20sp"
android:textColor="#ffF76D3C"
android:text="$2.99" />
</LinearLayout>
<TextView
android:visibility="gone"
android:id="#+id/chart_description_text_view"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/currency_exchange_description"
android:textColor="#ff626262"
android:textSize="15sp" />
</LinearLayout>
Your 2nd code snippet is almost correct, but you need to specify pixel sizes - not FILL_PARENT/MATCH_PARENT. This should work:
v.measure(MeasureSpec.makeMeasureSpec(parentView.getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(MAX_HEIGHT, MeasureSpec.AT_MOST));
final int targetHeight = v.getMeasuredHeight();
You'll need to have a reference to the ViewGroup that v is a child of to get its width, and define MAX_HEIGHT (or perhaps use the parent View's height?).
Also, you should change the height parameters of the two TextViews that are within the horizontal LinearLayout to wrap_content, as using match_parent here may cause problems. The LinearLayout is set to wrap_content, but the two children don't specify a height.
I accomplished this for my accordion component. I was facing the exact same issue, of expanding my accordion which required the 'destination' height, that is, the height that it would take after the expansion.
This returns the correct height:
/***
* This function returns the actual height the layout. The getHeight() function returns the current height which might be zero if
* the layout's visibility is GONE
* #param layout
* #return
*/
public static int getFullHeight(ViewGroup layout) {
int specWidth = View.MeasureSpec.makeMeasureSpec(0 /* any */, View.MeasureSpec.UNSPECIFIED);
int specHeight = View.MeasureSpec.makeMeasureSpec(0 /* any */, View.MeasureSpec.UNSPECIFIED);
layout.measure(specWidth,specHeight);
int totalHeight = 0;//layout.getMeasuredHeight();
int initialVisibility = layout.getVisibility();
layout.setVisibility(View.VISIBLE);
int numberOfChildren = layout.getChildCount();
for(int i = 0;i<numberOfChildren;i++) {
View child = layout.getChildAt(i);
if(child instanceof ViewGroup) {
totalHeight+=getFullHeight((ViewGroup)child);
}else {
int desiredWidth = View.MeasureSpec.makeMeasureSpec(layout.getWidth(),
View.MeasureSpec.AT_MOST);
child.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight+=child.getMeasuredHeight();
}
}
layout.setVisibility(initialVisibility);
return totalHeight;
}
You can take a look at the accordion component and the animation on GitHub: Android Accordion View

Move two side by side textviews to be one under another if text is too long

I have two textviews like this:
=======================
= TextView1 TextView2 =
=======================
And I would like to detect when the textviews are too long such that they are displayed like this:
=======================
= TextView1 =
= TextView2 =
=======================
currently for longer text, it is displayed like this:
=======================
= TextView1 Text =
= View2 =
=======================
how can I do this, such that when the text is short the textviews are side by side and when it is too long, the second textview is not splitted but moved to the second line?
I tought at a solution to create a single textview and build the text according to length (text 1 + padding + text 2 if short, and text 1 + "\n" + text 2 if long) but I do not like this solution.
Is there any way to detect if the second text will be split such that to change the orientation of the layout that contains the textviews from horizontal cu vertical?
UPDATE
This is my xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<TextView
android:id="#+id/my_text_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="10dp"
android:text="#string/text1"/>
<TextView
android:id="#+id/my_text_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"/>
</LinearLayout>
I have found a better solution. Changed my textviews into autoresizable textviews (more info here)
Also, each textview is in a separate layout, to make sure both textviews are resized to the same value.
My xml looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/value_linear_layout"
android:gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
<com.mihaela.view.AutoResizeTextView
android:id="#+id/my_text_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content">
<com.mihaela.view.AutoResizeTextView
android:id="#+id/my_text_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
and I have implemented the OnTextResizeListener from AutoResizeTextView to do this:
public class TextWidthResizeListener implements OnTextResizeListener {
#Override
public void onTextResize(TextView textView, float oldSize, float newSize) {
TextPaint paint = textView.getPaint();
if (paint.measureText(textView.getText().toString()) > (valueLinearLayout.getWidth() / 2)){
valueLinearLayout.setOrientation(LinearLayout.VERTICAL);
}
}
}
where valueLinearLayout is:
valueLinearLayout = (LinearLayout)findViewById(R.id.value_linear_layout);
This solution best fits for me, as the textviews are dimensioned when they are side by side until a minimum size. When the minimum size is reached, and the text still does not fit, the textviews will be aligned one under another.
Also, this idea with the listener can be applied to non-resizable textviews also.
I will set this answer as the correct one.
You should use a single, multi-line TextView and set the text as follows :
mTextView.setText(text1+" "+text2);
or
mTextView.setText(text1+"\n"+text2);
depending on your particular needs.
EDIT: you could specify your text in html, and then use Html.fromHtml(htmlString) and display this text in your TextView.
String text1 ="<font color=\"red\">This is some text!</font>"
String text2="<font color=\"blue\">This is some other text!</font>"
textView.setText(Html.fromHtml(text1+ "<br/>"+ text2);
I made a slightly different version of the accepted answer. I did not alter my layout xml in any way and did not use onTextResize() or AutoResizeTextView as that seemed an overkill for my situation. I needed my LinearLayout to switch from Horizontal orientation to Vertical orientation if the device's language setting caused a long string to be used.
Layout
<LinearLayout
android:id="#+id/customer_care_bottom_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:layout_marginBottom="#dimen/lmargin_bottom_10">
<TextView
android:id="#+id/customer_care_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/CUSTOMER_CARE_TITLE" />
<TextView
android:id="#+id/customer_care_number_information"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/CUSTOMER_CARE_INFORMATION"/>
</LinearLayout>
Java
private void setCustomerServiceLayoutOrientationBasedOnTextWidth() {
TextPaint paint = customer_care_number_text.getPaint();
TextView tvCustomerCareTitle = (TextView) findViewById(R.id.customer_care_title);
TextView tvCustomerCareInformation = (TextView) findViewById(R.id.customer_care_information);
int halfCustomerServiceLayoutWidth = getScreenWidth() / 2;
boolean isCustomerCareTitleTooLong = paint.measureText(tvCustomerCareTitle.getText().toString()) > customerServiceLayoutWidth;
boolean isCustomerCareInformationTooLong = paint.measureText(tvCustomerCareInformation.getText().toString) > customerServiceLayoutWidth;
if (isCustomerCareTitleTooLong || isCustomerCareInformationTooLong) {
LinearLayout llCustomerCareBottom = (LinearLayout) findViewById(R.id.customer_care_bottom_layout);
llCustomerCareBottom.setOrientation(LinearLayout.VERTICAL);
}
}
private int getScreenWidth() {
int screenWidth;Display display = getWindowManager().getDefaultDisplay();
if (Build.VERSION.SDK_INT < 13) {
screenWidth = display.getWidth();
} else {
Point point = new Point();
display.getSize(point);
screenWidth = point.x;
}
return screenWidth;
}

Categories

Resources