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

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
}

Related

2 different layouts for the type of each row

I know that there are similar questions, but i couldn't really understand, so i decided to ask again.
I am trying to do something similar to a chat, so in the list view there would be 2 types of rows, the ones of the received items and the ones of the sent items. The ones that were received will inflate the recvRow.xml layout, and the ones that were sent will inflate the sentRow.xml layout.
I have a list of items that are suposed to be shown ( name, img, etc) and i have a boolean that represents if the object was sent or received.
The problem is that those layouts have different buttons and if for example i receive something first, it will obviously load the recvRow.xml , but then if I try to send something, it will throw a nullpointerexception because on one of the buttons that only exists in the sentRow.xml layout (and doesn't exist in the recvRow.xml).
Since i am checking that boolean that i told you guys before, i don't see the need to use the getItemViewType method.
Here is my code for the getView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
viewHolder = null;
if (convertView == null) {
viewHolder=new ViewHolder();
LayoutInflater layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
System.out.println("Transf Rec Adapter : Going to draw AN ITEM : "+ listOfItems.get(position).getAppName());
System.out.println("Transf Rec Adapter : The received bool is : "+ listOfItems.get(position).isReceived());
if(listOfItems.get(position).isReceived()){
view=layoutInflater.inflate(R.layout.highway_transf_record_recv_row,parent,false);
viewHolder.deleteFile=(ImageView) view.findViewById(R.id.transfRecRowDelete);
viewHolder.installButton = (ImageView) view.findViewById(R.id.transfRecRowInstall);
}else{//se enviado
view=layoutInflater.inflate(R.layout.highway_transf_record_sent_row,parent,false);
viewHolder.reSendButton=(ImageView) view.findViewById(R.id.transfRecReSendButton);
}
viewHolder.appImageIcon=(ImageView) view.findViewById(R.id.transfRecRowImage);
viewHolder.appNameLabel=(TextView) view.findViewById(R.id.transfRecRowText);
viewHolder.appVersionLabel = (TextView) view.findViewById(R.id.transfRecRowAppVersion);
viewHolder.senderInfo = (TextView) view.findViewById(R.id.apkOrigin);
viewHolder.rowImageLayout = (RelativeLayout) view.findViewById(R.id.transfRecRowImageLayout);
viewHolder.appInfoLayout = (RelativeLayout) view.findViewById(R.id.appInfoLayout);
}else{
view= convertView;
viewHolder = (ViewHolder) convertView.getTag();
}
if(listOfItems.get(position).isReceived()){
System.out.println("INSIDE THE GET VIEW TRANSF REC ADAPTER : RECEIVED SOMETHING");
viewHolder.senderInfo.setText("You received this app :");
myOnClickListenerToInstall = new MyOnClickListenerToInstall(position);
viewHolder.installButton.setOnClickListener(myOnClickListenerToInstall);
myOnClickListenerToDelete= new MyOnClickListenerToDelete(position);
viewHolder.deleteFile.setOnClickListener(myOnClickListenerToDelete);
}else{
System.out.println("INSIDE THE GET VIEW TRANSF REC ADAPTER : SENT SOMETHING");
viewHolder.senderInfo.setText("You sent this app :");
ReSendListener reSendListener=new ReSendListener(position);
viewHolder.reSendButton.setOnClickListener(reSendListener);//null pointer exception here
}
viewHolder.appNameLabel.setText(listOfItems.get(position).getAppName());
viewHolder.appImageIcon.setImageDrawable(listOfItems.get(position).getIcon());
viewHolder.appVersionLabel.setText(listOfItems.get(position).getVersionName());
view.setTag(viewHolder);
return view;
}
The id's are right and everything exists on the viewHolder.
You need to use getItemViewType because of recycling. Otherwise you can try to recycle a received item into a non-received view, which will screw things up royally. However it is ok for getItemViewType to just return 0 or 1 based on that boolean. It doesn't need to be very complicated for 2 view types.
You should override getItemViewType() in your adapter. This method will indicate the type of view which should be inflated for each row. You also need to override getViewTypeCount().

Android custom expandable listview expands every nth item

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.

Highlight items of a listview without using onTouch or onItemClick

I am using a default array adapter to display my listview.
How do I highlight specific rows from my listview without touching anything i.e. without using onTouch() or onItemClick() (Just by using a code!) ?
I guess the way you should do it is use custom adapter and in getVew function highlight the row you needed
e.g.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
final Holder holder;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
...
if(position==thePositionYouNeed)
row.setBackgroundColor(color)

Android, overwrite items view in ListView to display slightly different to actual value

So in my listview I have a bunch of strings, but I'd like to display the values with £ in front of the strings, but NOT actually edit the values themselves in the ArrayList.
Anyone know how I can do this?
I'm already overwriting the view anyway, I'm just not sure how to alter the display of the items values themselves.
Some Code:
adapter = (new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, listItems) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if (position % 2 != 0)
view.setBackgroundColor(Color.rgb(135,206,250)); // Pale blue
return view;
}
});
foodListView = (ListView) findViewById(R.id.foodListView);
foodListView.setAdapter(adapter);
In you getView method you can use:
TextView text = (TextView) view.findViewById(android.R.id.text1);
text.setText("£" + listItems.get(position));

Can I populate a listview from getView of a custom adapter?

I have a listview that contains items that have listviews. I am trying to populate item's listviews from inside the getView of the custom adapter that populates the "parent" listview:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
System.out.println("session adapter: here1");
if (v == null) {
LayoutInflater inflater = (LayoutInflater) act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.single_session, null);
}
SessionObject i = sessions.get(position);
if (i != null) {
tvTrackName = (TextView) v.findViewById(R.id.textViewTrackName);
tvTrackName.setText(i.trackName);
tvSessionName = (TextView) v.findViewById(R.id.textViewSessionName);
tvSessionName.setText(i.sessionName);
tvSessionModerator = (TextView) v.findViewById(R.id.textViewModeratorName);
tvSessionModerator.setText("Moderator: "+i.sessionModerator);
listAbstracts = i.abstractList;
lvAbstracts = (ListView) v.findViewById(R.id.listViewAbstracts);
AbstractObjectAdapter adapter = new AbstractObjectAdapter(act, R.id.listViewAbstracts, listAbstracts);
lvAbstracts.setAdapter(adapter);
}
return v;
}
The "interior" adapter seems to only be calling its getView function once, regardless of the number of items in its list. If there are 2 items, only the first gets put into the listview. Is this the wrong way to do this? Am I missing something?
Any help is appreciated. Thanks.
Just create your item view dynamically, adding textviews to a linearlayout. You'll just have to be careful about handling the convertView, initially it will be easiest to always ingore it but you'll take a bit of a performance hit.
Optimise later.

Categories