Android: get view from listview by position - android

i want to change color of listview (simple_list_item_2 adapter) children at specific positions programmatically. (here for example all items with a = lv.getCount();)
ListView lv = getListView();
int a = lv.getCount();
for (int i = 0; i < a; i++) {
((TextView) lv.getChildAt(i).findViewById(android.R.id.text1)).setTextColor(Color
.parseColor("#EEC900"));
}
getChildAt(); doesnt always work for me. in case of the list-item being out of sceen, getChild doesnt return a view or something..
isnt there a better solution instead if getChildAt?

You will have to do this in your Adapter class. Android caches and re-cycles the views in a listview to conserve memory. So there are are no views that you can't see to change the color of.
So for example if you had an arrayAdapter, you would override the getView function and run your check there:
#Override
public View getView(int position, View view, ViewGroup parent) {
// use "position" to determine which item you have.
// Then set the properties of "view" which is your list row.
}

Related

Android listview getting all items

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!

Change the color of a specified item in a listview for android

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()

GridView get view by position, first child view different

Android GridView is quite interesting, it reuses the child views. The ones scrolled up comes back from bottom. So there is no method from GridView to get the child view by its position. But I really need to get view by its position and do some work on it. So to do that, I created an SparseArray and put views by their position in it from getView of BaseAdapter.
SparseArray<View> ViewArray = new SparseArray<View>();
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null)
view = li.inflate(layoutID, null);
ViewArray.put(position, view);
}
Now, I can get all visible views by their position. Everything works perfect as it should but in some devices, the first child view(position 0) is not same as the one in array. I logged the getView and found that for position 0, getView got called many times and each time array was set with different view. I have no idea why GridView is calling getView for position 0 many times and that happens only on few devices. Any solution ?
After reading source of getPositionForView, I have wrote this method in own GridView, works perfect by API 18
public View GetViewByPosition(int position) {
int firstPosition = this.getFirstVisiblePosition();
int lastPosition = this.getLastVisiblePosition();
if ((position < firstPosition) || (position > lastPosition))
return null;
return this.getChildAt(position - firstPosition);
}
You can't reach the views directly because of the recycling. The view at position 0 may be re-used for the position 10, so you can't be sure of the data present in a specific view.
The way to go is to use the underlying data. If you need to modify data at position 10, then do it in the List or array under your adapter and call notifyDataSetChanged() on the adapter.
if you need to have different views for different data subtypes, you can override the two following method in your adapter: getItemViewType() and getViewTypeCount()
Then, in getView() you can 1) decide which layout to inflate 2) know the type of view recycled using getItemViewType()
You can find an example here:
https://stackoverflow.com/a/5301093/990616
There was an issue reported for this. Here is the link. This issue has been closed as WorkingAsIntended. Wish means we can expect the GridView to call getView() on pos 0 multiple times.
My work around is as follow:
public class GridAdapter extends BaseAdapter {
...
int previouslyDisplayedPosition = -1;
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(previouslyDisplayedPosition != position) {
....
previouslyDisplayedPosition = position;
}
return convertedView;
}
What I am trying to do here is returning the same 'convertView' if same pos is called again and again. There by preventing any logic within getView() (eg setting image view etc)to be executed again and again.

Set RequestFocus on first EditText in a dynamic ListView

At the moment im looping through a dynamic arraylist and building a Listview with Switches and Edittexts from its data.
for (int i = 0; i < response.size(); ++i) {
...
xxx.SetId(i)
...
}
this was my working solution if a Edittext was on the first position:
if (i == 0 ) {
editText.requestFocus();
getWindow().setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
But how to set the focus on the first available Edittext? for example third position after two switches?
(the position changes dynamically based on the arraylist)
Generally you should populate and set any required state inside the Adapter that is attached to the ListView. A simple solution would be something in the lines of:
public class MyAdapter extends Adapter {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = layoutInflator.inflate(R.layout.somelayout, parent, false);
// position is zero-based so 3rd item is at position 2
if (position == 2) {
view.findViewById(R.id.edittext).requestFocus();
}
return view;
}
}
And to scroll the listview to the 3rd item you could call listView.setSelection(2).

Row color based on contents in the ListView of my RSS reader

I am very much an Android newbie and I have built a simple RSS reader application based around the free IBM android RSS tutorial. I would like to change the background color of each row if the category of that row is equal to a particular String.
I wrote the following "for loop" which discovers the category of each item and runs an if statement should that category be equal to "News". At the moment the background colour of the entire listview gets changed as soon as a feed is supplied with a News category.
Does anyone out there feel like helping out a beginner?
for(int i = 0; i < feed.getItemCount(); i++)
{
if (feed.getItem(i).getCategory().equals("News"))
{
ListView.setBackgroundColor(0x77ee0044);
}
}
You're going to need to do this inside the getView() method of your adapter.
Before you return the view in getView(), you can call setBackgroundColor() on the view or use one of the other setBackgroundFoo() methods.
Edit - given your code, when you create your Adapter, try:
ArrayAdapter<RSSItem> adapter = new ArrayAdapter<RSSItem>(
this,android.R.layout.simple_list_item_1,feed.getAllItems(­)) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if (getItem(position).getCategory().equals("News")) {
view.setBackgroundColor(0xffff0000); // red
}
return view;
}
};
This overrides getView() to adjust the background of your list item views properly.

Categories

Resources