I try to create custom ScrollView, which will have attribute max_height, but i faced with problem. When I set custom height, ScrollView doesn't show TextView.
Lite version of my code:
Layout:
<RelativeLayout 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">
<com.example.scrollviewtest.ExpandScrollView
android:id="#+id/scrollView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#Fe6" >
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView TextView TextView TextView TextView" />
</com.example.scrollviewtest.ExpandScrollView>
ExpandScrollView.java
public class ExpandScrollView extends ScrollView {
public ExpandScrollView(Context context) {
super(context);
}
public ExpandScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(widthSize, 180);
}}
So what do i do wrong?
Just remove the onMeasure() method in ExpandScrollView class. It is causing problem.
Once you remove it textview will be visible.
The problem was solved!
I just added super.onMeasure(widthMeasureSpec, heightMeasureSpec); before widthSize
Related
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>
Here is the sample code,
contact.xml
<ScrollView
android:id="#+id/scroll_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:layout_marginBottom="55dp">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
style="#style/ContentFrame"
android:layout_marginTop="20dp"
android:layout_marginBottom="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:id="#+id/msg_listview_frame"
android:layout_marginTop="10dp">
<com.android.bundle.helper.NonScrollListView
android:id="#+id/contact_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#color/white_lilac"
android:dividerHeight="1dp"
android:footerDividersEnabled="false"
android:scrollbars="none">
</com.android.bundle.helper.NonScrollListView>
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
</ScrollView>
To make ListView non-scrollable, I'm using this custom class NonScrollListView.
NonScrollListView.java
public class NonScrollListView extends ListView {
public NonScrollListView(Context context) {
super(context);
}
public NonScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
The adapter is been called more than 40 times, I have tried a couple of options from StackOverflow like changing listview height = fill_parent as well as match_parent.
I know this is an old issue, I'm new to android not able to resolve this one. Kindly help to resolve this issue.
Note: At any cost, ListView has to be inside ScrollView. I want to make CardView be scrollable.
Thanks
I made a custom View that extends the PercentRelativeLayout and forces the View to be quadratic. The child elements of this view should match their parent's size (height and width). If I set the children's layout_width or layout_height to match_parent or fill_parent they extend over the parent View (as you can see in the right half of the picture). The child elements are not visible outside of the custom Layout, but I can't align the children via relative sizes properly.
The custom view:
public class QuadraticPercentRelativeLayout extends PercentRelativeLayout {
public QuadraticPercentRelativeLayout(Context context) {
super(context);
}
public QuadraticPercentRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public QuadraticPercentRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int size = width < height ? width : height;
setMeasuredDimension(size, size);
}
}
Here is my Layout (simplified):
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<QuadraticPercentRelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/progress_bar">
<ImageView
android:id="#+id/page_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:scaleType="fitCenter"
app:srcCompat="#drawable/package_stock"/>
<ImageView
android:id="#+id/next_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="#+id/page_view"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
app:layout_widthPercent="35%"
app:srcCompat="#color/ColorPrimaryDark"/>
<ImageView
android:id="#+id/previous_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="#+id/page_view"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
app:layout_widthPercent="35%"
app:srcCompat="#color/ColorPrimaryDark"/>
</QuadraticPercentRelativeLayout>
</RelativeLayout>
Is this the standard behavior for children Views? How can I change it to make the children match the parent size?
I fixed the onMeasure method in the QuadraticPercentRelativeLayout class:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int size = Math.min(width, height);
int measureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
super.onMeasure(measureSpec, measureSpec);
}
I am trying to populate a gridview with image thumbnails. I am unable to center the child items and a mismatch occurs when the image orientation is different i.e landscape vs portrait. The pic shows how it is coming out. I dont want to change the size of the thumbnails but to display the text view on the same level and the imageview to be centered accordingly.
photo gridview with childs not centered
Gridview XML:
<syook.syookfirst.classes.Utils.ExpandableHeightGridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listview_call_photos"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_weight="1"
android:nestedScrollingEnabled="true"
android:gravity="center"
android:layout_gravity="center"
android:numColumns="auto_fit">
</syook.syookfirst.classes.Utils.ExpandableHeightGridView>
ExpandableHeightGridView class:
public class ExpandableHeightGridView extends GridView
{
boolean expanded = false;
public ExpandableHeightGridView(Context context)
{
super(context);
}
public ExpandableHeightGridView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightGridView(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;
}
}
Gridview child layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/button_pressed_nocolor_all"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/photo_thumb_calldetails"
android:padding="5dp"
android:layout_gravity="center" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/label_photo_name"
android:textSize="12sp"
android:layout_gravity="center"
android:gravity="center"
android:padding="2dp"
android:layout_marginBottom="2dp" />
Appreciate any help on this. I tried searching for such issues but haven't been able to resolve it with any of the solutions provided.
Setting the height of ImageView to 100dp works. Thanks :)
Just set fix width and set gravity to center.
android:layout_width="8" and
android:gravity="center"
How can I force an android GridView to generate square cells (Cell's height equal to cell's width)
GridView has 10*9 cells and the app must support multiple screens !
I used a Linear Layout:
row_grid.xml
<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:padding="0dp" >
<ImageView
android:id="#+id/item_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/ic_launcher" >
</ImageView>
</LinearLayout>
and GridView:
activity_main.xml
<RelativeLayout 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:background="#drawable/katy" >
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:horizontalSpacing="0dp"
android:numColumns="4"
android:stretchMode="columnWidth"
android:verticalSpacing="0dp" >
</GridView>
</RelativeLayout>
Each cell of GridView contains a image that has same width and height.
images are larger than cells and must stretch to fit in cells.
First, you're going to want to create a custom View class that you can use instead of the default LinearLayout you're using. Then you want to override the View's onMeasure call, and force it to be square:
public class GridViewItem extends ImageView {
public GridViewItem(Context context) {
super(context);
}
public GridViewItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridViewItem(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec); // This is the key that will make the height equivalent to its width
}
}
Then you can change your row_grid.xml file to:
<path.to.item.GridViewItem xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/ic_launcher" >
</path.to.item.GridViewItem>
Just be sure to change "path.to.item" to the package where your GridViewItem.java class resides.
I also removed your LinearLayout parent since it wasn't doing anything for you there.
Edit:
Also changed scaleType from fitXY to centerCrop so that your image doesn't stretch itself and maintains its aspect ratio. And, as long as it's a square image, nothing should be cropped, regardless.
You can Override your linear layout
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context) {
super(context);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec); // This is the key that will make the height equivalent to its width
}
}
then use it in the item_grid.xml
<?xml version="1.0" encoding="utf-8"?>
<com.example.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/item_grid"
android:layout_margin="2dp"
android:padding="3dp"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Category Name"
android:textStyle="bold"
android:textColor="#color/colorPrimary"
android:id="#+id/tvCategoryName" />
</com.example.MyLinearLayout>
How about using ConstraintLayout?
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="3dp">
<ImageView
android:id="#+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Works nicely, thank you! A small improvement I required would be always pick the smaller value, to prevent overshooting the screen:
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(heightMeasureSpec < widthMeasureSpec) {
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
} else if(widthMeasureSpec < heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
public class GridViewItem extends RelativeLayout {
public GridViewItem(Context context) {
super(context);
}
public GridViewItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridViewItem(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec); // This is the key that will make the height equivalent to its width
}
}
If your grid item just have an image then the answer is very good. But you want to add multiple items in your grid item then you must create Your Custom GridViewItem extending the layout you want your grid item to be. For example in my case I had RelativeLayout as the parent view so I created GridViewItem extending the RelativeLayout and it worked flawlessly.
Just make sure that your images are square. And make the container wrap_content.