i have a list view defined in the xml, now i am setting the content view setContentView(R.layout.topic_layout); , i have 5 items in it,currently its filling only half the height of the list view but i want it to completely fill the height so that i dont have any space at the bottom.
i have searched for it but couldnt find any solution, please help me to acheive this :
and also i am setting the adapter like this:
adapter = new MyAdapter(this);
if (adapter != null) {
setListAdapter(adapter);
}
If you have a fixed number of items and want them to stretch all the way to the end of the screen, ListView is not the best choice for you. Use a LinearLayout which takes up all the space and add all the items to it. This is assuming you want the items to take up all the space every time.
Using LinearLayout, you can spread the items out evenly without doing any calculations yourself.
LinearLayout linearLayout = new LinearLayout(getSupportActivity());
linearLayout.setOrientation(android.widget.LinearLayout.VERTICAL);
RelativeLayout.LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
for (int i = 0; i < 5; i++) {
View individualView = new View(getSupportActivity());
// Create your custom view here and add it to the linear layout
// Leave the height as 0, LinearLayout will calculate the height properly.
params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
additionalOption.setLayoutParams(params);
// As a we are adding it to the linear layout, they will all have a weight of 1, which will make them spread out evenly.
linearLayout.addView(additionalOption);
}
mainView.addView(linearLayout);
EDIT: If you have already implemented it with ListView and is troublesome to change it, you can do the following.
Make sure the list view width and height are set to match_parent in the xml. Then in getView() of the adapter where you create your custom view, do the following
// Get the height of the ListView
int totalHeight = listView.getHeight();
int rowHeight = totalHeight/getCount(); // Divide by number of items.
// Create custom view with the height calculated above.
Be careful about the totalHeight being 0. If you create the ListView in onCreate() and set the adapter in onCreate() as well, the ListView will most likely not have the width or height calculated yet. Try setting the adapter in onResume() instead. By this point, the dimensions of the ListView would have been calculated and laid out on the screen.
Hope this helps.
I totally agree with #Aswin, using LinearLayout with layout_weight property would be your solution. But if you insist to use listView, i can offer you a workout which is not so recommended.
You can get your screenHeight when activity created by using these codes:
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
int height = dm.heightPixels;
int listItemHeight = height / YOUR_ITEM_COUNT;
Then you can use this listItemHeight in your listAdapter, by setting inflated view's height on getView method.
This is what I use to do:
Set your xml listview height to match_parent instead of wrap_content, in order to fill all the available space.
Set the minimum height of each item in the listview to match the listview height divided by the number of elements.
Activity Layout:
(...)
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
(...)
ArrayAdapter for the Listview:
private class MyAdapter extends ArrayAdapter<MyObject> {
(...)
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyObject myobject = getItem(position);
ObjectHolder oh;
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) myContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.myitemlayout, parent, false);
// This is the important line:
convertView.setMinimumHeight(parent.getHeight()/getCount());
(...)
return convertView;
}
}
Related
How can i have 2 by 2 scrollable Grid? Which control should i use?
I tried Grid-View and as Grid-View can not have fixed rows so should i use Table-Layout or Grid-Layout ? or use linear-Layout in Grid-View ?
I want image to be displayed without being scaled down or scaled up so i am using AUTO_FIT and i get three rows with the below code but i want only two rows and two columns
#Override public View getView(int position, View convertView, ViewGroup parent)
{
ImageView view;
if (convertView == null)
{
view = (ImageView) convertView;
view = new ImageView(context);
view.setAdjustViewBounds(true);
view.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, GridView. AUTO_FIT));
}
else
view = (ImageView) convertView;
String url = getItem(position);
Picasso.with(context).load(url).error(R.mipmap.no_photo).fit().into(view);
return view;
}
Below is the sample attached image
I would recommend you use a RecyclerView with a GridLayoutManager. This will allow you to specify the number of columns:
recyclerView.setLayoutManager(new GridLayoutManager(context, 2));
If you would like to set the row height so that two rows always match the height of your screen, you could set it inside onBindView() of your adapter. You can ascertain the relative row height by subtracting the screen height from the height of your Toolbar:
//Could calculate this in your `Activity` class and pass the value to your Adapter
public int getProprtionalRowHeight() {
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
return ((height - toolbar.getHeight()) / 2);
}
In your adapter:
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
//...
ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
params.height = valueReturnedFromGetProprtionalRowHeight;
holder.itemView.setLayoutParams(params);
}
you can use StaggeredGrid for this purpose its stable and easy to use.
you can also use StaggeredGridLayoutManager with recycler view.
I have a ListView that every row shows different percentage.
and I wanna change one of inner layouts width (inside inflated counterView) for this purpose .
for example:
if first value item in listview is 10% then width set to 10px too
if second value item is 50% then width change to 50px too
something like this:
How can I do that ?
I tried these codes but it doesn't work and the width doesn't change:
(I defined match_parent width for layout inside XML and I wanna change it programmatically)
public class MyAdapterScores extends BaseAdapter {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.scores_layout,null,true);
//I wanna change 'relativeLayoutRightSqure' width inside 'scores_layout'
View layout = convertView.findViewById(R.id.relativeLayoutRightSqure);
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) layout.getLayoutParams();
//variable precentage has value
p.width=precentage ;
layout.requestLayout();
You can't just set the width to a percentage I think. I haven't tested this solution, but try it out! Might work!
One solution could be to set the width to a percentage of the total width of the display maybe:
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int layoutWidth = size.x * (percentage / 100)
Then you can use that variable "layoutWidth" to set the width on the layout you want.
please use the following code
RelativeLayout layout = convertView.findViewById(R.id.relativeLayoutRightSqure);
RelativeLayout.LayoutParams param=layout.getLayoutParams();
param.width=precentage ;
layout.setLayoutParams(param);
I found the problem !
the problem was defining android:layout_toRightOf and android:layout_toLeftOf for my inner counterView layout view simultaneously that causes setting width doesn't work !!
(
Referred to above code (relativeLayoutRightSqure):
View layout = convertView.findViewById(R.id.relativeLayoutRightSqure);
)
I would like the rows in a ListView to be sized so that exactly six of them can fit on the screen. For that, I would need to know how much vertical space is available to the ListView (not the whole screen). However, no measuring can be done in onCreate() since no views have been rendered yet.
If I make measurements after rendering, the ListView might be drawn and then resized, which may be distracting. What is the smartest way to establish the necessary row height before rendering the ListView?
in onCreate you can get the height of your screen and divide by 6.
Now in your getView you get the reference of the top layout for each item, suppost you have named it's id to root and i.e it's a LinearLayout.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(view == null){ some inflate }
LinearLayout root = (LinearLayout) view.findViewById(R.id.root);
LayoutParams lp = root.getLayoutParams();
lp.height = screenHeight/6;
root.setLayoutParams(lp);
....
return view;
}
Yes, this assumes the ListView is in fullscreen.
If you have other layouts, you will have to get those height into account.
Then your height will be: int heightForEachItem = (screenHeight - otherlayoutsHeightTogether) / 6;
Turns out that the earliest you can measure a ListView is in the onGlobalLayout() callback.
Here is my example.
params = new AbsListView.LayoutParams(-1,-1);
listview.getViewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
#Override
public void onGlobalLayout(){ //this is called just before rendering
params.height = listview.getHeight()/6; // this is what I was looking for
listview.getViewTreeObserver.removeOnGlobalLayoutListener(this); // this is called very often
}
adapter = new ArrayAdapter<...>(int position, ...){
#Override
public View getView(...){
LinearLayout item = new LinearLayout(context);
item.setLayoutParams(params);
// add text, images etc with getItem(position) and item.addView(View)
return item;
}
}
listview.setAdapter(adapter);
I have a number of elements in a ListView that scroll off the screen.
I would like there to be blank space at the end of the View. That is, the user should be able to scroll past the last element such that the last element is in the middle of the viewport.
I could use an OverScroller, but I think that would only enable the View to have a bouncy effect like one often sees on the iPhone.
Is there something I might have overlooked?
The scrolled-to-the-botton screen should look something like this:
The accepted answer is too complicated, and addFooterView is not for this kind of thing. The proper and simpler way is to set the paddingTop and paddingBottom, and you need to set clipToPadding to "false". In your list view or grid view, add the following:
android:paddingTop="100dp"
android:paddingBottom="100dp"
android:clipToPadding="false"
You'll get blank space at the top and the bottom that moves with your finger scroll.
Inflate any layout of your choice (this could be an XML of and ImageView with no drawable and with set height and width of your choice)
Measure the screen height and create new LayoutParams and set the height of it to 1/2 of the screen height
Set the new layout params on your inflated view
Use the ListView's addFooterView() method to add that view to the bottom of your list (there is also an addHeaderView())
Code to measure screen height
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int screenHeight = display.getHeight();
Code to set half screen height:
View layout = inflater.inflate(R.layout.mylistviewfooter, container, false);
ViewGroup.LayoutParams lp = layout.getLayoutParams();
lp.height = screenHeight/2;
layout.setLayoutParams(lp);
myListView.addFooterView(layout);
An Aside:
When you add a footer or header view to any listview, it has to be done before adding the adapter. Also, if you need to get your adapter class after doing this you will need to know calling the listview's adapter by getAdapter() will return an instance of HeaderViewListAdapter in which you will need to call its getWrappedAdapter method
Something like this :
MyAdapterClassInstance myAdapter = (MyAdapterClassInstance) ((HeaderViewListAdapter) myListView.getAdapter()).getWrappedAdapter();
this 100% works.
in adapter set your code like this
//in getCount
#Override
public int getCount() {
return ArrayList.size()+1;
}
//in getview make your code like this
public View getView(final int i, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.yourlayout, null);
if(i<getCount()-1) {
//your code
}
else{
ViewGroup itemContainer =(ViewGroup) view.findViewById(R.id.container);
itemContainer.setVisibility(View.INVISIBLE);
}
Return view;
}
if you have multiple listviews in your app, create an xml of a footer, something like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="200dp"
android:layout_width="match_parent"
android:layout_height="200dp"></LinearLayout>
and then in the code, use this:
listView.addFooterView(LayoutInflater.from(getActivity()).inflate(R.layout.empty200, null));
This do the job in a simple way
android:paddingBottom="100dp"
android:clipToPadding="false"
Try the followings:
View footer = new View(getActivity());
footer.setLayoutParams( new AbsListView.LayoutParams( LayoutParams.FILL_PARENT, 100 ));
// 100 is the height, you can change it.
mListView.addFooterView(footer, null, false);
In my application i have a list view and i am inflating a web view into the list view. I am able to load data and images into the list view item. The problem is the list items are not of same height due to different contents. I want to make all list items having same height
How to calculate the height of the list item that has the maximum data and set that height to rest of the list items in the list.
How would i do that.. i have no clue on that.. Say if the 10th item has the maximum height i want to apply that height to the rest. help me implement this please and thank you for your support
<?xml version="1.0" encoding="utf-8"?>
<WebView
android:id="#+id/wv1"
android:layout_width="fill_parent" android:paddingRight="20dp"
android:layout_height="wrap_content" />
Have an array of flags, say
boolean[] flags=new boolean[szieOfList];
fill this array to false;
Have a variable max height in your activity or adapter, say max, initialize it with 0 in onCreate method, now in getView method where you are inflating xml, write the following code:
LayoutInflater layoutInflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view= (WebView) layoutInflater
.inflate(R.layout.web_view, null);
if(flag[position])
{
LayoutParams params = view.getLayoutParams();
params.height = max;
view.setLayoutParams(params);
}
ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
//in here, place the code that requires you to know the dimensions.
flag[position]=true;
int height= view.getHeight();
if(max<height)
{
max=height;
notifyDataSetInvalidated();
}
else
{
LayoutParams params = view.getLayoutParams();
params.height = max;
view.setLayoutParams(params);
}
//this will be called as the layout is finished, prior to displaying.
}
}