I have used this tutorial in order to create a custom listview, but for some reason it is behaving differently than what I expect.
Here is the code I changed and am currently using for the adapter:
public View getView(int position, View convertView, ViewGroup parent) {
// same code as in example with some differences in the .xml
viewHolder.itemLabel.setText(info.split(";")[0]);
viewHolder.itemDescription.setText(info.split(";")[1]);
viewHolder.itemLabel.setOnClickListener(this);
viewHolder.itemLabel.setTag(position);
if(viewHolder.itemLabel.getText().equals("Fat")){
System.out.println(info);
System.out.println(viewHolder.itemLabel.getText());
viewHolder.itemLabel.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.info_icon, 0);
}
return convertView;
}
Now, what is happening is that for some reason the icon is being set for more than one item on the list even though there is only one with "Fat" on the label.
The print is actually showing that the code on the if is being run three times.
I think that this must have something to do with the lifecycle of the app, but i'm not sure about it.
I'm sorry if the question is to vague, but I couldn't find a better way to ask this.
You need to add the else part inside getView().
public View getView(int position, View convertView, ViewGroup parent) {
// same code as in example with some differences in the .xml
if(viewHolder.itemLabel.getText().equals("Fat")){
// Stuff
}else{
// Else stuff
}
return convertView;
}
ConvertView parameter is a recycled instance of View that you previously returned from getView(). You can read about it just search for it .
Making some quick points . You are not using viewholder pattern correctly in code. Use it properly look for ViewHolder pattern in List view. Apart from that you should Move to RecyclerView ListView is in legacy now.
Please check code It may be helpful.
public View getView(int position, View convertView, ViewGroup parent) {
// same code as in example with some differences in the .xml
viewHolder.itemLabel.setText(info.split(";")[0]);
viewHolder.itemDescription.setText(info.split(";")[1]);
viewHolder.itemLabel.setOnClickListener(this);
viewHolder.itemLabel.setTag(position);
if(viewHolder.itemLabel.getText().equals("Fat")){
System.out.println(info);
System.out.println(viewHolder.itemLabel.getText());
viewHolder.itemLabel.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.info_icon, 0);
}else{
viewHolder.itemLabel.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
return convertView;
}
Related
I read many other posts, but most, if not all of them tell you to override one of the methods and put change the background then. I want to change it outside of the ListView Adapter class, so I tried doing this. It doesn't seem to work. I do however get the object, nut it wont change its background.
RelativeLayout item;
item = (RelativeLayout) listView.getAdapter().getView(0, null, listView);
item.setBackgroundColor(Color.YELLOW);
Thank you.
Find the nearest time save it in a variable and call adapter.notifyDataSetChanged()
public View getView(int position, View convertView, ViewGroup parent){
if(time is nerest time) {
convertView. setBackgroundColor(Color. YELLOW)
} else {
convertView. setBackgroundColor("default color")
}
}
I have customised list view using BaseAdapter, I want to give separate color for the row position%5 ==0. but it also change the color some other rows which not satisfy the condition. Following is my getView().
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view=convertView;
if(convertView==null){
view=inflater.inflate(R.layout.groupl_ist, null);
}
TextView countryName=(TextView) view.findViewById(R.id.tvCountryText);
ImageView countryImage=(ImageView) view.findViewById(R.id.imgCountry);
String label=countryNames.get(position);
countryName.setText(label);
if(position%5==0){
countryImage.setVisibility(LinearLayout.GONE);
view.setBackgroundColor(Color.GREEN);
}else{
countryImage.setImageResource(R.drawable.ic_launcher);
}
return view;
}
It looks like you're having an issue with recycling. You need to implement the ViewHolder pattern. See this link for details on how to implement.
Ultimately what you'll be doing is holding onto the view as you scroll up and down so that it redraws correctly.
I am not pretty sure why is happened your problem but try to set to the original color to the rows that don't satisfy the condition. Also, you should implement the ViewHolder pattern. There are a lots post about this pattern.
if(position%5==0){
view.setBackgroundColor(Color.GREEN);
}else{
view.setBackgroundColor(Color.WHITE); //whatever color
}
I have a row in a listview that I need to change its layout dynamically. In my array adapter I have the following (simplified) code
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = inflater.inflate(R.layout.default);
}
...
if(condition) {
View view = inflater.inflate(R.layout.new);
...
return view; // doesn't work
}
return convertView;
}
My actual listview is actually pretty complex and I am also using the getViewType for the two different layouts. But the above code should be enough to make my point that the new layout won't display correctly when I want to switch layout dynamically.
My question is, how can I refresh the convertView, or trigger a reload of the adapter/listview to the point that the convertViews will be cleared? I've tried calling notifyDataSetChanged, or calling the listview invalidateViews() but they all didn't worked. My last resort seems to restart the whole activity but I don't think this is an elegant solution.
I would like to have a listView that the first list item will have a red background and the second will have black.Is that possible?And if yes,how will i create the custom list adapter?
thanks!!
|Black item|
|Red item|
|Black item|
|Red item|
|Black item|
etc.
You should Override getView in your arrayadapter. One of the parameters passed into this method is a position. So you can just do the position % 2 to determine if the row is even or odd. Depending on what you want to do you can change you can inflate two totally different layouts there.
When you have the public View getView(int position, View convertView, ViewGroup parent) method make it apply different style for each position %2 == 0. This way you can easily make those items differ from each other :)
I hope this helped.
here's the getView from my latest project's adapter. I've simplified it to highlight a couple of things: 1. that you can use whatever criteria you like to decide what kind of view will be returned, and 2. that you can use LayoutInflater.inflate to get any kind of view at all, whatever the case may be.
public View getView(final int position, View convertView, ViewGroup parent)
{
View v;
int n = itemList.get(position);
if (n < 0)
{
v = inflator.inflate(R.layout.layout1, null);
}
else if (n > 0)
{
v = inflator.inflate(R.layout.layout2, null);
}
else
v = inflator.inflate(R.layout.layout3, null);
return v;
}
I have several spinners that I have created a custom ArrayAdapter for so I can change the drop down menu look. I want to manipulate the view depending on what spinner the dropdown belongs to. I thought I would be able to do something like parent.getTag() but it is returning null.
The custom array adapter looks like:
class BackgroundColorAdapter extends ArrayAdapter<String> {
BackgroundColorAdapter() {
super(SettingsActivity.this, R.layout.settings_spinner_item, R.id.item_text, textColors);
}
public View getDropDownView (int position, View convertView, ViewGroup parent){
View row=super.getView(position, convertView, parent);
if(parent.getTag().equals("background"){
//Do custom stuff here
}
return(row);
}
}
and I'm setting the tag:
settingsSpinner.setTag("bg_color_spinner");
settingsSpinner.setAdapter(new BackgroundColorAdapter());
I think I'm confused how the view hierarchy works but it seems logical that the parent of the spinner drop down would be the spinner. Anyone know how I can find out what spinner the drop down belongs to in getDropDownView?
edit: made the settingsSpinner a single spinner instead of an array of spinners to make it less confusing
Eventually got this to work, here is the code for example that changes the text font for each item in the drop down.
class TextSizeAdapter extends ArrayAdapter<String> {
TextSizeAdapter() {
super(SettingsActivity.this, R.layout.settings_spinner_item, R.id.item_text, textSizes);
}
public View getDropDownView (int position, View convertView, ViewGroup parent){
View row=super.getView(position, convertView, parent);
TextView text = (TextView)row.findViewById(R.id.item_text);
text.setTextSize(TypedValue.COMPLEX_UNIT_PX,appState.FONTSIZES[position]);
RadioButton radio = (RadioButton)row.findViewById(R.id.item_radio);
if(settingsSpinners[2].getSelectedItemPosition() == position){
radio.setChecked(true);
}else{
radio.setChecked(false);
}
return(row);
}
}
I'm unfamiliar with getDropDownView(), and don't know why you use it. Documentation for getDropDownView() states the following about the parent:
parent the parent that this view will eventually be attached to
This doesn't sound like the 'parent' you are looking for...
Since the 'parent' in the getView() call is indeed a Spinner, you could use that to store an instance variable of the parent like below:
public Spinner mParent = null;
public View getView (int position, View convertView, ViewGroup parent)
{
this.mParent = parent;
return super.getView(position, convertView, parent);
}
public View getDropDownView(int position, View convertView, ViewGroup parent)
{ // Your code here -> but use 'mParent'
}
I haven't tried, but maybe it's a workaround to get what you need. Please let me know if you found the solution.