GridView to make square board - android

I'm trying to make a square board with 5 x 5 grid using gridview. Here is my code:
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<GridView
android:id="#+id/squareBoard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:numColumns="5"
/>
</RelativeLayout>
This is the Adapter I used:
private class TextViewAdapter extends BaseAdapter {
private Context mContext;
private int mWidth, mHeight;
public TextViewAdapter(Context c, int width, int height) {
mContext = c;
mWidth = width;
mHeight = height;
}
public int getCount() {
return mWidth * mHeight;
}
public TextView getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = null;
if (convertView == null) { // if it's not recycled, initialize some attributes
tv = new TextView(mContext);
tv.setText("" + position);
tv.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
tv.setLayoutParams(new GridView.LayoutParams(100, 100));
tv.setWidth(100);
tv.setBackground(getResources().getDrawable(R.drawable.letter_box));
} else {
tv = (TextView) convertView;
}
return tv;
}
}
and this is the letter_box.xml of the textview background
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid
android:color="#android:color/white" >
</solid>
<stroke
android:width="1dp"
android:color="#android:color/black" >
</stroke>
</shape>
So far, i managed to display boxes, but there's always horizontal space between columns. I want them to be like a chess board.
Can anyone help me?

Create your own class MyGridView which extends GridView.
Override its onMeasure(...) method and set height == width, like so:
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
Then, create your own GridViewItem extending a View subclass e.g. TextView or ImageView etc. Override its onMeasure(...) method in the same way.
MyGridViewand its items will all appear square.

On your GridView, you can set the vertical spacing and the horizontal spacing that is between two items. Try setting those to 0dp.
<GridView
android:id="#+id/squareBoard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:numColumns="5"
/>

Related

How to make a gridview scrolling exactly the same as another gridview?

To display data in table layout with the first column frozen, the others can scroll horizontally, I have used 2 gridviews as below XML file content:
<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"
tools:context="com.example.gridviews.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<GridView
android:id="#+id/gridViewID"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:columnWidth="50dp"
android:horizontalSpacing="1dp"
android:numColumns="1"
android:paddingTop="5dp"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<GridView
android:id="#+id/gridViewDays"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:horizontalSpacing="1dp"
android:numColumns="5"
android:paddingTop="5dp"
android:scrollbarStyle="outsideOverlay"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</RelativeLayout>
and my code:
...
BaseAdapter adapterId = new BaseAdapter() {
#Override
public int getCount() {
return dataList.size();
}
#Override
public Object getItem(int position) {
return dataList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(context);
textView.setText(String.valueOf(dataList.get(position).Id));
textView.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, 70));
return textView;
}
};
BaseAdapter adapterDays = new BaseAdapter() {
#Override
public int getCount() {
return dataList.size() * 5;
}
#Override
public Object getItem(int position) {
return dataList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(context);
int mod = position % 5;
int idx = position / 5;
switch (mod) {
case 0:
textView.setText(String.valueOf(dataList.get(idx).Mon));
break;
case 1:
textView.setText(String.valueOf(dataList.get(idx).Tue));
break;
case 2:
textView.setText(String.valueOf(dataList.get(idx).Wed));
break;
case 3:
textView.setText(String.valueOf(dataList.get(idx).Thu));
break;
case 4:
textView.setText(String.valueOf(dataList.get(idx).Fri));
break;
}
textView.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, 70));
return textView;
}
};
gridViewID.setAdapter(adapterId);
gridViewDays.setAdapter(adapterDays);
// Horizontal scrolling of gridViewDays
LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) gridViewDays.getLayoutParams();
linearParams.width = 300;
gridViewDays.setLayoutParams(linearParams);
// Vertical scrolling...
gridViewID.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int firstVisibleItem = view.getFirstVisiblePosition();
gridViewID.setSelection(firstVisibleItem);
gridViewDays.setSelection(firstVisibleItem * 5);
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
...
With these code, of course when I move my hand out of the screen, the gridViewDays gridview will have the same selection with the gridViewID as the image below:
However, when I keep my hand touch on the screen to scroll the gridViewID, the gridViewDays will look like the image below (it does not scroll while gridViewID is scrolling)
So, how can I make the gridViewDays gridview vertically scrolling the same as the gridViewID? I have also tried some methods such as smoothScrollToPosition, smoothScrollByOffset, smoothScrollToPositionFromTop... inside onScroll but they do not work
Update: although the answers (#vrundpurohit's and mine) below are working, however, I have found that the app has poor performance with big data (I mean when the data list has too many items).
use NonScrollGridView. and wrap both in single ScrollView
Here is code for NonScrollGridView..
public class NonScrollGridView extends GridView {
public NonScrollGridView(Context context) {
super(context);
}
public NonScrollGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonScrollGridView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#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();
}
}
EDIT:
Here is how you can do this.
<ScrollView android:id="#+id/scroll" ... >
<NonScrollGridView />
<RelativeLayout android:id="#+id/head1" ... >
<!-- header for 1st GridView -->
</RelativeLayout>
<HorizontalScrollView ... >
<HorizontalScrollView ... >
<NonScrollGridView />
<RelativeLayout android:id="#+id/head2" ... >
<!-- header for 1st GridView -->
</RelativeLayout>
</HorizontalScrollView>
</HorizontalScrollView>
</ScrollView>
Now for making both headers sticky.. do following.
scroll.getViewTreeObserver().addOnScrollChangedListener(
new ViewTreeObserver.OnScrollChangedListener() {
public void onScrollChanged() {
ViewCompat.setTranslationY(head1, who.getScrollY());
ViewCompat.setTranslationY(head2, who.getScrollY());
}
});
Happy Coding..
Thanks to #vrundpurohit comment, I have searched more in S.O and found
#dennisdrew's answer at
How to put GridView inside ScrollView
From there, I use the ExpandableHeightGridView class of #tacone at
Gridview height gets cut
to solve my issue.
My modified code:
...
final ExpandableHeightGridView gridViewID = (ExpandableHeightGridView) findViewById(R.id.gridViewID);
final ExpandableHeightGridView gridViewDays = (ExpandableHeightGridView) findViewById(R.id.gridViewDays);
gridViewID.setExpanded(true);
gridViewDays.setExpanded(true);
...
Layout file:
<ScrollView 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:context="com.example.gridviews.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.example.gridviews.ExpandableHeightGridView
android:id="#+id/gridViewID"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:columnWidth="50dp"
android:horizontalSpacing="1dp"
android:numColumns="1"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
<HorizontalScrollView
android:id="#+id/horizontalScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.example.gridviews.ExpandableHeightGridView
android:id="#+id/gridViewDays"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:horizontalSpacing="1dp"
android:numColumns="5"
android:scrollbarStyle="outsideOverlay"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp" />
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</ScrollView>
Thank you all!

