Android HorizontalScrollView get width - android

I'm trying to implement a horizontal ListView using a HorizontalScrollView and adding 'items' to it within the code. Adding the items works fine. Now I want each item to be 1/7 of the ScrollView's width so I can display exactly 7 items without scrolling. I cannot figure out a way to get the width of the HorizontalScrollView.
My XML looks like this:
<HorizontalScrollView
android:id="#+id/information_popup_dialog_listScrollView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="7" >
<LinearLayout
android:id="#+id/information_popup_dialog_listParent"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
I add an item like this:
LinearLayout listContainer = (LinearLayout) view
.findViewById(R.id.information_popup_dialog_listParent);
LinearLayout listItem = (LinearLayout) inflater.inflate(
R.layout.information_popup_dialog_list_item, listContainer,
false);
listItem.setLayoutParams(new LinearLayout.LayoutParams(
width, LayoutParams.MATCH_PARENT));
listContainer.addView(listItem);
When I use measure() to get the width of the ScrollView I get the total width, not the visible width. So it keeps growing with every item I add.
HorizontalScrollView scrollView = (HorizontalScrollView) view
.findViewById(R.id.information_popup_dialog_listScrollView);
scrollView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
System.out.println("Width: " + scrollView.getMeasuredWidth());
I tried different ways using .getLayoutParams().width / getWidth(), both return 0.
Is there anyway to do this?
I'm doing all of this in the onCreateView() method of a DialogFragment.

You can get device's screen width, and then divide it by 7. Now, set this number you get after dividing screen width, as the width of your each view in HorizontalScrollView. This way you can have exactly 7 items visible on your screen.
I haven't tried this, but it should work and it is pretty easy to do.

Use view.getWidth() in onViewCreated(). LayoutParameters.width will return the value you put in the XML.
If it's still not working , then you'll need to getWidth inside the view.post() method. This makes sure the view has been laid out.

Related

Adding views dynamically to LinearLayout not working as expected

I'm inflating views inside a linearlayout dynamically, however once the linear layout reaches the end of the first row, it cuts off the rest and doesn't start on the second row.
for(int a = 0; a < mSkills.get(i).size(); a++){
View singleSkill = LayoutInflater.from(mContext)
.inflate(R.layout.singleskill, holder.mSkillLayout, false);
TextView skillText = singleSkill.findViewById(R.id.singleskilltext);
skillText.setText(mSkills.get(i).get(a));
holder.mSkillLayout.addView(skillText);
}
For the linear layout I have it set to wrap_content for the height:
<LinearLayout
android:id="#+id/ll_skills"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="#+id/tv_description"
android:layout_margin="16dp"/>
I've tried setting it to a defined height e.g 300dp however that doesn't work either.
How can I make the layout start on the second row, once the first is full?
Linear Layout can either fill views horizontally or vertically so the 2nd row you are expecting cant to be done with linear layout only. you can try a horizontal scroll view for that to scroll horizontally. For the exact view-like flow that you described, you can use this 3rd party https://github.com/nex3z/FlowLayout
It can manage the flow of your dynamically inflated view such as if there is no space in the first line then it will put the next view in the second line.
also, you can use material design library chips https://material.io/components/chips/#usage
LinearLayout works exactly how it has to be because you specify it as horizontal. For such behavior, you need RecyclerView With GridLayoutManager or create your own layout;).
Actually it's doing exactly as it should be, LinearLayout is Linear!, and place its subviews in a single horizontal or vertical row.
My advice to you is that create dynamic horizontal LinearLayout as you already doing with TextViews. and put every 3 or 4 textviews (depending on screen size) inside it.
and put all LinearLayouts inside one vertical LinearLayout...
Of course in your case, it's not a good idea, the best thing you can do is to use recycler view. but I consider you have problem with that.

Unable to set layout width, height and weight of inflated view in XML in Android

I am developing an Android app. In my app, I need to inflate list of views dynamically. I added them and working. The problem is with setting the width and height of layout. Now I will demonstrate my problem with a simple project. Actually, my project is much more complicated than this simple project.
I am inflating views to this layout.
<LinearLayout
android:orientation="horizontal"
android:id="#+id/cm_photos_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
I am looping through a list of bitmap and adding view dynamically as follow
for(Bitmap bmp : bitmaps)
{
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,null);
ImageView previewImageView = (ImageView)preview.findViewById(R.id.item_cm_preview_image);
previewImageView.setImageBitmap(bmp);
container.addView(preview);
}
Please note, in the above code, container is a LinearLayout added dynamically to the parent XML in the above.
container = new LinearLayout(this);
container.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
container.setLayoutParams(params);
parentLinearLayout.addView(container);
This is my item_cm_preview_image.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_weight="1"
android:layout_height="400dp"
android:layout_width="0dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:scaleType="centerCrop"
android:id="#+id/item_cm_preview_image"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
As you can see, I set the layout height to 400dp, width 0 and layout_weight to 1 in the XML. So all image height must be same and width must be equal because of layout_weight. But the result is not as expected. You can see screenshot below.
As you can see in the screenshot, both layout_weight and height are not working for all inflated views. But if I add extra ViewGroup dynamically and inflate the view to that layout, it is working. Below is my code
//This happening in for loop
LinearLayout wrapper = new LinearLayout(this);
wrapper.setLayoutParams(new LinearLayout.LayoutParams(0,500,1));
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,null);
ImageView previewImageView = (ImageView)preview.findViewById(R.id.item_cm_preview_image);
previewImageView.setImageBitmap(bmp);
wrapper.addView(preview);
container.addView(wrapper);
This is the result:
As you can see both layout_weight and height working when I use an extra dynamic linear layout. Why is setting layout weight and height in XML not working? Why second way is working? How can I set weight and height in XML layout file? Is it possible?
If you inflate layout using method
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,null);
it skip its width and height parameters..., but if you will use:
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,parent,false);
it should work correct, for example if you inflate view in activity as parent you can provide (ViewGroup) getView():
View preview = layoutInflater.inflate(R.layout.item_cm_preview_image,(ViewGroup) getView(), false);

