I have a listview and I want to change the dividerHeight for specific Item.
For example I want it look like that:
Item 1
Item 2
Item 3
// Bigger space here
Item 4
Item 5
I know how to change space between each Items but how can I specify a space depending on the item position in the list.
The other possibility is to use a different drawer for some items.
Thanks a lot
PS: Sorry for my bad english, I'm french
EDIT: Here is the code where my Items are displayed on my Listview:
drawerItemsList = getResources().getStringArray(R.array.items);
myDrawer = (ListView) findViewById(R.id.my_drawer);
myDrawer.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_item, drawerItemsList));
You can customize your adapter by extending ArrayAdapter class and then do what you want in its getView method, A simple solution for your problem might be the following snippet code:
#Override
protected View getView(int position, View convertView, AdapterView parent) {
View view = convertView;
// Check 'view' value and inflate it if needed
if(position == 3) { // Gap index in the list
// Here you can add some additional bottom margin or padding to the
// 'view'.
// Or you can left this view empty like a free space
}
return view;
}
Related
I'm trying to implement a custom listview. Everything works fine until I use a if () statement inside the getView() method
Without the if() condition a single item gets selected when I select an item but when I add the if() condition, the views are displayed properly but two items (non-adjacent) get selected (1st and last 1st or and second-last, any such combination).
View getView(...){
....
if (!item.getPriceTo().equals(""))
priceToTV.setText(item.getPriceTo());
else
priceToTV.setText(item.getPriceFrom());
return view;
}
Also I'm using saving the previous view to show the selection so the current selection has a red_border and when it is selected a black_border is set to it.:
subItemsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Log.d("New Order", "........");
if (previousViewOfSubItems != null && previousViewOfSubItems != view) {
previousViewOfSubItems.setBackgroundResource(R.drawable.black_border);
if (quantity.getText().toString().equals("xx") || quantity.getText().toString().equals("0")) {
viewForVisibility.setVisibility(View.GONE);
layoutForQuantity.setVisibility(View.GONE);
}
}
if (previousViewOfSubItems == view)
return;
previousViewOfSubItems = view;
previousViewOfSubItems.setBackgroundResource(R.drawable.red_border);
viewForVisibility = previousViewOfSubItems.findViewById(R.id.viewForVisibility);
viewForVisibility.setVisibility(View.VISIBLE);
layoutForQuantity = (LinearLayout) previousViewOfSubItems.findViewById(R.id.layoutForQuantity);
layoutForQuantity.setVisibility(View.VISIBLE);
quantity = (TextView) previousViewOfSubItems.findViewById(R.id.subTypeQuantity);
}
});
previousViewOfSubItems = view; seems to be causing the problem,
In Listviews with adapter you should avoid saving view instances, because views are reused by adapters so view can be same for two rows so rather than saving view instance's reference use ViewHolder Design pattern and use view tagging
You need to use ViewHolder Pattern and view tagging to properly identify every view in different position. ListView always recycle the view instead of re-inflating the view again and again.
You can refer to Android Training documentation on how to implement ViewHolder pattern.
ListViews recycle the views in the list. so as you scroll, top views are reused and content replaced using the methods.
Where you set background to Red etc, use Else statements to set it back to your default black.
its beacause it listview reuses view to display items, once the first view is scrolled out the the same view is reused to display the view at bottom of the listview. instead of comparing the view try compairing the position of the view clicked
I have explained about this abnormal behavior in my blog on recyclerview you refer that to solve this problem.
use pojo class to get the status and update the view accordingly
In android, is it possible to get all items inside the list view. Lets say the list view has multiple rows and only 2 rows are visible on the screen while the rest are accessible using the scroll bar. Each row has a radio button and a text view. Is there a way to get all textview of the rows whose radio button is selected and not just the ones visible on the screen.
Your answer may be:
for(int item = 0; item < m_listitem.count(); item ++){
if(m_listitem[item].isSelected){
View view = ListView.getChildAt(i);
TextView textview = view.findViewById(your textView id);
// do some thing
}
}
You can use custom list view to show your list items with checkbox & textview.
I happened to have a similar requirement where I had multiple EditText inside a ListView and only few of them were visible on the screen. I needed to get the values of all EditText and not just the ones visible on the screen.
Well if you are using a default Adapter, then the way it will work is it will recycle the old views to create new ones. So there is no way to preserve values of those Views which are not visible.
So the only workaround is to create your own Adapter, maybe something like the following, which will not recycle any views, but every time inflate new ones.
public class ListViewAdapter extends ArrayAdapter {
public ListViewAdapter(Context context, ArrayList<Object> items) {
super(context, 0, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return LayoutInflater.from(getContext()).inflate(R.layout.your_layout_for_list_view_item, parent, false);
}
}
After that, as in above answer Lãng Tử Bị Điên has mentioned, you can check in your java code, if your radio buttons are checked or not, and according to that, selected desired TextViews
for(int item = 0; item < m_listitem.count(); item ++){
if(m_listitem[item].isSelected){
View view = ListView.getChildAt(i);
TextView textview = view.findViewById(your textView id);
// do some thing
}
}
Hopefully this should do it.. It sure worked in my case!
I would like to change the text color of only one item in a listview.
This change will be triggered by the result of a running asynctask.
So far I searched on google and all I found was to overwrite the getView() function of the adapter, but this approach is kind of hard since I would need to keep the id of the rows I want to color in a global variable that will be accessed by getView().
Is there another way to simply set the text color of an item from a listview when an event happens ?
EDIT
I create the listview this way:
myListView = (ListView) findViewById(R.id.listView);
listAdapter = new ArrayAdapter<String>(this, R.layout.simplerow);
listAdapter.add("test");
myListView.setAdapter(listAdapter);
For setting a color for a list item definitely you need to override the getView() method of the Adapter. Here is a small example for updating the color of the list item without using the id of the item.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.simplerow) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if (position % 2 == 0) { //Place the condition where you want to change the item color.
view.setBackgroundColor(Color.GRAY);
} else {
//Setting to default color.
view.setBackgroundColor(Color.WHITE);
}
return view;
}
};
In the above example, all the list item at even number positions will be in GREY color and others will be WHITE color. We cannot do this without implementing the getView(). For reference Click Here
You may set custom object vis color in adapter then change color in this adapter and call notifyDataSetChanged()
The Problem
My way to add the view makes every fifth item to add the view when i only want one position to have this "Mängd" row.
Why Can i only edit listitems when they are visible on the screen.
The child will be static at 5 items even though i got like 20 item....
Is there any way to only say that item 1 will have this and not
position - firstvisibleposition
i think this is the problem with the listview
My code is not understandable at the time because of other things so i hope you get my problem anyways.
This is my main question
It seems like the thing i add to position 0 also happens to 6 and 12 Why is ListView this wierd ?
It's on swedish, but this is what i got with list view.
Every listview item has a empty Linearlayout that i add a view to when i press the down arrow button. the problem is that every fifth item gets this or i can only click on the first 5.
I dont get why they make ListView so complicated. i want to be able to get a child that is in the list without seening it!
CODE getView
public View getView (int position, View convertView, ViewGroup parent){
if (convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.view_meal_item_editable, null);
}
convertView.setOnTouchListener(new ItemSwipeListener(position,
getResources().getDisplayMetrics().density));
convertView.setClickable(true);
// Lookup view for data population
TextView food_item_name = (TextView) convertView.findViewById(R.id.food_item_name);
food_item_name.setHint("hello");
}
Where i add the view
View view = searchResultList.getAdapter().getView(position, searchResultList.getChildAt(position - searchResultList.getFirstVisiblePosition()), searchResultList);
LinearLayout extendedView = (LinearLayout)view.findViewById(R.id.extended_food_information);
View convertExtendedView = LayoutInflater.from(this).inflate(R.layout.change_amount_on_food_view, null);
extendedView.addView(convertExtendedView);
It's recommended to use a header view if you do this stuff only for the first element.
Otherwise it will be better if you add your extra view in getView() method, something like:
if(position==0){
// add extra view
} else {
// remove extra view if exist
}
Or you can remove the IF condition: if (convertView == null), so you will inflate a new layout each time, it will solve your problem but this is not good for list performance
when my ListView is being filled by a custom Array Adapter, I check for a certain parameter in the current list item, and if it is false, I want to return an empty row. At the moment, I am doing this by inflating an empty xml file, but that creates ugly list item dividers when a number of items should not be shown, and is obviously not the best way ;-)!
if (list.get(position).equals("i-dont-want-this-in-the-list-view")){
View empty=inflater.inflate(R.layout.empty_row, parent, false);
return(empty);
}
I have tried to return "null", but it clearly expects a View to be returned. Is there anything I could do without having to filter the list that is being used for the ListView beforehand (I want to keep it intact as I am doing other things with it, too).
Thanks,
Nick
To fix the issue of line dividers, remove the line dividers from the ListView and put your own in inside the individual items.
Inflate a View and setVisibility to VIEW.GONE
What's about:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
//use a global Array to set the rows visible/hidden and return empty rows
if(disArray[position] == false) return new View(getContext());
... // continue with your getView() implementation
return convertView;
}
to update the ListView use
adapter.notifyDataSetChanged();
What're in the rows that aren't empty? Images can be replaced by empty, transparent pngs and text views can be set to "", etc.
View.Gone will give u empty list row. try using layout params and set to zero value like this:
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(0,0);
viewholder.programRow.setLayoutParams(layoutParams);
Layoutparams should be used as according to parent viewgroup used