How do I center a GridView inside a fragment with viewpager

I have a Gridview inside a fragment of a ViewPager. I have 2x2 grid that I want to center on the parent, the ViewPager. It's displaying like this, only centering horizontally but not vertically My xml files are as follow.
This is the activity_main_menu.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/background"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/actionBar"
android:scaleType="centerCrop"
android:background="#drawable/home_01" />
<android.support.v4.view.ViewPager
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_below="#+id/actionBar"
android:layout_above="#+id/buttonBar"
tools:context="com.excitingspace.areias_do_seixo.MainMenu" >
</android.support.v4.view.ViewPager>
<com.viewpagerindicator.CirclePageIndicator
android:id="#+id/titles"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_above="#+id/buttonBar"/>
</RelativeLayout>
And this is the fragment_main_menu.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"
tools:context="com.excitingspace.areias_do_seixo.MainMenu$PlaceholderFragment" >
<GridView
android:id="#+id/gridView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:columnWidth="150dp"
android:gravity="center"
android:listSelector="#android:color/transparent"
android:horizontalSpacing="10dp"
android:layout_centerInParent="true"
android:numColumns="2"
android:verticalSpacing="10dp" >
</GridView>
</RelativeLayout>
EDIT, adds the ImageAdapter used to populate the GridView:
public class ImageAdapter extends BaseAdapter {
private static int PADDING = 0;
private static int WIDTH = 0;
private static int HEIGHT = 0;
private Context mContext;
private List<Integer> mThumbIds;
private List<Integer> mThumbIds_highlighted;
public ImageAdapter(Context c, List<Integer> ids, List<Integer> ids_highlighted) {
mContext = c;
this.mThumbIds = ids;
this.mThumbIds_highlighted = ids_highlighted;
int baseWidth = 150;
int baseHeight = 150;
int basePading = 20;
float density = mContext.getResources().getDisplayMetrics().density;
if ((mContext.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE)
{
baseWidth = 200;
baseHeight = 200;
basePading = 20;
}
ImageAdapter.WIDTH = (int) (baseWidth * density + 0.5f);
ImageAdapter.HEIGHT = (int) (baseHeight * density + 0.5f);
ImageAdapter.PADDING = (int) (basePading * density + 0.5f);
}
#Override
public int getCount() {
return mThumbIds.size();
}
#Override
public Object getItem(int position) {
return null;
}
// Will get called to provide the ID that
// is passed to OnItemClickListener.onItemClick()
#Override
public long getItemId(int position) {
return mThumbIds.get(position);
}
// create a new ImageView for each item referenced by the Adapter
#SuppressWarnings("deprecation")
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ImageView imageView = (ImageView) convertView;
StateListDrawable sld = new StateListDrawable();
Drawable draw1 = mContext.getResources().getDrawable(mThumbIds.get(position));
Drawable draw2 = mContext.getResources().getDrawable(mThumbIds_highlighted.get(position));
sld.addState(new int[] { android.R.attr.state_pressed }, draw2);
sld.addState(StateSet.WILD_CARD, draw1);
// if convertView's not recycled, initialize some attributes
if (imageView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(WIDTH, HEIGHT));
imageView.setPadding(PADDING, PADDING, PADDING, PADDING);
// imageView.setScaleX();
}
imageView.setBackgroundDrawable(sld);
return imageView;
}
}
modify your fragment_main_menu.xml file like this
<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"
tools:context="com.excitingspace.areias_do_seixo.MainMenu$PlaceholderFragment" >
<GridView
android:id="#+id/gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="150dp"
android:gravity="center_vertical"
android:listSelector="#android:color/transparent"
android:horizontalSpacing="10dp"
android:layout_centerInParent="true"
android:numColumns="2"
android:verticalSpacing="10dp" >
</GridView>
</RelativeLayout>

How to make a list of square buttons with autoresize?

