Dynamically update list element height in ListView - android

I have a list.
When you click on element, it becomes selected, and should be expanded vertically to displat some more data.
I am trying to accomplish this by adding to each element's layout "Details" view which is hidden by dafault and is set to VISIBLE onClick.
The only problem that the height of element isn't changed.
If I try to it like this:
holder.line_view
.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, dip(
convertView.getContext(), 30)));
then I get unknown exception.
Just
holder.details_pane.setVisibility(View.VISIBLE);
doesn't work, the size isn't changed.
Please advise.
Layout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/line_view">
<TextView
android:id="#+id/desc"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Description" />
<TextView
android:text="LALALA"
android:id="#+id/detailed_desc"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
In adapter I try:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
...
switch (getItemViewType(position)) {
case TYPE_ITEM_EXPANDED:
holder.details_pane.setVisibility(View.VISIBLE);
...
case TYPE_ITEM_NORMAL:
holder.details_pane.setVisibility(View.GONE);
}

"doesn't work, the size isn't changed"
something to try if you allow your view to be rotated: make your view redraw itself and see if the row is bigger.
It might be that you just need to invalidate the listview so that it redraws. Possibly invalidate the row.
maybe it's even as easy as calling notifyDataSetChanged(); on your custom listview adapter

I have no idea about the issue of you code. but you should try this
com.android.widget.ExpandableListView
com.android.widget.ExpandableListAdapter
this is designed for your requirement and shipped with the OS

Related

Spinner dropdown height to match parent

Is it possible to adjust height of Spinner dropdown to fill the entire screen. Right now i have 3 items that i dynamically add into the spinner adapter but these only cover half of the screen. What i have right now is something like this:
What i want is something like this:
I could add empty items but that won't solve the problem for different screen sizes
I tried to implement a style on the spinner but it didn't work
<style name="MyCustomSpinner" parent="Widget.AppCompat.Spinner.DropDown">
<item name="android:dropDownHeight">match_parent</item>
</style>
UPDATE
I have a view between action bar and spinner so i cannot use layout_weight=1 for my spinner
try using this with your adapter.
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
The only way to achieve this is by writing your own view that works like a spinner.
In yourspinner.xml,
add the android:minHeight="48dp" to TextView element. see the example below-
<TextView
android:id="#+id/textViewRowFacility"
android:minHeight="50dp" />
Try to put your Spinner in LinearLayout & set spinner weight to 1 like
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Spinner
android:id="#+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
Set the weight of the spinner to take the entire space. If no other view is there in the Layout then use this code:
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
To learn more about android weight refer to this:
What does android:layout_weight mean?
Try using the code below
ArrayAdapter<String> yourSpinnerAdapter = new ArrayAdapter<String>(this,
R.layout.spinner_item, yourItem) {
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
convertView = super.getDropDownView(position, convertView,
parent);
convertView.setVisibility(View.VISIBLE);
ViewGroup.LayoutParams p = convertView.getLayoutParams();
p.height = 100; // assign the required height here
convertView.setLayoutParams(p);
return convertView;
}
};

How to horizontally center composite list view items inside the list view?