TextView inside FrameLayout being cut-off and not wrapping

Ive got a FrameLayout which im dynamically adding TextViews to. Currently, the TextViews near the edge arent wrapping at the end of the parent FrameLayout and are going off screen. The FrameLayout is using wrap_content for both the width and height:
<FrameLayout
android:layout_margin="10dp"
android:id="#+id/wrappingFrameLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00ff00"
>
The TextViews are just being created, then translated to a certain spot using .setTranslationX() and .setTranslationY().
I've tried getting it to wrap using some answers found elsewhere on SO, such as setting LayoutParams to WRAP_CONTENT on the TextView:
newTextView.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT));
I've also tried newTextView.setSingleLine(false); but that didnt work either.
Any ideas?
EDIT: So I noticed that none of the dynamically added views respond to any methods on them except things like color/textsize. I tried calling methods like setMinLines(3) and .setWidth(100) and they had no effect.
You can try using FrameLayout.MarginLayoutParams instead of .setTranslationX() and .setTranslationY() to position the TextViews.
Something like:
FrameLayout.MarginLayoutParams layoutParams = (FrameLayout.MarginLayoutParams)textView.getLayoutParams();
layoutParams.leftMargin = xPosition;
layoutParams.topMargin = yPosition;
textView.setLayoutParams(layoutParams);
(I was having the opposite problem. The TextViews were wrapping but I wanted them to be cut-off. I was using the LayoutParams and margins. Changing to setTranslation fixed it for me.)

Change child views to fit parent's width when added dynamically

I have a custom view which I add child views to dynamically.
When each child is added, I need to recalculate the size of the views so they can fit the parent's width
For example:
If I have a TextView:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:padding="8dp"
android:clickable="true"
android:textColor="#666666"
android:visibility="visible"/>
If I add three of these to a horizontal LinearLayout within the xml it correctly sizes the three views so the total widths match the parent.
But I want to inflate them one at a time and add them so can reuse elsewhere in the code if we want a different number of TextViews in a layout.
When I do this, the total width is less than its parent, and I can't get the views to resize when a new one is added.
Here's where I inflate the view:
layout = (LinearLayout) inflater.inflate(R.layout.segmented_control, this);
TextView item = (TextView) inflater.inflate(R.layout.segmented_control_item, null);
Change the width to match_parent, i think you need to keep the weight. Pass the parent layout to the inflater.
layout = (LinearLayout) inflater.inflate(R.layout.segmented_control, this);
TextView item = (TextView) inflater.inflate(R.layout.segmented_control_item, layout, false);
layout.addChild(item);
I'm not sure if that works right away, you might need to experiment a little with the layout paramters.
Change your TextView layout width to fill_parent and remove the weight. I think that it should work.

RelativeLayout in a ListView

Good Afternoon,
I am having trouble getting a RelativeLayout to work within a ListView. If I change the layout to linear etc. I see it behave as I would expect but the RelativeLayout is scrunching everything up into overlapping space. Now my uneducated guess is that it is trying to cram everything into on row. I thought it would expand that row but perhaps not or that is not the problem.
Note my code has been abbreviated for space.
Anyway in my Parent XML:
<LinearLayout ..._width="fill_parent" ..._height="fill_parent" ...orientation="vertical" >
<ListView ...layout_width="fill_parent" ...layout_height="fill_parent" />
</LinearLayout>
So my thought was that this would fill the device screen and in the GraphicalLayout view in Eclipse it appears that it does.
My "row" definition for the ListView is this:
<RelativeLayout width="fill_parent" height="fill_parent" >
<ImageView
android:layout_width="60dp"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:layout_marginTop="15dp"
android:layout_marginLeft="5dp" />
.....
</RelativeLayout>
As mentioned I thought this would fill all available space but it seems to only fill some sort of "default" row height?
Not sure what I am missing but any help would be greatly appreciated.
use the layout attributes layout-above, layout-below, layout-toRightOf, layout-toLeftOf in your xml. that way the items will be put next to where you want them to go. right now you are setting everything according to the parent so they are all going to overlap
RelativeLayout by default adds it's children anchored to the top left corner of the layout.
By using the very handy attributes of RelativeLayout, you can arrange the children both
relatively to each other, and
relatively to the parent view.
layout_alignParentLeft, ..Right, ..Top, ..Bottom, layout_centerInParent, layout_centerHorizontal, layout_centerVertical, layout_toLeftOf, ..toRightOf, ..above, ..below
These attributes will help you get the desired display in a very efficient (flat) way, so I'd suggest keep reading it up and consider using it instead of other layout containers for complex views.
I ended up overriding the getView of the ArrayAdapter and then setting the height and width to the dynamically determined screen size
...snip....
int[] iarry_ScrnDim = new int[2];
DisplayMetrics metrics = new DisplayMetrics();
metrics = ctx_Currnt.getResources().getDisplayMetrics();
iarry_ScrnDim[0] = metrics.heightPixels;
iarry_ScrnDim[1] = metrics.widthPixels;
return iarry_ScrnDim;
....snip....
if (vw_BigRow == null)
{
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vw_BigRow = inflater.inflate(R.layout.liftdatalayout, null);
}
vw_BigRow.setMinimumHeight(mHeight);
vw_BigRow.setMinimumWidth(mWidth);

Categories

Resources