I am trying to create an item in a ListView that has multiple options; view and edit. I would like to create it in exactly the same way as android's contact system - see below:
I have added the red boxes to illustrate the behaviour I want. If you press within the left red-box, you call the contact. If you press within the right red-box, you send a text message to the contact. I have already created a similar layout in XML, but I am having trouble implementing this functionality in code.
I have tried to create custom android:onClick function calls for the separate layouts within the item, but calling an onClick method only allows you to pass in the View as a parameter, but not the position. Needing the position to use listview.getItemAtPosition function, I tried to use listview.getPositionForView to return the position but found this was extremely unstable and was very easy to return incorrect positioning due to recycling of views.
What is the best way of implementing a list populated by items with multiple buttons/layouts on each item?
One way to accomplish this while still using a single android:onClick function would be to utilize the setTag() method for each of the clickable views to store an Integer that is the position for the item. For example in your adapter's getView():
#Override
public View getView(int position, View convertView, ViewGroup arg2) {
...
ImageView textMessageView = (ImageView)convertView.findViewById(R.id.whatever);
textMessageView.setTag(new Integer(position));
...
}
Then in your onClick() method you could do something like the following:
#Override
public void onClick(View clickedView) {
int position = clickedView.getTag() instanceof Integer ? ((Integer)clickedView.getTag()).intValue() : -1;
...
}
Don't know that it's ideal, but it allows you to use the XML android:onClick facility and doesn't involve creating separate onClick listeners for each list view item.
I also worked on a similar kind of project.
For doing it, i created my own layout having two linear layouts as linearLayoutLeft and linearLayoutRight.
I then added this layout to a listView.
And then i mentioned the onClickListener of the Listview, i used to getThe view being clicked at the position in the listView.
So for each row in listView, i had two linearLayouts and they have their own onClickListeners.
Related
The View Object is from onListItemClick(ListView listView, View view, int position, long id) is RelativeLayout.
However, I want to know which component inside the RelativeLayout is clicked as well for extended functionality.
How do I do that?
This answer show why use recyclerview instead of Listview, I think recyclerview will solve your problem stackoverflow.com/a/24933117/2242903
You have to add a listener to every view in RelativeLayout you want to listen. If you want to use a single listener, create one and add it to all of the views you want to listen. In your onClick method, you can put view.getId() to switch statement and determine which one is clicked.
OnItemClickListener won't solve your problem. Neither switching to RecyclerView. They work the same way. It is all about your adapter. If you are using a custom adapter, it doesn't matter you use ListView or RecyclerView. In your adapter, you have access to your components that are in your RelativeLayout. Create a listener as I explained above and add them to your views.
Not the same but similar question: Android: Add event listeners to every item in a ListView
I've got an AutoCompleteTextView in my app and I've been tasked with forcing the vertical scroll bar to always show if the results retrieved by said textview are numerous enough to be scrolled (i.e. there are more results than can fit at once in the autocreated listview).
I've tried adding the following xml attributes to the AutoCompleteTextView itself to no avail:
fadeScrollbars="false"
scrollbarFadeDuration="0"
scrollbarAlwaysDrawVertical="true"
I'm thinking if I could somehow obtain a reference to the listview created automatically for the AutoCompleteTextView and applying one or more of the above attributes to it that I could force the scrollbar to always show but I have no idea how to get a reference to that listview.
Thanks
UPDATE
In the Adapter I created for this AutoCompleteTextView, in the Overridden getView() method, I have a reference to the parent view. I can set those attributes above programatically on the parent and I get the desired functionality, the downside is that those attributes are set each time getView is called which isn't the most efficient?
I have tried styles but they don't work properly, so your coded way seems like the only possibility.
But the group is given on every time, so you could just add a boolean for this:
public View getView(int position, View convertView, ViewGroup parent) {
//Change the list attr programmatically becuase sometimes Android sucks :/
if (!_changedListAttr) {
_changedListAttr = true;
ListView list = (ListView) parent;
list.setBackgroundResource(R.color.color_white);
list.setVerticalScrollBarEnabled(false);
list.setDividerHeight(0);
}
I am trying to determine the best way to have a single Listview containing different rows styles.
I searched alot and found some tricks using getViewTypeCount() and getItemViewType(int position), to let the listview layout changes depending on position and that was not what I'm looking for.
What I'm trying to do is to change the listview layout depeding on a textview value on the row itself.
I don't understand why you cant achieve this with the methods listed above, if you know how many views you have, then create an .xml for each one of them and then in the getView() inflate the corresponding layout depending on the value of your textview. You then return this row and it should then work.
well, this is exactly what you need to do.
override the getViewTypeCout to return the amount of types you have.override the getItemViewType and determine the type according to the position (or item to show)
after you do that, just use this in your getView like this:
public View getView(int position, View convertView, ViewGroup parent) {
if(getItemViewType(position) == FIRST_VIEW_TYPE) {
// inflate first view
} else {
// inflate seconde view
}
}
I searched alot and found some tricks using getViewTypeCount() and getItemViewType(int position), to let the listview layout changes depending on position and that was not what I'm looking for.
Yes, it is.
What I'm trying to do is to change the listview layout depeding on a textview value on the row itself.
No, you are not. You are trying to "change the listview layout depeding [sic] on" some text that you plan on putting into "a textview value on the row itself". As mr_archano points out, this TextView is not magically getting a value -- it is getting a value based on something you put there by one means or another.
Hence:
Override getViewTypeCount() to return the number of distinct possible row types
Override getItemViewType() to return a value from 0 to getViewTypeCount()-1 based upon the text that you plan on pouring into the TextView
Ensure that your getView() or bindView() implementation is aware of the different view types and handles them accordingly
The contents of the TextView inside the ListView Row must come from some data you have defined (probably an ArrayList or similar I'm assuming), so what you have to do is check what kind of view you want to draw based on that data before drawing the ROW, this is done on the getView() method.
getView() is called when the ListView wants to render a given element, you're thinking it doesn't have to do with position but it does. You know the TextView contents before drawing them, so parse that value and use the type of layout you want in getView dynamically ;).
Read this if it is still not clear: Android custom listview row
I have a listview with two columns where the user can compare the productName and proudctQty against the stock. There are loads of products in that list and the user may get confuse checking all of them. So, the idea is to highlight the products and their price by using focus.
Does anyone know if would be possible to implement it in listview like on the virtual keyboard (it isnot onLongTouch or click)?
Could anyone give a hint about how to do it?
Many thanks
ok like in case of wheelpicker iPhone we can highlight the product just follow these steps
implement the list's onscrollchangedlistener .
put the list in a relative layout with another view at the centerinparent and fillparent
on this view you will display the highlighted item.
as the list is scrolled update the content over that view inside the overrided onscroll method.
You need to use a View Holder Pattern. You can find more information on Google.
Simply create a class called AdapterViewHolder, declare properties, the Views on each row.
For example:
public class AdapterViewHolder
{
ImageView myImageView;
TextView myTextView;
...
}
In constructor pass your values to set to the views, initialize your views and set your values like:
public AdapterViewHolder(String param, Drawable imageDrawable){
// set values to views
}
In the adapter in getView method:
if convertView == null
//then create your layout and holder class, set your holder to your layout by view.setTag method, prepare your view and return it
else
//get your layout tag by view.getTag(), cast it to AdapterViewHolder and update your views and values of them as you like and then return updated view.
For more info search for ViewHolder Pattern in android listviews.
Basically, I want to be able to use two ListViews through my BaseAdapter class in the same activity. The ListViews will be displayed side-by-side and each item within the ListView will contain multiple views (ImageView, TextView, etc.).
My main issue is retreiving/displaying data through the getView() method inherited from BaseAdapter. How would I go about detecting which ListView is being updated through this method so I will know which code to call/update? I've tried looking at the ViewGroup parameter in getView() hoping that it led me to the parent of the ListItem but the id it returns was different from my ListView's resource ID...in fact it wasn't even in my R.java file at all:
12-14 04:44:58.613: ERROR/ParentFromGetView(312): 16908298
12-14 04:44:58.623: ERROR/MyListViewId(312): 2131165191
I was hoping to do something like so:
public View getView(int position, View convertView, ViewGroup parent) {
if (parent.getId() == R.id.ListView1) {
//Do stuff
} else if (parent.getId() == R.id.ListView2) {
//Do different stuff
}
}
...but the Ids are drastically off as seen above.
Thanks in advance!
You cannot share a ListAdapter between two ListViews.
Well, I would like for them both to run on the same activity.
So?
Currently I'm extending my activity as a ListActivity and I set my adapter accordingly.
That only affects one of the two ListViews, whichever one has the #android:id/list value. You need to create a second ListAdapter for use with the second ListView. You get the second ListView by calling findViewById(), and you associate the adapter with that ListView via setAdapter().