get first item only in a Android ListView? - android

How do you get the first list item in a listView? I want to get at a TextView in the first list item.
I am currently doing this:
View listItem=(View)myList.getChildAt(0);
TextView txtDep=(TextView)listItem.findViewById(R.id.txtDepart);
txtDep.setText("Hello!");
But this is not only changing the text in the first item but in every 8th, 16th and so on items. I would like to change the text in the first(top) item only.
Thank you.

Views are recycled so your TextView will be used for many different items in the list. If you want to change what a specific item displays then you need to change the data that is behind your ListItem and is being served up by the ListAdapter (in the getView() method). So whenever the ListView shows the item in the list, the adapter will show the correct data in the TextView.
And when you change data in your list or whatever, you will need to call notifyDataSetChanged() on your adapter.

If you want to get the specific item in the list and want to change its color you can get this through getView method in your Adapter class.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater)context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.crewlist_row, null);
}
TextView firstname = (TextView)convertView.findViewById(R.id.firstname);
firstname.setText(userArray.get(position).getFirstName());
return convertView;
}

Shouldn't you use getItem(0) ?
http://developer.android.com/reference/android/widget/Adapter.html#getItem%28int%29

What you want to do is change the data in the ListAdapter and then call the notifyDataSetChanged() method to get the list to re-render. See the discussion here, includes some sample code:
ListView adapter data change without ListView being notified

Same symptom but different cause for me. I changed my fragment layout to a controlled height instead of match_parent and that solves my issue.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
to
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >

Related

Dynamically adding subitems to ListView in Android

I am trying to dynamically add information to a ListView. The information I am adding consists of a "Device Name" (the main item) and "MAC Address" (the sub item). An example from online is below. Note: I want to replace Item 1 with a device 1's name, sub item 1 with device 1's MAC address, and so on. This MUST be done dynamically because the list is being populated as devices are scanned for.
.
Before this is marked as a repeat, I have looked at the following questions and they have not helped me: Adding ListView Sub Item Text in Android, How to add subitems in a ListView, Adding Items and Subitems to a ListView
The conclusion I have come to through reading these questions is that I need to implement a custom ArrayAdapter and override the getView() method. I have created a custom layout with two text views in it:
cyan_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/main_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/cyan"/>
<TextView
android:id="#+id/sub_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/dark_cyan"/>
</LinearLayout>
I then try to create a custom ArrayAdapter in my Activity class, but I am lost as to what to put in my public View getView(final int position, View convertView, ViewGroup parent) method. Additionally, is creating a custom ArrayAdapter necessary if all I am trying to do is add a textview sub item?
The answer to your question is: NO, you don't need to create a custom ArrayAdapter if you just want to add items. I recommend, however, creating it if your layout is customized, as you'll gain so much control over the items you're displaying. You didn't add your code where you create your ArrayAdapter, but in your case I'd use this constructor. The important part is the third parameter: In your activity, you should store an ArrayList with the initial items you're adding to your ArrayAdapter, then, if you want to add a new item, you simply add it to the ArrayAdapter and call notifyDataSetChanged() on your adapter. Simply doing that, your item will be added to the layout and displayed. If you need to override the GetView method for your own ArrayAdapter, I recommend this link, it helped me understanding the whole thing.
are you searching some listview example in google like those tutorials :
http://www.vogella.com/tutorials/AndroidListView/article.html
http://www.mkyong.com/android/android-listview-example/
I think they explain step by step how to create a list adapter
You need to add getter method into your Adapter
YourAdapter ...{
List<Device> items = new ArrayList<Device>;
public List<Device> getItems(){
return items;
}
}
then change item that you need
...{
//for 1s item
Device item = getItems().get(0);
item.setTitle(macAdress)
}
and call notifyDataSetChanged for your adapter
...
yourListView.getAdapter().notifyDataSetChanged();
}
Thats it. Now you are able to change your list data.
And for your question, i think yes. Is better to create your own adapter in order to have simple possibility to exentd it later. And in your case (if you dont want to change your adapter after each title change) you deffinetly need custom one. Cheers

can't set view background

