Android custom expandable listview expands every nth item - java

I have custom listview and array adapter with ViewHolder. When click listview item, it expands new layout below. Problem is: unfortunately it is opened for every +9th item in listview.. For example: if item 0 is clicked; 0,9,18th elements opens their expand layouts. Any idea without looking code ?

I have no idea, but this sounds familair with an issue I had. I had a listview with TextView objects and multiple were selected and got typed in the same value.
I had a very, very dirty fix for that, in my custom adapter I'd always make a new View, no matter what:
#Override
public View getView (final int position, View convertView, final ViewGroup parent) {
//if (convertView == null) {
// Inflate the view from the converter
final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
convertView = layoutInflater.inflate(converter.getLayout(), parent, false);
//}
// Populate the view from the converter
converter.populateInflatedView(convertView, getItem(position));
return convertView;
}
Source can be found here if you want to know what the converter is about.
On a side note, I have created a sort of interface type of thing for a TreeView, however this is in Activity form which uses a ScrollView. So this is not really a ListView type of deal, but might help you. The Tree part can be found on the Tree-link, with an implementation in the subject package.

Related

How to add checkbox on all the listView items after having a long item click? Android Java

I want to add a feature on my project where if the user clicks one of the items on the listView then a checkbox would appear allowing the user to delete 1 or many items at once. Similar to Samsung Notes when you want to delete notes and or folders, etc. However, this concept is completely foreign to me and currently, I don't know where to begin to start this or what topic/resource/sample code I should look for. Also, I have a custom Array Adapter class that I used to order to work with my ListView but it came to my knowledge that you only need 1 array adapter class to make this work which made me confused since I don't know where to begin to manipulate it even further. Any help would be amazing!
Here is my Array Adapter that I have at the moment
//want to create our own custom ArrayAdapter. Going to extends the base class ArrayAdapter and hold our
//Word object
public class WordAdapter extends ArrayAdapter<WordFolder> {
//constructor - it takes the context and the list of words
WordAdapter(Context context, ArrayList<WordFolder> word){
super(context, 0, word);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View listItemView = convertView;
if(listItemView == null){
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.folder_view, parent, false);
}
//Getting the current word
WordFolder currentWord = getItem(position);
//making the 3 text view to match our word_folder.xml
TextView date_created = (TextView) listItemView.findViewById(R.id.date_created);
TextView title = (TextView) listItemView.findViewById(R.id.title);
TextView desc = (TextView) listItemView.findViewById(R.id.desc);
//using the setText to get the text and set it in the textView
date_created.setText(currentWord.getDateCreated());
title.setText(currentWord.getTitle());
desc.setText(currentWord.getTitleDesc());
return listItemView;
}
}```
In R.layout.folder_view add one and make it invisible or gone. OnLongClick make them Visible.

How to add sections/headers in a dropdown for Android?

Basically, I'm using an AutoCompleteTextView and it uses an ArrayAdapter of Objects.
When searching for Objects, I want to have separators or headers of some sort to categorize the objects that will be shown in the dropdown.
I've tried googling for examples to no avail. At the very least, I just need a top level guidance on how to do this. Some code examples would be nice.
So far, I have a custom xml layout for the Object rows in the dropdown. But not sure on how to add the headers/sections.
Couldnt you add a custom view to your adapter that is placed in the first position ?
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate( R.layout.list_row_layout, parent, false);
if (position == 0) {
//insert custom header layout into adapter
}else { //load the rest of your items
}

Android - How to get reference to view in a custom layout?

I have a ListView that gets its layout for each item from "rowlayout".
I want to do something to one of the buttons in the rowlayout in my main activity, how do i get a reference to it findviewbyid doesn't work.
I guess i'm essentially not understanding a general concept of how to get a reference to a view in a custom layout- unless getting a view from a ListView is different. Can anyone help? thanks.
ListView is a ViewGroup so you can just iterate over its children:
int n = getChildCount();
for (int i = 0; i < n; i++) {
doSomethingToView(getChildAt(i));
}
However, you must be careful. ListView is pretty special and only has a subset of children that you might expect. It only holds (roughly) references to children that are currently visible and reuses them as they disappear.
What you might consider is changing underlying adapter instead and than notifying the ListView that its adapter changed, so it needs to redraw children. Or alternatively, you can make the child of ListView directly listen for events that are supposed to change it and then adjust itself.
If you are inflating a custom layout in the getView method of your adapter, you can get a view like this
LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.your_custom_layout, parent, false);
TextView tv = (TextView) rowView.findViewById(R.id.your_tv_id);
You can use partial refresh principle if you implement ListView in the way of ViewHolder, just like this:
private void refreshPartially(int position){
int firstVisiblePosition = listview.getFirstVisiblePosition();
int lastVisiblePosition = listview.getLastVisiblePosition();
if(position>=firstVisiblePosition && position<=lastVisiblePosition){
View view = listview.getChildAt(position - firstVisiblePosition);
if(view.getTag() instanceof ViewHolder){
ViewHolder vh = (ViewHolder)view.getTag();
//holder.play.setBackgroundResource(resId);//Do something here.
...
}
}
}
Possibly you can use the answer from this android - listview get item view by position to get the child view at a position then call findViewById() on that child view.

ListView is empty/disapears after Orientation Change even if Adapter contains Items

I got a ListView with a custom Adapter.
In the Adapter a layout is inflated from xml.
All works fine, and I can see the items, until the Screen Orientation is changed.
I know that the Activity is recreated (or resumed) then, and the ListView is recreated too, as well as the Adapter.
But there are no items in the ListView now. The Adapter isn't empty, I use toasts to display the count of items in the Adapter.
I guess there is an inflating problem, because if I use the same Adapter (or an adapter with the same data) to a new ListView nothing is shown as well.
But the most crazy thing I don't understand is, that if I let my getView() method return a simple TextView, all works fine, even after orientation change.
I tried several things, like don't recycle a View so that it is inflated every time, or save the View to the matching Item (from getItem(position) from the Adapter).
I'm grateful for all hints :)
EDIT: so I was asked for some code.
Here is the getView() of my Adaptar
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
View view = convertView;
final Event event = getItem(position);
if (view == null) {
view = inflater.inflate(R.layout.new_event_item_layout, parent,
false);
view.setTag(R.id.eventDate, view.findViewById(R.id.eventDate));
view.setTag(R.id.eventTime, view.findViewById(R.id.eventTime));
view.setTag(R.id.eventName, view.findViewById(R.id.eventName));
view.setTag(R.id.eventBemerkungen,
view.findViewById(R.id.eventBemerkungen));
view.setTag(R.id.eventIcon, view.findViewById(R.id.eventIcon));
}
((TextView) view.getTag(R.id.eventDate)).setText(event.getDate());
((TextView) view.getTag(R.id.eventTime)).setText(event.getName());
((TextView) view.getTag(R.id.eventName)).setText(event.getTime());
((TextView) view.getTag(R.id.eventBemerkungen)).setText(event
.getDescription());
SquaredImageView icon = (SquaredImageView) view.getTag(R.id.eventIcon);
Picasso.with(context).load(event.getUri())
.placeholder(R.drawable.ic_reload).into(icon);
view.setBackgroundColor(event.getBackgroundColor());
view.setVisibility(View.VISIBLE);
return view;
//return getDummyTextView();
}
public TextView getDummyTextView()
{
TextView tv=new TextView(context);
tv.setText("YOLO BIATCHSES");
tv.setTextColor(Color.WHITE);
return tv;
}
I have had the same exact problem although it wasn't because of orientation change and I found the solution by just setting listView.setAdapter(adapter) again after the recreation of the activity or whatever case you have. I suspect the listview is basically losing the pointer to the adapter.

Set id and get id of inflated view?

I have to inflate the group of items in a listview and i need to find inflated view anywhere in the program .
May I know how to find the view.
How to set id and get id of inflated listview.
Thanks in Advance
In the Adapter of your list view
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.newlistrow, null);
//Access your inflated layout using vi
TextView sometextview= (TextView) vi.findViewById(R.id.textview); // sometextview
Typically you don't find views in a list view. The adapter behind the list view will pass you the view plus the underlying position of your data that you need to render via the getView method.
To answer your question of how to get or set id of inflated view you should call getId or setId on the inflated view.
http://developer.android.com/reference/android/view/View.html#setId(int)
http://developer.android.com/reference/android/view/View.html#getId()
View myView = LayoutInflater.from(activity).inflate(R.layout.list_item_punch_log, null);
myView.setId(android.R.id.button1);
int id = myView.getId();
However doing this and finding views in a list view is a very dangerous act as it will cause some really funny behaviors on the listview. Maybe you can tell us what you are trying to do and we can guide you from there.

Categories