ListView doesn't wrap content after child changes visibility - android

i have a ListView whose children toggle visibility on clicked. Each item has two children and only one is visible at a time, the other is gone, If the item is clicked the visibilities of its children are toggled.
The quite unfortunate thing is that one child is taller than the other so the height of the listview needs to be altered at each toggle but this doesn't happen. The height stays fixed.
I have tried playing with LayoutParams but got nothing out of it.
How can I fix this?

After a lot and a lot of trial and error, I managed to get this to work simple by altering the LayoutParams of the listview after changing the visibility of the views.
view.setVisibility(View.GONE);
LinearLayout layout = (LinearLayout) view.getParent();
layout.getChildAt(0).setVisibility(View.VISIBLE);
((ListView) layout.getParent()).getLayoutParams().height =
LinearLayout.LayoutParams.MATCH_PARENT;
Note that an item in my ListView looks like this
<LineaLayout>
<LinearLayout
onclick="alterVisibility">
</LinearLayout>
<LinearLayout
onclick="alterVisibility"
visibility="gone">
</LinearLayout>
</LinearLayout>

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.

Linearlayout with weightSum and three layouts

Below is the item of layout i am using in listview.The issue is that when i make visibility of countlayout gone in some items of list I expect vibelayout to be exactly at same place where countlayout was since weigtSum is 3.But it is appearing slightly right of position where countlayout was.
I am using View.GONE so that countlayout space is assigned to vibelayout but its not happening.. vibelayout is appearing slightly right of position where countlayout was.
Try using android:layout_width="0dp" in all 3 layouts. It will solve your problem

How to add a LinearLayout in the same activity which has Listview?

I have an Activity where there is a Linear Layout which occupies nearly half of the screen and below that I need to keep a listview which has hold any number of items. Now initially I was doing like this
<ScrollView>
<LinearLayout>
</LinearLayout>
<ListView>
</ListView>
</ScrollView>
But reading all the threads I think it is not really a good idea keeping listview inside Scrollview. Also I am facing a lot of issues like the height of the Listview is not proper.
So how do I keep the layout and listview inside the same activity without using ScrollView?
It is not recommended to include a scrolling View (ListView) inside a ScrollView. What you want to achieve can be done by adding a HeaderView which can be inflated from another XML.
LinearLayout ll = inflater.inflate(R.layout.my_layout, null);
listView.addHeaderView(ll);

Divider disappears from last item in listview if footerview added

If footer view added in ListView, then divider disappears from last item of ListView.
Even I have set android:footerDividersEnabled="true" with ListView and my footer view is just TextTiew.
Setting isSelectable to true didn't work for me, maybe because I was also calling removeFooterView when my list was done loading.
What finally fixed it for me was setting android:layout_height to "fill_parent" instead of "wrap_content" on the ListView.
The ListView implementation in Android never draws dividers between items that are disabled, which if you are just calling the addFooterView(View v) method then by default your footer will be.
Instead you need to call the addFooterView(View v, Object data, boolean isSelectable) method with isSelectable set to true. You can just pass null for the data object if you don't need it.
This almost worked for me. I was after a divider after the last list item, but not after the footer as my footer was empty space. I ended up adding two footers, one selectable of zero height and one not selectable containing the padding.
TextView view = new TextView(this);
view.setLines(0);
TextView view1 = new TextView(this);
view1.setLines(4);
mListView.addFooterView(view, null, true);
mListView.addFooterView(view1, null, false);
mListView.setFooterDividersEnabled(true);
Try setting the layout_height of the ListView to match_parent:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#333333"
android:dividerHeight="1px"
When the layout_height is set to wrap_content it might skip the bottom divider:
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#333333"
android:dividerHeight="1px"
Head through the wall approach, but reliable, is to manually add divider as a footer view.
ListView myListView = (ListView) view.findViewById(R.id.my_list_view);
myListView.addFooterView(getInflater().inflate(R.layout.horizontal_divider, myListView, false), null, false);
myListView.addFooterView(getInflater().inflate(R.layout.the_original_footer_view, myListView, false), null, false);
Where the layout file would look like this:
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?android:attr/dividerVertical" />
This approach can be used to add the divider easily even after the last footer, regardless it is selectable, enabled or anything - it just stays there.
Note the height is 1px rather than 1dp. Though against all recommendations, at least at the device I tested this gives the same divider height as ListView, while 1dp does not.

How can I get my ListView to scroll?

I have a quite complex View build-up, and as a part of that, I have a ListView inside a LinearLayout within a ScrollView (and quite a lot more components, but they do not matter in this issue).
Now the whole activity scrolls nicely as it should, but the ListView has a limited height, and when the Items inside it surpass the height, the disappear of my screen. I've tried to place the ListView inside it's own ScrollView, but this doesn't work. When I try to scroll on the ListView, the main ScrollView is selected and my screen scrolls instead of the ListView.
My question may sound easy, but I haven't been able to fix this... Is it possible to make the ListView scrollable aswell?
The relevant XML:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:id="#+id/GlobalLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView android:id="#+id/EndpointList"
android:choiceMode="multipleChoice"
android:layout_height="175dip"
android:layout_width="fill_parent" />
</LinearLayout>
</ScrollView>
Instead of ListView with other layouts inside ScrollView create one ListView with header and footer.
Add views that should be above ListView as a header:
addHeaderView(View v)
and that below as a footer:
addFooterView(View v)
Put everything what should be above ListView to header of ListView and the same with footer.
LayoutInflater inflater = LayoutInflater.from(this);
mTop = inflater.inflate(R.layout.view_top, null);
mBottom = inflater.inflate(R.layout.view_bottom, null);
list.addHeaderView(mTop);
list.addFooterView(mBottom);
// add header and footer before setting adapter
list.setAdapter(mAdapter);
In result you'll get one scrollable view.
Actually, the way that I have it set up is really working... Placing a ListView in a LinearLayout within a ScrollView. Just avoid that the ListView is the direct child of the ScrollView, and it will work out just fine...
Just be aware that if there aren't enough items in the ListView to fill it so it goes 'off screen', that it won't scroll (kind of logically though). Also note that when you have enough items to scroll through, you need to keep pressing on an item in the ListView to make it scroll, and half of the time, focus is given to the global scrollview in stead of the ListView... To avoid this (most of the time), keep pressing on the most top or most down item, depending on which way you want to scroll.This will optimize your chance to get focus on your ListView.
I've made a video that it is possible, am uploading it now to YouTube...
Video is http://www.youtube.com/watch?v=c53oIg_3lKY. The quality is kinda bad, but it proves my point.
Just for a global overview, I used the ScrollView to be able to scroll my entire activity, the LinearLayout for the Activity's layout, and the ListView to, well, make the list...
I would like to just note something for the video
The listview is working once every x touches not because you placed it inside a linearlayout but because you are touching the the divider...
the scrollview will then consider that the place you touched does not have children to dispatch the motionevent to... so it calls the super.dispatchTouchEvent which is in this case the View.dispatchTouchView hence the listview.onTouchEvent.
When you touch inside a row the scrollview which is really a viewgroup will send the dispatch to the children in your case the textview and never calls the one of the view so the listview do not scroll.
Hope my explanation was clear enough to point out why is it not working.

Categories

Resources