I want to make an application that show lyric of sound with music,
I put lyrics in a custom made listview with layout below ( layout for row's ), and time of that lyric in text separated with comma,
then, I want to scroll with media.
This is my custom layout for rows:
<TextView
android:id="#+id/custom_text_arabic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center"
android:lineSpacingExtra="15dp"
android:textSize="20sp" />
<TextView
android:id="#+id/custom_text_persian"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:lineSpacingExtra="10dp"
android:textColor="#999999"
android:textSize="12sp" />
</LinearLayout>
and I have an adapter for this custom row layout in list view,
I have a music file that plays with MediaPlayer and I get current position of sound and check that in an array of time to find the position of row in list view, then I scroll to that row in a listview, along side this things, I want that row background change to black!
So, I get that row with this code and change it!
// cAdapter is the name of my BaseAdapter and whereIsMe is current child of listview
// that i want to manipulate it
View mVi = cAdapter.getView(whereIsMe-1, null, lv);
TextView persian = (TextView) mVi.findViewById(R.id.custom_text_persian);
// this toast works great!
Toast.makeText(getApplicationContext(),persian.getText(), Toast.LENGTH_LONG).show();
// this part of code is not working!
persian.setBackgroundColor( Color.BLACK );
the problem is:
I can Toast Text in a TextView perfectly! But I can't change that TextView Background or any other manipulation! why and how can I fix that?
Calling getView doesn't return the actual child of the ListView. There are two options, you can call getChild for the ListViewand update the background color or call notifyDataSetChanged and set the background color in your adapter getView method.
The getView method of the adapter is not meant to be used as you are using it.
Read some tutorials on creating a custom adapter for a listView. Then you can do whatever you want.
Here is a good read on custom adapters;
http://www.vogella.com/tutorials/AndroidListView/article.html
For getting the view you want from outside the adapter use something like this:
View view;
int nFirstPos = lv_data.getFirstVisiblePosition();
int nWantedPos = invalidaEste - nFirstPos;
if ((nWantedPos >= 0) && (nWantedPos <= lv_data.getChildCount())
{
view = lv_data.getChildAt(nWantedPos);
if (view == null)
return;
// else we have the view we want
}
Sometimes listView.getChildAt(int index) returns NULL (Android)
This happens because getView is called internally to create a view. by what you are doing you are actually creating a new view which is not added to any screen/layout so any changes you do wont be reflected on the UI

ListView onItemLongClickListener is not working properly

I am working on a ListView and I have used setBackgroundColor inside onItemLongClickListener on the selected item. My problem is that when I am doing this and scrolling, it is setting color of some invisible child of ListView too. How can it be solved.
Try putting the following attributes in your xml:
`
<ListView
android:dividerHeight="1dp"
android:scrollingCache="false" >
`
this is caused since a listview uses old views in order to avoid re-creation of views when you scroll.
in fact , this is common to all of the adapterView classes .
in order to handle this , store the status of the position of the view (using an arrayList or whatever collection you wish) and on the getView , if the position is set in the list to be of this background , use this background , otherwise use the default background.
for more information about listview , either read the API , or (and i highly recommend it) watch the video "the world of listView" .
In your adapter class:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = inflater.inflate(...);
}
convertView.setBackgroundColor(defaultcolor);
...
}
This however will overwrite the background you set in the onlongclicklistener when that view would be redrawn. So you might want to keep a list of the positions of the clicked items so you can set these in the getView method.

find a Textview in ListActivity in android

I'm usind ListActivity to show stock market information. Each row has my own layout with 4 textviews. I need to update the information of each stock as they change.
My problem is I could extract a specific view from list, however I don't know how to find a textview within this view.The code below might clarify my problem.
This is what I've done which didn't work:
ListView list = (ListView) findViewById(R.id.list);
View r = list.getChildAt(2);
TextView t = (TextView) r.findViewById(R.id.t_buy);
t.setText("3200$");
t_buy is one of the textviews in my layout.
I was hopping that android has something like below, but it hasn't.
TextView t = (TextView) r.getChildAt(R.id.t_buy);
This is the screen shot of my app.
Create you custom adapter from BaseAdapter and override method:
#Override
public View getView(int position, View convertView,
ViewGroup parent)
{
//...
TextView textView;
textView = (TextView)view.findViewById(R.id.itemText);
textView.setText("some text");
}
see mode details here: http://codinglines.frankiv.me/post/14552677846/android-implementing-a-dynamically-loading-adapter
You could try using getAdaper() on the list object and then use getItem() to retrieve the one you need.
You can update the items in adapter, and then invoke adapter.notifyDataSetChanged
I think it is best if you can use the View getView method because you are using a ListView and when you click on a List item you want to populate one of your custom layout with four TextViews as you have mentioned. This links show you how to do it clearly.

How to highlight ListView item on touch?

I have a simple ListView and I want each of it items to be highlighted on user's touch. I thought this should happen by default but it isn't. Can you advice?
ListView xml:
<ListView
android:id="#+id/list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:divider="#206600"
android:dividerHeight="2dp"
android:smoothScrollbar="true"
android:background="#ffffff"
>
</ListView>
And code of my Adapter:
private class MyAdapter extends ArrayAdapter<Task> {
private LayoutInflater mInflater;
public MyAdapter(Context context, int resource, List<Task> list) {
super(context, resource, list);
mInflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
v = mInflater.inflate(R.layout.list_item, null);
}
Task task = taskList.get(position);
/* Setup views from your layout using data in Object here */
return v;
}
You may want to post your actual row layout code, but I suspect the problem will be that you set a background color on your list row. By default, the selectors are drawn behind the list items (which looks nicer, since the highlight color is behind the text). Either don't set a background color on your list items, or set it to draw the selector on top instead with ListView's drawSelectorOnTop XML attribute.
EDIT: If you really must have an opaque background for the default state and don't want to use drawSelectorOnTop, you can also try this: Set a background on your list rows, but use a StateListDrawable to use #android:drawable/list_selector_background for all but the default state (you can define an xml file in your drawables folder for this; see the StateList documentation).
You could also nest a layout inside your outer backgrounded row layout with its background set to #android:drawable/list_selector_background; that way the background would draw on top of your background, but below the content.
ListViews do not retain a visual indication of focus (or selection) while in touch mode. You will only see this when you use the hardware keyboard or controls to navigate your UI.
See the Google Touch Mode Android Blog article for more details.
So, if you are only using touch mode, you will never see focus or selection on ListViews.
I believe this has to do with the "Enabled" attribute of the items in the ListAdapter.
If your Adapter contains the code:
#Override
public boolean areAllItemsEnabled() {
return true;
}
Then each item should be clickable (and therefore should highlight on being touched).
Could you post details (and possibly code) of what kind of Adapter you're using for this list?
I struggled with this for a few days. In the end, I have to create a widget that supports Checkable interface and return that widget/view in my adapter's getiew() function. And the listview needs to be in ListView.CHOICE_MODE_SINGLE (or possibly any other mode specified by android:choiceMode) for it to keep track of the choice made on the UI.
So in essence, all the following needs to be in place for the listview item to stay highlighted:
ListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
ListAdapter.getView() return a view that implements Checkable interface
ListView.OnItemClickListener should call setItemChecked(position, true) to mark the item to be checked (and thus highlight it in the listview)
Hope this can help someone who is also struggling with this.

Categories

Resources