Last row of expandable listview not full view in android - android

Here I uses view and there code as per given below.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TableRow
android:id="#+id/tab_stone_info"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_marginTop="1dp"
android:background="#color/styleBreakTabColor"
android:weightSum="9">
<TextView
android:id="#+id/stone_Type"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/cell_shape"
android:gravity="center"
android:text="#string/Type"
android:textColor="#color/txtStyleBreakup"
android:textSize="12sp" />
<TextView
android:id="#+id/stone_Shape"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/cell_shape"
android:gravity="center"
android:text="#string/Shape"
android:textColor="#color/txtStyleBreakup"
android:textSize="12sp" />
<TextView
android:id="#+id/stone_Qlty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/cell_shape"
android:gravity="center"
android:text="#string/Quality"
android:textColor="#color/txtStyleBreakup"
android:textSize="12sp" />
<TextView
android:id="#+id/stone_Grade"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/cell_shape"
android:gravity="center"
android:text="#string/Grade"
android:textColor="#color/txtStyleBreakup"
android:textSize="12sp" />
<TextView
android:id="#+id/stone_Qty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/cell_shape"
android:gravity="center"
android:text="#string/Qty"
android:textColor="#color/txtStyleBreakup"
android:textSize="12sp" />
<TextView
android:id="#+id/stone_Wt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/cell_shape"
android:gravity="center"
android:text="#string/Wt"
android:textColor="#color/txtStyleBreakup"
android:textSize="12sp" />
<TextView
android:id="#+id/stone_MMSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/cell_shape"
android:gravity="center"
android:text="#string/MMSize"
android:textColor="#color/txtStyleBreakup"
android:textSize="12sp" />
<TextView
android:id="#+id/stone_Setting"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/cell_shape"
android:gravity="center"
android:text="#string/Setting"
android:textColor="#color/txtStyleBreakup"
android:textSize="12sp" />
<TextView
android:id="#+id/stone_SettMode"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/cell_shape"
android:gravity="center"
android:text="#string/SettingMode"
android:textColor="#color/txtStyleBreakup"
android:textSize="12sp" />
</TableRow>
<RelativeLayout
android:id="#+id/layout_tab_stone_info_value"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.mindtech.ExpandableHeightListView
android:id="#+id/listviewstone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#00000000"
android:gravity="center"
android:horizontalSpacing="2dp"
android:isScrollContainer="false"
android:stretchMode="columnWidth"
android:verticalSpacing="20dp"
/>
</RelativeLayout>
</LinearLayout>
And I uses epandablelistview as below class.
public class ExpandableHeightListView extends ListView
{
boolean expanded = false;
public ExpandableHeightListView(Context context, AttributeSet attrs,
int defStyle)
{
super(context, attrs, defStyle);
}
public ExpandableHeightListView(Context context)
{
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
// MeasureSpec.AT_MOST);
//
// super.onMeasure(widthMeasureSpec, expandSpec);
// int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
// Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
// super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
// ViewGroup.LayoutParams params = getLayoutParams();
// params.height = getMeasuredHeight();
if (isExpanded())
{
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
I refer this question but did not get correct.
Grid of images inside ScrollView
Gridview height gets cut
The main problem occur when first row height is not biger than second or other. if all row content length are same then no issues.

It looks like you are getting the LayoutParams for your ListView, modifying the height parameter, but you are never calling setLayoutParams to tell the view to use the modified height. Try this:
if (isExpanded()) {
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
//Add this line
setLayoutParams(params);
}
Also, I've ran into problems in the past with the onMeasure() method, not everything is measured when the framework calls that method. You might try a ViewTreeObserver, where you can register a listener to be notified when the full view is laid out, like this:
final LinearLayout layout = (LinearLayout) findViewById(R.id.layout_id);
ViewTreeObserver vto;
if (layout != null) {
vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//Modify your LayoutParams here
}
});
}