I have a list view displaying items from a custom adapter which extends ArrayAdapter. Each item is a custom layout with a RelativeLayout being the root view. Now, I want this RelativeLayout to be centered horizontally inside the list view, but I everything I tried seems to fail.
Here's my custom adapter getView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = mInflater.inflate(R.layout.screens_listview_row, parent, false);
return row;
}
And here's the file screens_listview_row.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/root"
.....
android:layout_gravity="center_horizontal" >
</RelativeLayout>
At first, it seemed like my layout parameters in the RelativeLayout were completely ignored, and it really was the case because i used inflate(R.layout.screens_listview_row, null), what is a problem like this answer says.
So now the only thing ignored is the layout_gravity parameter. I also tried layout_marginLeft (Everything in this layout is in absolute sizes so I could center it myself by giving a left margin...) but Android ignored it too. What is the problem here?
try to use gravity instead of layout_gravity (as i know gravity is for the content of layout)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/root"
.....
android:gravity="center_horizontal" >
</RelativeLayout>
I didn't find out how to control the position of the items inside the ListView, so instead I made the ListView width exactly as the items' width, then controlled its position (Which practically controls the items' position).

ListView being drawn twice

So I am rather confused right now. I am using an XML layout so I can show an empty view like so:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="#string/samples_empty"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
As you have probably seen a billion times here on so.
So I do setContentView(R.layout.foo) and it works the first time, but if I return to this Activity (As in onPause has been called and then onResume) I get this:
I call notifyDataSetChanged(); on the adapter and that works fine, what I don't get is why its being drawn twice?
Its not like I am creating a new ListView and then adding it to the view, I'm sure I would know about it if I was.
The getView method of the adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RecordView av;
if(convertView == null){
av = new RecordView(mCtx, this, mRecords[position], position);
}else{
av = (RecordView) convertView;
av.setRecord(mRecords[position]);
}
return av;
}
This would be what it would look like normally...
NOTE
This doesn't seem to be happening every single time, and doesn't happen on a single event happening, but when it does, its when I return from another screen.
UPDATE
I noticed that when I had another activity on top (something that was transparent, like facebook chat heads, then I could see that the problem had occurred then, It doesn't seem to happen on onResume, but more likely on onPause which I actually don't do anything in.
You have this problem because you are dynamically create the row view each time while the convertview still has the old view existing and it is being reused. To get around this problem, you should give an id to every view (that is, every child view in your RecordView)when you dynamically create them, for example a child textview in your RecordView class should be instantiated like this
TextView tv = new TextView(this.getContext());
tv.setId(1);
...
Then, in your getView:
if(convertView == null){
av = new RecordView(mCtx, this, mRecords[position], position);
}else{
av = (RecordView) convertView;
av.findViewById(1).setText(mRecords[position]);
}
assuming your mRecords holds an array of String. If you have variant layout for different rows, you can provide a type to each view. See this for further details.
try changing android:layout_height="wrap_content" of listview to android:layout_height="fill_parent"

getView() not working properly

Look at the code :-
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
row = inflater.inflate(R.layout.country_row, parent, false);
}
return row;
}
The country row XML is :--
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="1" >
<TextView
android:id="#+id/nameOfCountry"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:text="Country" />
<CheckBox
android:id="#+id/checkBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:gravity="right" />
Now my question is once I check few of the check boxes in the list view and the scroll the list view, many other check boxes are automatically checked....
I know there is problem in getView but I'm not able to figure out where....
Also the problem is solved if I don't reuse the convert view. But that is a dumb idea...
Any thoughts.....
That's because the ListView does recycling of views. Essentially, it reuses some views that go off screen to make the new ones on screen to help with performance. There are 2 ways of dealing with this:
Set the values of the views before you return the row. For example, you would set the nameOfCountry and whether or not the checkbox is checked before the return view line. To do this though, you need to keep track of what is checked.
Don't use the convertview and just inflate a new view every time. This may result in a performance hit, but as long as the list isn't too long it shouldn't be too noticable (at least in my experience). Simply igonre the convertview value
You have to set the state of the checkbox explicitly if you reuse an old View.

How to put divider at particular position in an Android list view

I need to make a list view in which I want to have a divider at some position only not after every list item. I am using custom list view.
Is there any solution of this problem?
you can you this xml file in list adapter class like
ItemsAdapter ItemsAdapter = new ItemsAdapter(EnterpriseFertilisersScreen.this,
R.layout.list, Constant.FERTILIZERMANAGERARRAY);
R.layout."below xml file " and user as further white color.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:background="#color/list_bg" >
<TextView
android:id="#+id/post"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginLeft="7dp"
android:layout_toRightOf="#+id/bite_image"
android:gravity="center_vertical"
android:textColor="#android:color/white"
android:textSize="20sp" />
</RelativeLayout>
If you have another issues, ask feel free..
You can create Adapter for list, which will be place dividers as elements (via getView).
This is standart android approach
If you have used Custom ListView to show your .you need to make position where you need to show different View from xml by condition .you should have to do this in getView Method.
Either you need to see how this example use divider using CursorAdapter.
Check this https://github.com/cyrilmottier/ListViewTipsAndTricks/blob/master/src/com/cyrilmottier/android/listviewtipsandtricks/SectionedListActivity.java
you can add it to getview Methoid as follow :
public View getView(int position, View convertView, ViewGroup parent) {
if(items.get(position).get("name").startsWith("-")){
View divider = mInflater.inflate(R.layout."yourlayout",null);
return divider; }
also, you must add item names starting with "-" where you want to add a divider.
Hope this helpful

Categories

Resources