I am developing an app that displays a page with a variable number of square buttons, like the second picture of "Square MIUI":
Square MIUI on APP store
I need displaying only three columns of square buttons, and make the entire list scrollable.
I'm trying first with plain XML:
<?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" >
<ScrollView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight="1.19"
android:orientation="horizontal" >
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Title"/>
</TableRow>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<!-- Icon buttons here -->
</TableRow>
</TableLayout>
</ScrollView>
<Button
android:layout_width="fill_parent"
android:layout_height="48dp"
android:text="Button" />
</LinearLayout>
For every button (4 TableRow of 3 buttons, images are square .png made with Eclipse icon generator)
EDIT: checked, icons of all screen densities are square
<Button
android:layout_margin="4dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="image"/>
but the buttons on my tablet are square, and on my phone are wider than tall (stretched on X-axis).
What I'm doing wrong?
TODO: code a variable button number.
Thanks in advance.
EDIT:
I tried this code:
private void squareButton() {
square(R.id.b1);
square(R.id.b2);
....
square(R.id.b<N>);
}
private void square(int id) {
ImageButton temp=(ImageButton) findViewById(id);
int l=temp.getWidth();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int Measuredwidth = metrics.widthPixels;
l=(int) (Measuredwidth/4);
temp.setMaxWidth(l);
temp.setMaxHeight(l);
temp.setMinimumWidth(l);
temp.setMinimumHeight(l);
LayoutParams param = temp.getLayoutParams();
param.width = l;
param.height = l;
temp.setLayoutParams(param);
temp.requestLayout();
}
But I'm still getting weird buttons on phone (Gingerbread)...
I can't rely only on the auto-sized icons (too little on my tablet, too big on my phone)
EDIT:
I'm looking for a code that:
squares button
has user-definable width
works with Gingerbread
In my case, button_width = widthPixels/4;
Thank you in advance.
Implements you own square button class like this:
public class SquareButton extends Button {
public SquareButton(Context context) {
super(context);
}
public SquareButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); // Snap to width
}
}
Finally, I found a solution using GridView.
First, I follow the GridView tutorial
Then I got some code from other answers.
Now this code creates a scrollable and clickable big square icon list, resized according to screen size. When one icon is clicked, changes his image.
Thank you Lubos for your suggestion.
[main activity]
public class Grid extends Activity {
public boolean audio=true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
// load icons on grid
ImageAdapter.loadImages(new Integer[] {
R.drawable.ic_blu_voice_on,
R.drawable.ic_blu_help,
R.drawable.ic_blu_save,
R.drawable.ic_blu_load
});
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View imgView, int position, long id) {
ImageView image=(ImageView) imgView;
switch (position) {
case 0:
// switch voice icon on/off when clicked
image.setImageResource(voice());
break;
}
Toast.makeText(Grid.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
}
private int voice() {
audio=!audio;
if (audio) return R.drawable.ic_blu_voice_on;
return R.drawable.ic_blu_voice_off;
}
}
[imageadapter.java]
public class ImageAdapter extends BaseAdapter {
private Context mContext;
// reference to images (dummy)
private static Integer[] mThumbIds = {0,0};
private float px;
public ImageAdapter(Context c) {
mContext = c;
//Calculation of ImageView Size - density independent.
Resources r = Resources.getSystem();
px = r.getDisplayMetrics().widthPixels;
px=px/3;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public static void setImage(int position, int id) {
mThumbIds[position]=id;
}
public static void loadImages(Integer[] images) {
mThumbIds = images;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams((int)px, (int)px));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
}
[activity_grid.xml]
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
tools:context="${packageName}.${activityClass}">
<LinearLayout
android:id="#+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >
<TextView
android:id="#+id/testo1"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:gravity="center_horizontal"
android:text="#string/hello_world"
android:textSize="30sp" />
<GridView
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:columnWidth="120dp"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="spacingWidthUniform">
</GridView>
<Button
android:id="#+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_world"
android:textSize="30sp" />
</LinearLayout>
</RelativeLayout>

Android list view inside a scroll view

I have an android layout which has a scrollView with a number of elements with in it. At the bottom of the scrollView I have a listView which is then populated by an adapter.
The problem that I am experiencing, is that android is excluding the listView from the scrollView as the scrollView already has a scroll-able function. I want the listView to be as long as the content is and for the master scroll view to be scroll-able.
How can I achieve this behavior?
Here is my main layout:
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:fillViewport="true"
android:gravity="top" >
<LinearLayout
android:id="#+id/foodItemActvity_linearLayout_fragments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
I then programmatically add my components to the linearlayour with the id: foodItemActvity_linearLayout_fragments. Below is one of the views that is loaded into that linearlayout. This is the one giving me trouble with the scrolls.
<?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="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/fragment_dds_review_textView_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reviews:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
android:id="#+id/fragment_dds_review_listView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
My adapter then fills up this list view.
Here is an image from the android hierarchy viewer when I click on the master scrollView:
As you can see, it is excluding the reviews listView.
I should be able to scroll the page down and see 8 reviews, but instead it only shows me those 3, and I can scroll on the tiny part where the reviews are. I want a global page scroll
For any Child view to scroll inside a ScrollView. Anything like ListView, RecyclerView, etc. You just have to replace ScrollView with androidx.core.widget.NestedScrollView in your current xml and then magic happens.
Below is a sample xml code :
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
android:paddingBottom="20dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Recycler View inside a Scroll View"
android:textColor="#color/black"
android:textSize="#dimen/_20sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Below is a Recycler View as an example."
android:textSize="16sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#id/et_damaged_qty" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="This textview automatically goes below the Recycler View."
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.core.widget.NestedScrollView>
Now you can get rid of all the ugly hacks you did to get around with nested scrolling.
The answer is simple and I am surprised it has yet to be answered here.
Use a Header View or/and Footer View on the list itself.
Don't mix a ScrollView with a ListView or anything that can scroll. It's meant to be used with headers and footers :)
Essentially, take all the content above your ListView, put it in another .xml file as a layout and then in code inflate it and add it to the list as a header view.
i.e.
View header = getLayoutInflater().inflate(R.layout.header, null);
View footer = getLayoutInflater().inflate(R.layout.footer, null);
listView.addHeaderView(header);
listView.addFooterView(footer);
I know it's been so long but I got this problem too, tried this solution and it's working. So I guess it may help the others too.
I add android:fillViewport="true" on the layout xml for the scrollView.
So overall my ScrollView will be like this.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollView6"
android:fillViewport="true">
And it works like magic to me.
the ListView that located inside my ScrollView expand to its size again.
Here is the full example code for the ScrollView and the ListView.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollView6" android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
....
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lv_transList" android:layout_gravity="top"
android:layout_marginTop="5dp"/>
....
</LinearLayout>
</ScrollView>
You Create Custom ListView Which is non Scrollable
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();
}
}
In Your Layout Resources File
<?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"
android:fadingEdgeLength="0dp"
android:fillViewport="true"
android:overScrollMode="never"
android:scrollbars="none" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- com.Example Changed with your Package name -->
<com.Example.NonScrollListView
android:id="#+id/lv_nonscroll_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.Example.NonScrollListView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/lv_nonscroll_list" >
<!-- Your another layout in scroll view -->
</RelativeLayout>
</RelativeLayout>
</ScrollView>
In Java File
Create a object of your customListview instead of ListView like :
NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);
public static void setListViewHeightBasedOnChildren(ListView listView) {
// 获取ListView对应的Adapter
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0); // 计算子项View 的宽高
totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
// listView.getDividerHeight()获取子项间分隔符占用的高度
// params.height最后得到整个ListView完整显示需要的高度
listView.setLayoutParams(params);
}
you can use this code for listview in scrollview
Don't do anything in Parent ScrollView. Only do this to child ListView. Everything will work perfectly.
mListView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mScrollView.requestDisallowInterceptTouchEvent(true);
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_UP:
mScrollView.requestDisallowInterceptTouchEvent(false);
break;
}
return false;
}
});
This code will solve your problem if you have implemented just a ListView in a code.
If you are using RelativeLayout as ListView child than this code return a NullPointerException here listItem.measure(0, 0);, because of RelativeLayout.And the solution is put your Relativelayout inside a LinearLayout and it will work fine.
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
You may solve it by adding android:fillViewport="true" to your ScrollView.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:fillViewport="true"
android:scrollbars="vertical">
<ListView
android:id="#+id/statusList"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:animationCache="false"
android:divider="#null"
android:scrollingCache="false"
android:smoothScrollbar="true" />
</ScrollView>
before use that property, there was only one child of my list view is visible. after using that all the rows or child of list are visible.
I'll leave it here in case anyone will face the same issue. I had to put a ListView inside a ScrollView. ListView with header was not an option by a number of reasons. Neither was an option to use LinearLayout instead of ListView. So I followed the accepted solution, but it didn't work because items in the list had complex layout with multiple rows and each listview item was of variable height. Height was measured not properly. The solution was to measure each item inside ListView Adapter's getView() method.
#Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view == null) {
. . .
view.setTag(holder);
} else holder = (ViewHolder)view.getTag();
. . .
// measure ListView item (to solve 'ListView inside ScrollView' problem)
view.measure(View.MeasureSpec.makeMeasureSpec(
View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
return view;
}
You can easy put ListView in ScrollView!
Just need to change height of ListView programmatically, like this:
ViewGroup.LayoutParams listViewParams = (ViewGroup.LayoutParams)listView.getLayoutParams();
listViewParams.height = 400;
listView.requestLayout();
This works perfectly!
Done after lots of R&D:
fragment_one.xml should looks like:
<?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"
android:id="#+id/scrollViewParent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="400dip" >
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<View
android:id="#+id/customView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/transparent" />
</RelativeLayout>
<!-- Your other elements are here -->
</LinearLayout>
</ScrollView>
Your Java class of FragmentOne.java looks like:
private ListView listView;
private View customView
onCreateView
listView = (ListView) rootView.findViewById(R.id.listView);
scrollViewParent = (ScrollView)rootView.findViewById(R.id.scrollViewParent);
customView = (View)rootView.findViewById(R.id.customView);
customView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
scrollViewParent.requestDisallowInterceptTouchEvent(true);
// Disable touch on transparent view
return false;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
scrollViewParent.requestDisallowInterceptTouchEvent(false);
return true;
case MotionEvent.ACTION_MOVE:
scrollViewParent.requestDisallowInterceptTouchEvent(true);
return false;
default:
return true;
}
}
});
My requirement is to include a ListView of equally-sized items within a ScrollView. I tried a few of the other solutions listed here, none seemed to size the ListView correctly (either too little space or too much). Here's what worked for me:
public static void expandListViewHeight(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
ViewGroup.LayoutParams params = listView.getLayoutParams();
listView.measure(0, 0);
params.height = listView.getMeasuredHeight() * listAdapter.getCount() + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
Hope this helps someone.
I had a similar problem to the issue posed by the Original Poster - how to make the listview scroll inside the scrollview - and this answer solved my problem.
Disable scrolling of a ListView contained within a ScrollView
I didn't call new fragments into existing layouts or anything like that, like the OP was doing, so my code would look something like this :
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:fillViewport="true"
android:gravity="top" >
<LinearLayout
android:id="#+id/foodItemActvity_linearLayout_fragments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/fragment_dds_review_textView_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reviews:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
android:id="#+id/my_listView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
</ScrollView>
Basically what I am doing is checking the length of the listview before I call it and when I call it I make it into that length. In your java class use this function:
public static void justifyListViewHeightBasedOnChildren (ListView listView) {
ListAdapter adapter = listView.getAdapter();
if (adapter == null) {
return;
}
ViewGroup vg = listView;
int totalHeight = 0;
for (int i = 0; i < adapter.getCount(); i++) {
View listItem = adapter.getView(i, null, vg);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams par = listView.getLayoutParams();
par.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
listView.setLayoutParams(par);
listView.requestLayout();
}
And call the function like this:
justifyListViewHeightBasedOnChildren(listView);
The result is a listview with no scrollbar, the whole length of the listview being displayed, that scrolls with the scroll bar of the scrollview.
As others had already mentioned, don't use ListView inside a ScrollView.
To workaround, you can use a LinearLayout, but to still keep things neat - populate your LinearLayout with an Adapter, same as you do with a ListView
You can use this class as a LinearLayout replacement that supports Adapters
import android.content.Context;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
public class AdaptableLinearLayout extends LinearLayout {
private BaseAdapter mAdapter;
private int mItemCount = 0;
private boolean mDisableChildrenWhenDisabled = false;
private int mWidthMeasureSpec;
private int mHeightMeasureSpec;
public AdaptableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public BaseAdapter getAdapter() {
return mAdapter;
}
public void setAdapter(BaseAdapter adapter) {
mAdapter = adapter;
adapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
updateLayout();
super.onChanged();
}
#Override
public void onInvalidated() {
updateLayout();
super.onInvalidated();
}
});
updateLayout();
}
private void updateLayout() {
mItemCount = mAdapter.getCount();
requestLayout();
invalidate();
}
/**
* set size for the current View
*/
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidthMeasureSpec = widthMeasureSpec;
mHeightMeasureSpec = heightMeasureSpec;
removeAllViewsInLayout();
for (int i = 0; i < mItemCount; i++) {
makeAndAddView(i);
}
}
private View makeAndAddView(int position) {
View child;
// Nothing found in the recycler -- ask the adapter for a view
child = mAdapter.getView(position, null, this);
// Position the view
setUpChild(child, position);
return child;
}
private void setUpChild(View child, int position) {
ViewGroup.LayoutParams lp = child.getLayoutParams();
if (lp == null) {
lp = generateDefaultLayoutParams();
}
addViewInLayout(child, position, lp);
// Get measure specs
int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, getPaddingTop() + getPaddingBottom(), lp.height);
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getPaddingLeft() + getPaddingRight(), lp.width);
// Measure child
child.measure(childWidthSpec, childHeightSpec);
int childLeft;
int childRight;
// Position vertically based on gravity setting
int childTop = getPaddingTop() + ((getMeasuredHeight() - getPaddingBottom() - getPaddingTop() - child.getMeasuredHeight()) / 2);
int childBottom = childTop + child.getMeasuredHeight();
int width = child.getMeasuredWidth();
childLeft = 0;
childRight = childLeft + width;
child.layout(childLeft, childTop, childRight, childBottom);
if (mDisableChildrenWhenDisabled) {
child.setEnabled(isEnabled());
}
}
}
You can put all into linear layout. That is, create linear layout and it will have 2 childs, scrollview and another linear layout. Give them layout weights and here you go :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="0dip" android:layout_weight="0.8">
<LinearLayout
android:id="#+id/seTaskActivityRoot"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/taskName" />
<Spinner
android:id="#+id/seTaskPrioritiesSP"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/taskTargetInNumeric" />
<Spinner
android:id="#+id/seTaskUnitsSP"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="#+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/newTaskCurrentStatus" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="#string/addTaskCurrentStatus"
android:inputType="numberDecimal" />
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:orientation="vertical" android:layout_weight="0.2">
<TextView
android:id="#+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<ListView
android:id="#+id/logList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
You should never use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by ScrollView.
http://developer.android.com/reference/android/widget/ScrollView.html
Best solution is add this android:nestedScrollingEnabled="true" attribute in child scrolling for example i have inserted this attribute in my ListView that is child of ScrollView. i hope this mathod works for you :-
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TextView"/>
<ListView
android:nestedScrollingEnabled="true" //add this only
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="300dp"/>
</LinearLayout>
</ScrollView>
Do NEVER put a ListView inside of a ScrollView! You can find more information about that topic on Google. In your case, use a LinearLayout instead of the ListView and add the elements programmatically.
Update
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:fillViewport="true"
android:gravity="top" >
<LinearLayout
android:id="#+id/foodItemActvity_linearLayout_fragments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
to
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:fillViewport="true"
android:gravity="top" >
<LinearLayout
android:id="#+id/foodItemActvity_linearLayout_fragments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
The point here is you are trying to set height to 0dp (fixed)
found a solution for scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> dynamic listview, but im not the author. there is some bugs, but at least it works
public class CustomPager extends ViewPager {
private View mCurrentView;
public CustomPager(Context context) {
super(context);
}
public CustomPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mCurrentView == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
int height = 0;
mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = mCurrentView.getMeasuredHeight();
if (h > height) height = h;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void measureCurrentView(View currentView) {
mCurrentView = currentView;
this.post(new Runnable() {
#Override
public void run() {
requestLayout();
}
});
}
public int measureFragment(View view) {
if (view == null)
return 0;
view.measure(0, 0);
return view.getMeasuredHeight();
}
}
public class MyPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
private int mCurrentPosition = -1;
public MyPagerAdapter(FragmentManager fm) {
super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
this.fragments = new ArrayList<Fragment>();
fragments.add(new FirstFragment());
fragments.add(new SecondFragment());
fragments.add(new ThirdFragment());
fragments.add(new FourthFragment());
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (position != mCurrentPosition) {
Fragment fragment = (Fragment) object;
CustomPager pager = (CustomPager) container;
if (fragment != null && fragment.getView() != null) {
mCurrentPosition = position;
pager.measureCurrentView(fragment.getView());
}
}
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
}
fragments layout can be anything
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" tools:context="nevet.me.wcviewpagersample.FirstFragment">
<ListView
android:id="#+id/lv1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#991199"/>
</LinearLayout>
then somewhere just
lv = (ListView) view.findViewById(R.id.lv1);
lv.setAdapter(arrayAdapter);
setListViewHeightBasedOnChildren(lv);
}
public static void setListViewHeightBasedOnChildren(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,
LinearLayout.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();
}
using this ListView Worked for me
package net.londatiga.android.widget;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ListView;
import android.content.Context;
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;
}
}
and in xml
<com.pakagename.ExpandableHeightListView
android:id="#+id/expandableHeightListView"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.Example.ExpandableHeightListView>
and in MainActivity
ExpandableHeightListView listView = new ExpandableHeightListView(this);
listview=(ExpandableHeightListView)findViewById(R.id.expandableHeightListView);
listView.setAdapter(adapter); //set your adaper
listView.setExpanded(true);
Refer This article for more info and also to know how to keep gridview inside scroll view
It is not possible to use Scroll-view inside List-view as List-view already has scrolling property.
To use list-view inside Scroll-view you can follow these steps which worked for me :
1) Create NonScrollListView java file that disable the default scrolling property of list-view. and code is below
package your-package-structure;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ListView;
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();
}
}
2) Now create xml file which which has NestedScrollView and inside this use NonScrollListView for listing your items. This will make your entire screen to scroll with all the views.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<ViewFlipper
android:id="#+id/v_flipper"
android:layout_width="match_parent"
android:layout_height="130dp">
</ViewFlipper>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SHOP"
android:textSize="15dp"
android:textStyle="bold"
android:gravity="center"
android:padding="5dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#ddd"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1"
>
<com.abc.xyz.NonScrollListView
android:id="#+id/listview"
android:divider="#null"
android:layout_width="match_parent"
android:layout_marginBottom="10dp"
android:layout_height="match_parent"
android:padding="8dp">
</com.abc.xyz.NonScrollListView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom">
<include layout="#layout/footer" />
</LinearLayout>
</LinearLayout>
3) Now in java class i.e, home.java define NonScrollListView instead of Listview.
package comabc.xyz.landscapeapp;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.Toolbar;
import android.widget.ViewFlipper;
public class home extends Fragment {
int pos = 0;
ViewFlipper v_flipper;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_home, container, false);
return view;
}
#Override
public void onViewCreated(#NonNull final View view, #Nullable Bundle savedInstanceState) {
NonScrollListView listView = (NonScrollListView) view.findViewById(R.id.listview);
customAdapter customAdapter = new customAdapter(getActivity());
listView.setAdapter(customAdapter);
listView.setFocusable(false);
customAdapter.notifyDataSetChanged();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("listview click", "onItemClick: ");
/* FragmentTransaction fr = getFragmentManager().beginTransaction().replace(R.id.fragment_container, new productdisplay());
fr.putExtra("Position", position);
fr.addToBackStack("tag");
fr.commit();*/
Intent intent = new Intent(getActivity(), productdisplay.class);
intent.putExtra("Position", position);
startActivity(intent);
}
});
//image slider
int images[] = {R.drawable.slide1, R.drawable.slide2, R.drawable.slide3};
v_flipper = view.findViewById(R.id.v_flipper);
for (int image : images) {
flipperImages(image);
}
}
private void flipperImages(int image) {
ImageView imageView = new ImageView(getActivity());
imageView.setBackgroundResource(image);
v_flipper.addView(imageView);
v_flipper.setFlipInterval(4000);
v_flipper.setAutoStart(true);
v_flipper.setInAnimation(getActivity(), android.R.anim.slide_in_left);
v_flipper.setOutAnimation(getActivity(), android.R.anim.slide_out_right);
}
}
Note: I used Fragments here.
Ok, here 's my answer. The method that fixes the ListView height is closed enough, but not perfect. In case that most of the items are the same height, that work well. But in case that's not, then there's a big problem. I've tried many time, and when I put out the value of listItem.getMeasureHeight and listItem.getMeasuerWidth into the log, I saw the width values vary a lot, which is not expected here, since all the item in the same ListView should have the same width. And there go the bug :
Some used measure(0 ,0), which actually made the view unbound, in both direction, and width run wild. Some tried to getWidth of listView, but then it return 0, meaningless.
When I read further into how android render the View, I realize that all of this attempt can't reach the answer that I searched for, unless these function run after the view is render.
This time I use the getViewTreeObserver on the ListView that I want to fix height, then addOnGlobalLayoutListener. Inside this method, I declare a new OnGlobalLayoutListener, in which, this time, getWidth return the actual width of the ListView.
private void getLayoutWidth(final ListView lv, final int pad){
//final ArrayList<Integer> width = new ArrayList<Integer>();
ViewTreeObserver vto = lv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
lv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//width.add(layout.getMeasuredWidth());
int width = lv.getMeasuredWidth();
ListUtils.setDynamicHeight(lv, width, pad);
}
});
}
public static class ListUtils {
//private static final int UNBOUNDED = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
public static void setDynamicHeight(ListView mListView, int width, int pad) {
ListAdapter mListAdapter = mListView.getAdapter();
mListView.getParent();
if (mListAdapter == null) {
// when adapter is null
return;
}
int height = 0;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(width - 2*pad, View.MeasureSpec.EXACTLY);
for (int i = 0; i < mListAdapter.getCount(); i++) {
View listItem = mListAdapter.getView(i, null, mListView);
listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
//listItem.measure(UNBOUNDED, UNBOUNDED);
height += listItem.getMeasuredHeight() + 2*pad;
Log.v("ViewHeight :", mListAdapter.getClass().toString() + " " + listItem.getMeasuredHeight() + "--" + listItem.getMeasuredWidth());
}
ViewGroup.LayoutParams params = mListView.getLayoutParams();
params.height = height + (mListView.getDividerHeight() * (mListAdapter.getCount() - 1));
mListView.setLayoutParams(params);
mListView.requestLayout();
}
}
The value pad, is the padding that I set in ListView layout.
If for some reason you don't want to use addHeaderView and addFooterView, e.g. when you have several lists, a good idea would be to reuse ListAdapter to populate a simple LinearLayout so there's no scrolling functionality.
If you already have a whole fragment derived from ListFragment and want to convert it to a similar fragment with simple LinearLayout without scrolling instead (e.g. to put it in ScrollView), you can implement an adapter fragment like this:
// converts listFragment to linearLayout (no scrolling)
// please call init() after fragment is inflated to set listFragment to convert
public class ListAsArrayFragment extends Fragment {
public ListAsArrayFragment() {}
private ListFragment mListFragment;
private LinearLayout mRootView;
// please call me!
public void init(Activity activity, ListFragment listFragment){
mListFragment = listFragment;
mListFragment.onAttach(activity);
mListFragment.getListAdapter().registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
refreshView();
}
});
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// create an empty vertical LinearLayout as the root view of this fragment
mRootView = new LinearLayout(getActivity());
mRootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mRootView.setOrientation(LinearLayout.VERTICAL);
return mRootView;
}
// reusing views for performance
// todo: support for more than one view type
ArrayList<View> mViewsToReuse = new ArrayList<>();
ArrayList<View> mCurrentViews = new ArrayList<>();
// re-add views to linearLayout
void refreshView(){
// remove old views from linearLayout and move them to mViewsToReuse
mRootView.removeAllViews();
mViewsToReuse.addAll(mCurrentViews);
mCurrentViews.clear();
// create new views
for(int i=0; i<mListFragment.getListAdapter().getCount(); ++i){
View viewToReuse = null;
if(!mViewsToReuse.isEmpty()){
viewToReuse = mViewsToReuse.get(mViewsToReuse.size()-1);
mViewsToReuse.remove(mViewsToReuse.size()-1);
}
final View view = mListFragment.getListAdapter().getView(i, viewToReuse, mRootView);
ViewGroup.LayoutParams oldParams = view.getLayoutParams();
view.setLayoutParams(new LinearLayout.LayoutParams(oldParams.width, oldParams.height));
final int finalI = i;
// pass click events to listFragment
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListFragment.onListItemClick(null, view, finalI, finalI);
}
});
mRootView.addView(view);
mCurrentViews.add(view);
}
}
You may also want to forward onCreate, onPause, onResume, etc. to the original fragment depending on your needs or try inheritance instead of composition (but override certain methods so original fragment is not actually attached to layout hierarchy); but I wanted to isolate original fragment as much as possible, because we only need to extract its ListAdapter. If you call original fragment's setListAdapter in onAttach, that's probably enough.
Here's how to use ListAsArrayFragment to include OriginalListFragment without scrolling. In parent activity's onCreate:
ListAsArrayFragment fragment = (ListAsArrayFragment) getFragmentManager().findFragmentById(R.id.someFragmentId);
OriginalListFragment originalFragment = new OriginalListFragment();
fragment.init(this, originalFragment);
// now access originalFragment.getListAdapter() to modify list entries
// and remember to call notifyDatasetChanged()
found a solution for scrollview -> viewpager -> FragmentPagerAdapter -> fragment -> dynamic listview, but im not the author.
public class CustomPager extends ViewPager {
private View mCurrentView;
public CustomPager(Context context) {
super(context);
}
public CustomPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mCurrentView == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
int height = 0;
mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = mCurrentView.getMeasuredHeight();
if (h > height) height = h;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void measureCurrentView(View currentView) {
mCurrentView = currentView;
this.post(new Runnable() {
#Override
public void run() {
requestLayout();
}
});
}
public int measureFragment(View view) {
if (view == null)
return 0;
view.measure(0, 0);
return view.getMeasuredHeight();
}
}
public class MyPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
private int mCurrentPosition = -1;
public MyPagerAdapter(FragmentManager fm) {
super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
this.fragments = new ArrayList<Fragment>();
fragments.add(new FirstFragment());
fragments.add(new SecondFragment());
fragments.add(new ThirdFragment());
fragments.add(new FourthFragment());
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (position != mCurrentPosition) {
Fragment fragment = (Fragment) object;
CustomPager pager = (CustomPager) container;
if (fragment != null && fragment.getView() != null) {
mCurrentPosition = position;
pager.measureCurrentView(fragment.getView());
}
}
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
}
fragments layout can be anything
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" tools:context="nevet.me.wcviewpagersample.FirstFragment">
<ListView
android:id="#+id/lv1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#991199"/>
</LinearLayout>
then somewhere just
lv = (ListView) view.findViewById(R.id.lv1);
lv.setAdapter(arrayAdapter);
setListViewHeightBasedOnChildren(lv);
}
public static void setListViewHeightBasedOnChildren(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,
LinearLayout.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();
}
In xml:
<com.example.util.NestedListView
android:layout_marginTop="10dp"
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#null"
android:layout_below="#+id/rl_delivery_type" >
</com.example.util.NestedListView>
In Java:
public class NestedListView extends ListView implements View.OnTouchListener, AbsListView.OnScrollListener {
private int listViewTouchAction;
private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99;
public NestedListView(Context context, AttributeSet attrs) {
super(context, attrs);
listViewTouchAction = -1;
setOnScrollListener(this);
setOnTouchListener(this);
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
scrollBy(0, -1);
}
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int newHeight = 0;
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
ListAdapter listAdapter = getAdapter();
if (listAdapter != null && !listAdapter.isEmpty()) {
int listPosition = 0;
for (listPosition = 0; listPosition < listAdapter.getCount()
&& listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) {
View listItem = listAdapter.getView(listPosition, null, this);
//now it will not throw a NPE if listItem is a ViewGroup instance
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
listItem.measure(widthMeasureSpec, heightMeasureSpec);
newHeight += listItem.getMeasuredHeight();
}
newHeight += getDividerHeight() * listPosition;
}
if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) {
if (newHeight > heightSize) {
newHeight = heightSize;
}
}
} else {
newHeight = getMeasuredHeight();
}
setMeasuredDimension(getMeasuredWidth(), newHeight);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
scrollBy(0, 1);
}
}
return false;
}
}
Just call this function after assign adapter to listview
public static void setListViewHeightBasedOnChildren
(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();
}
if you what show all items in listView inside ScrollView use this code
val params: ViewGroup.LayoutParams = listView!!.layoutParams
params.height = useitemsList.size * 200 //add static height
listView!!.layoutParams = params
listView!!.requestLayout()
Just set the value of required height in a listview height attribute inside a parent scrollview. It will scroll along with other parents child item.
This worked for me (link1, link2):
You Create Custom ListView Which is non Scrollable
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 = View.MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
In Your Layout File
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- com.Example Changed with your Package name -->
<com.thedeveloperworldisyours.view.NonScrollListView
android:id="#+id/lv_nonscroll_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.thedeveloperworldisyours.view.NonScrollListView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/lv_nonscroll_list" >
<!-- Your another layout in scroll view -->
</RelativeLayout>
</RelativeLayout>
</ScrollView>
Create a object of your customListview instead of ListView like :
NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);

GridView Stretching ImageView Non-Uniformly

I have a GridView that I am using to display a row of 4 images, each image is 200 x 200 pixels. Here is the layout 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"
tools:context=".MainActivity" >
<GridView
android:id="#+id/myGridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:numColumns="4" >
</GridView>
</RelativeLayout>
When I run my app here is what the images look like:
As you can see the images are getting scaled (narrowed) to fit the screen.
How do I make it so the images are stretched both vertically and horizontally to maintain the correct aspect ratio?
Note that I am using an adapter to draw the images:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
} else {
imageView = (ImageView) convertView;
}
imageView.setBackgroundResource(imageIds[position]);
return imageView;
}
I got the same issue in last weak.Use my image view class and solve this issue.
public class iv_autoSizedImageView extends ImageView {
public iv_autoSizedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
try {
getLayoutParams().height = getMeasuredWidth();
} catch (Exception e) {
// TODO: handle exception
}
}
}
layout.xml
<com.sample.test.iv_autoSizedImageView
android:id="#+id/IV_NEWS_IMAGE"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>

Categories

Resources