If there's only one child, then it's better to use ExpandableListView or RecyclerView with different layouts. Here is a complete and very good tutorial on using ExpandableListView.
While using ListView, it always adds height which is a bit less than the original one (or may be there's another case, but I don't know why. If someone knows, than kindly correct me). So you have to add some dp's height manually at the end.
I've done it by overriding onDraw method. Below is how I did it.
#Override
protected void onDraw(Canvas canvas) {
params = getLayoutParams();
if (getCount() != old_count) {
old_count = getCount();
params.height = getCount() * (old_count > 0 ? getChildAt(0).getHeight()+5 : 0);
//I've added 5 pixels with each item to get proper height, you can alter it as per your need
setLayoutParams(params);
}
super.onDraw(canvas);
}

You are modifying the height, but you are not passing it to the view.
Use this method, setLayoutParams(params);

Related

scrollview with listview not working

I've only included one direct child in the scroll view , and i've added the below codes in the java files. When i remove the Utility method the listview appear fully, but doesnt work as a scrollview
ScrollView sv_fragment_globe;
sv_fragment_globe = (ScrollView)rowView.findViewById(R.id.sv_fragment_globe);
sv_fragment_globe.smoothScrollTo(0,0);
Utility.setListViewHeightBasedOnChildren(holder.lv_globe);
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/sv_fragment_globe"
android:fillViewport="true"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:orientation="vertical"
>
<ImageView
android:layout_width="fill_parent"
android:layout_height="200dp"
android:src="#drawable/home_hospital1"
android:id="#+id/iv_vp_globe"
android:scaleType="fitXY"
/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/lv_globe"
>
</ListView>
</LinearLayout>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
If you have more than two scrolling views inside any Layout, then the parent scrolling view will only scrolls. Follow the steps below to allows the child's scrolling elements to scroll.
Step 1:
Create a custom ListView.
public class ExpandableHeightListView extends ListView
{
boolean expanded = false;
public ExpandableHeightListView(Context context)
{
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs,int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// But do not use the highest 2 bits of this integer; those are
// reserved for the MeasureSpec mode.
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
Step 2: Add the line below after initializing the Listview object.
lv_selected_time_zone.setExpanded(true);
Try this
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="#android:drawable/home_hospital"
android:id="#+id/iv_vp_globe"
android:scaleType="fitXY"
/>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/lv_globe"
android:layout_weight="1"
>
</ListView>
</LinearLayout>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

Scrollview only Works in Listview

I have the following layout defined in my app:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/disco_photo"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/disco_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="#id/disco_photo"
android:layout_alignParentLeft="true"
android:layout_gravity="left"
android:layout_margin="8dp"
android:gravity="end"
android:textSize="20sp"
android:textStyle="italic" />
<TextView
android:id="#+id/disco_times"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="#id/disco_name"
android:layout_alignParentLeft="true"
android:layout_gravity="left"
android:layout_margin="8dp"
android:gravity="end"
android:textSize="20sp"
android:textStyle="italic"
android:visibility="gone" />
<ListView
android:id="#+id/disco_parties"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/disco_times"
android:layout_alignParentLeft="true"
android:layout_gravity="left"
android:layout_margin="8dp"
android:text="#string/map_view"
android:gravity="end"
android:textSize="20sp"
android:textStyle="italic" />
<RatingBar
android:id="#+id/disco_rating"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="#id/disco_parties"
android:numStars="5"
android:stepSize="1.0"
android:rating="3.0"
android:visibility="gone" />
<TextView
android:id="#+id/disco_map"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="#id/disco_rating"
android:layout_alignParentLeft="true"
android:layout_gravity="left"
android:layout_margin="8dp"
android:text="#string/map_view"
android:gravity="end"
android:textSize="20sp"
android:textStyle="italic" />
</RelativeLayout>
</ScrollView>
I want to get scroll in the whole layout but the problems comes when only ListView is getting the scrollbar, so you can only scroll this list. The rest of the layour is fixed to the screen height.
How can I make the whole layout be scrollable? Thanks in advance.
I am going through your problem. You can not use list view inside the scroll-view directly. If you want to use it, then you have to give height pragmatically to list view and it work for me.
public class test1 extends Activity {
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test1);
...
//here 1st set your list view than call set_List_View_Height_Based_On_Children...
set_List_View_Height_Based_On_Children(your_Listview_name);
...
}
///method set_List_View_Height_Based_On_Children
public static void set_List_View_Height_Based_On_Children(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
}
ListView can't be placed inside a ScrollView unless you define that your ListView isn't scrollable. If you wanna do this you should create a custom ListView like the following
public class NonScrollListView extends ListViewCompat {
//Define a public constructor
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = View.MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
You should not use a ListView in a ScroolView, it has it's own scroll and they interfere with each-other.
I would recommend creating a list adapter that creates all of your different views from an array using a switch statement:
class MyAdapter extends ArrayAdapter{
public MyAdapter(Context context, int resource, List objects) {
super(context, resource, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewItem viewType = getItem(position);
switch(viewType.type){
case TEXTVIEW: convertView = LayoutInflater.from(getContext()).inflate(R.layout.textView1, parent, false);
break;
case LISTITEM: convertView = LayoutInflater.from(getContext()).inflate(R.layout.listItem, parent, false);
break;
}
return convertView;
}
}

How to set Viewpager height from its Adapter

Hi friends I'm working on an app which contains a ViewPager having heading and its description in each view. Initially only 3 lines of those description has to be shown but when clicked it will expand to full description.
I tried doing these but unfortunately couldn't achieve it. So, anyone can please help me with these.. Thanks in advance.
Xml
<RelativeLayout android:id="#+id/llDescriptionMap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.explorelife.CustomViews.CustomViewPager
android:id="#+id/vpDescriptionMap"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.viewpagerindicator.CirclePageIndicator
android:id="#+id/indicatorDescriptionMap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/vpDescriptionMap"
android:padding="2dp"
app:radius="5dp" />
</RelativeLayout>
CustomViewPager
public class CustomViewPager extends ViewPager{
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for(int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if(h > height) height = h;
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}}
first your XML Must be like this..
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
>
</android.support.v4.view.ViewPager>
can you send your viewpager code first..

Position children views relative to their parent view

I need to implement a view that looks like this
The hard part is that the sizes and the font sizes of the textviews need to be adaptable to the width and height of the parent view. Here is what I have tried and the result is
The xml file:
<?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"
tools:layout_width="200dp"
tools:layout_height="100dp"
android:orientation="vertical">
<BuySellView
android:id="#+id/tradeNow_layoutSell"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="#color/gray_light_light">
<LinearLayout
android:id="#+id/smallPart1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top|right"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<ImageView
android:id="#+id/greenArrowSellImg"
android:layout_width="10dp"
android:layout_height="10dp"
android:src="#drawable/green_arrow"
android:visibility="invisible"
tools:visibility="visible" />
<ImageView
android:id="#+id/redArrowSellImg"
android:layout_width="10dp"
android:layout_height="10dp"
android:src="#drawable/red_arrow"
android:visibility="invisible"
tools:visibility="visible" />
</RelativeLayout>
<TextView
android:id="#+id/smallPart1Txt"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="top|right"
android:layout_gravity="center_vertical"
android:maxLines="1"
android:text="#string/misc_blank"
android:textColor="#android:color/black"
tools:text="10,015." />
</LinearLayout>
<TextView
android:id="#+id/largePart"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:maxLines="1"
android:text="#string/misc_blank"
android:textColor="#android:color/black"
tools:text="46"
android:gravity="center"
tools:textColor="#color/red_sell" />
<TextView
android:id="#+id/smallPart2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:maxLines="1"
android:text="#string/misc_blank"
android:textColor="#android:color/black"
android:gravity="left|center_vertical"
tools:text="8"
tools:textColor="#color/red_sell" />
<TextView
android:id="#+id/trdLbl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#drawable/rounded_corner_sell"
android:text="#string/CommonCapitalSell"
android:textColor="#color/white" />
</BuySellView>
</LinearLayout>
The custom view:
public class BuySellView extends ViewGroup {
private final Rect mTmpChildRect = new Rect();
public BuySellView(Context context) {
super(context);
}
public BuySellView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BuySellView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int t = 10;
int b = 10 + height / 3 * 2;
LinearLayout smallPart1 = (LinearLayout) findViewById(R.id.smallPart1);
smallPart1.layout(0, height / 3, width / 2, b);
smallPart1.setGravity(Gravity.RIGHT);
TextView smallPart1Txt = (TextView) smallPart1.findViewById(R.id.smallPart1Txt);
smallPart1Txt.setTextSize(height / 4 / 2);
TextView largePart = (TextView) findViewById(R.id.largePart);
largePart.setTextSize(height / 3);
largePart.layout(width / 2, 10, b - t + width / 2, b);
TextView smallPart2 = (TextView) findViewById(R.id.smallPart2);
smallPart2.layout(b - t + width / 2, t, width, height / 2);
smallPart2.setTextSize(height / 4 / 2);
TextView tradeLbl = (TextView) findViewById(R.id.trdLbl);
tradeLbl.layout(width / 2 - width / 3 / 2, height / 4 * 3 + 10, width / 2 + width / 3 / 2, height / 4 * 4 + 10);
tradeLbl.setGravity(Gravity.CENTER);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
LinearLayout smallPart1 = (LinearLayout) findViewById(R.id.smallPart1);
TextView largePart = (TextView) findViewById(R.id.largePart);
TextView smallPart2 = (TextView) findViewById(R.id.smallPart2);
TextView tradeLbl = (TextView) findViewById(R.id.trdLbl);
smallPart1.measure(Math.max(smallPart1.getMeasuredWidth(), widthMeasureSpec / 8 * 3), heightMeasureSpec / 4);
largePart.measure(heightMeasureSpec / 4 * 2, heightMeasureSpec / 4 * 2);
smallPart2.measure(Math.max(smallPart2.getMeasuredWidth(), widthMeasureSpec / 8), smallPart2.getMeasuredHeight());
tradeLbl.measure(widthMeasureSpec / 3, heightMeasureSpec / 4);
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
#Override
public boolean shouldDelayChildPressedState() {
return false;
}
}
try this XML:
<RelativeLayout
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0.87"
android:textSize="25sp"
android:layout_alignBottom="#+id/large"
android:paddingBottom="8dp"
android:fontFamily="sans-serif-light"
/>
<TextView
android:id="#+id/large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/small"
android:text="46"
android:textSize="58sp"
android:textColor="#00DC00"
android:fontFamily="sans-serif-light"
/>
<TextView
android:id="#+id/up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9"
android:textSize="24sp"
android:layout_alignTop="#+id/large"
android:layout_toRightOf="#+id/large"
android:textColor="#00DC00"
android:fontFamily="sans-serif-light"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="30dp"
android:background="#FF4848"
android:layout_below="#+id/large"
android:layout_alignRight="#+id/large"
android:text="Sell USD"
android:padding="5dp"
android:textColor="#fff"
android:textSize="12sp"
/>
</RelativeLayout>
You can change the textSize based on number of character or width of text via java code.

android ScrollView layout (wrap_content, maximum size)

Here is what I would like my ScrollView to look like:
The maximum size is defined with the layout_weight (so that other items below the ScrollView can be displayed properly)
If the content is smaller than that maximum size, then it just behaves as with layout_height="wrap_content"
Here is what I currently have:
<ScrollView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:measureAllChildren="true"
android:fillViewport="false"
>
I don't think the measureAllChildren really does anything at all...
If I add android:layout_weight, the size will always be what I would like the maximum to be. Without it, it just extends more than it should...
I don't mind extending the ScrollView class to change the behavior of onMeasure if I need to...?
PS: If that makes a differences, I am trying to get this working from Froyo onward.
I ended up writing my own class, extending ScrollView
Since you ask...here is the code. Probably not the cleanest but it does what I want.
Note that it expects the layout_weight to be set when the view is created and you should not set the weigthSum in the parent LinearLayout or you'll get funny things (since the weight of this one changes from the original value to 0 depending on the size of the content of the ScrollView)
First, in the layout file, the view is declared like this:
<com.matthieu.widget.ShrinkingScrollView
android:id="#+id/scroll"
android:scrollbars="vertical"
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="4"
android:background="#cc0000"
>
<TextView
android:id="#+id/in_scroll_view"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="#0000bb"
/>
</com.matthieu.widget.ShrinkingScrollView>
Then the code for the widget:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.ScrollView;
public class ShrinkingScrollView extends ScrollView {
private float original_weight=-1;
public ShrinkingScrollView(Context context) {
super(context);
}
public ShrinkingScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ShrinkingScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();
float previous_weight = params.weight;
if (original_weight == -1)
original_weight = params.weight;
if ((getChildCount()>0) && (getVisibility()!=GONE)) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED));
int overall_height = getChildAt(0).getMeasuredHeight();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (getMeasuredHeight() >= overall_height) {
if (previous_weight != 0) {
params.weight=0;
params.height = overall_height;
setLayoutParams(params);
post(new Runnable() {
public void run() {
requestLayout();
}
});
}
setMeasuredDimension(getMeasuredWidth(),overall_height);
}
else if (previous_weight == 0) {
params.weight = original_weight;
params.height = 0;
setLayoutParams(params);
post(new Runnable() {
public void run() {
requestLayout();
}
});
}
}
else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
If I understand your requirement correctly, the way I have done something like this is to place the scrollview along with anything else you want to display below it into a Relative layout. Then, in your layout file place the item on the bottom of the screen in the file first (with android:layout_alignParentBottom="true"), then put the scroll view and place it above the first item using something like:android:layout_above="#id/firstItem". Like this in which I put an image view on the bottom with a scroll view above it taking the remaining space:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/searchByNameScreen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:layout_marginTop="1dip"
android:gravity="center_horizontal"
android:orientation="vertical" >
<ImageView
android:id="#+id/bottomImage"
android:layout_width="fill_parent"
android:layout_height="75dip"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:paddingBottom="15dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="7dip"
android:scaleType="fitXY"
android:src="#drawable/android_450x50_moreinfo" />
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ScrollView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#id/bottomImage"
android:layout_marginBottom="3dip"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_marginTop="1dip"
android:scrollbars="none" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/aboutCopyLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/aboutTopLayer"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:background="#drawable/rounded_background"
android:gravity="center"
android:padding="5dip" >
<!-- android:background="#drawable/rounded_background" -->
<TextView
android:id="#+id/aboutCopyText"
style="#style/ResortNameExtraLine"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:text="#string/aboutCopy" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
Here another solution using sizes instead of weights. I've extended ScrollView and added code to implement this feature:
https://gist.github.com/JMPergar/439aaa3249fa184c7c0c
I hope that be useful.
JMpergar answer seems right but its not worked until I changed the onMeasure method like below.
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (maxHeight != WITHOUT_MAX_HEIGHT_VALUE
&& heightSize > maxHeight) {
heightSize = maxHeight;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
getLayoutParams().height = heightSize;
} else {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec)
, getDefaultSize(this.getSuggestedMinimumHeight(), heightMeasureSpec));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
you can just wrap your ScrollView into another ConstraintLayout, then constrain the height (the line app:layout_constrainedHeight="true"):
<!-- another constraint layout to keep ScrollView shrinking -->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">

Categories

Resources