Change width of a ListView item(row)? - android

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);
)

Related

Set vertical RecyclerView height to correspond to only N items height

Each row in my RecyclerView is a single-row TextView with a certain size.
I'm looking for a general implementation such that the RecyclerView's height is set to correspond to the height of N such rows.
At the moment I'm using a magic value corresponding to 3 * rowHeight but it wouldn't be valid if I would change the text size of TextView.
Is this possible?
Edit: all rows have the same height
Make your itemView a LinearLayout which have vertical orientation. Then give it's width and height programmatically in your viewHolder like this.You have to calculate each rows width and height.
LayoutParams params = layout.getLayoutParams();
params.height = your_height;
params.width = your_width;
layout.setLayoutParams(params);
However if you have only 2,3 or 4 different heights, I mean these are specific for your recyclerView, you have to use getItemViewType() and make your different layouts and different ViewHolders for each type.
I ended up using the solution given in the comment.
Inflating the row view and then changing the layout params.
fun calculateRowHeight(layoutInflater : LayoutInflater, large: Boolean = true): Float {
val textView = layoutInflater
.inflate(R.layout.recycler_view_row, null) as TextView
val fm = textView.paint.fontMetrics
return fm.descent - fm.ascent
}
recyclerView.apply {
...
layoutParams.height = N * rowHeight.toInt()
}

How to set a single recyclerview item [imageview] take half of the screen?

I have inflated recyclerview item from single_item.xml and it has only one imageview. How do i make it take half of the screen?
Or in another way, how can i show two items per screen in the main xml file that inflates single_item.xml file?
And i want to do this without setting fixed height.
I tried with layout weight division, but that disables the hosting view from displaying two item instead of one.
The best way to do this is to add code to onCreateViewHolder() that changes the item view's height (if you're using a vertical layout manager) or width (if you're using a horizontal layout manager).
Here's an example for how to make each item be half the size of the screen:
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.itemview, parent, false);
// here we override the inflated view's height to be half the recyclerview size
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) itemView.getLayoutParams();
layoutParams.height = (parent.getHeight() / 2) - layoutParams.topMargin - layoutParams.bottomMargin;
itemView.setLayoutParams(layoutParams);
return new MyViewHolder(itemView);
}
If your item view layout doesn't have any margins, you can leave off the subtraction of margins and just use
layoutParams.height = parent.getHeight() / 2;
If you're trying to use a horizontal layout manager instead, you'd change the width instead of the height:
layoutParams.width = (parent.getWidth() / 2) - layoutParams.leftMargin - layoutParams.rightMargin;

Setting ImageView width and height before drawing in a ListView adapter

I have an adapter to a ListView is a list of ImageViews. I am using a stretch to make the image fil the imageview so I can take smaller images and make them larger on the screen, however the ImageView normally just uses wrap_content and this is an issue because the images just show up as their normal width and height. Is there any way I can set the height and width of a view before drawing it because as in this case I do not have control over the view after it has been drawn. Here is my aapter method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String currentImage = getItem(position);
ScaleType scaleType = ScaleType.FIT_CENTER;
float screenWidth = parent.getResources().getDisplayMetrics().widthPixels;
if (convertView == null) {
convertView = new ImageView(parent.getContext());
}
// WHAT I WOULD LIKE TO BE ABLE TO DO, but this returns null pointer exception
// convertView.getLayoutParams().width = (int) screenWidth;
// convertView.getLayoutParams().height = (int) ((float)(screenWidth/currentImage.getWidth())*currentImage.getHeight());
((ImageView) convertView).setScaleType(scaleType);
((ImageView) convertView).setImageBitmap(MainActivity.cache.getBitmap(currentImage));
return convertView;
}
How about something like someView.setHeight() and someView.setWidth()? Or someView.setLayoutParams()? You could add either of these to the overridden getView() callback and it should take care of your problem.
You could also Create a Custom View and override something like getMeasuredWidthAndState(). (I think that's one of the right methods, but I'm not one hundred percent sure.) You could create a width class variable and a height class variable that all instances of your custom ImageView would use. However, that might be a bit much if you just want to set the layout width and height though.

Android List view fill the height to the contents

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;
}
}

How can I add blank space to the end of a ListView?

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);

Categories

Resources