-1

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?

jdamcd
  • 3,658
  • 3
  • 21
  • 20
Ali Abdolahi
  • 324
  • 3
  • 10

2 Answers2

2

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.

Niko
  • 8,093
  • 5
  • 49
  • 85
  • when i use lv.getChildAt(whereIsMe); and then change the background, more that one child of my listview change their background! what is the problem? – Ali Abdolahi Jan 06 '14 at 16:01
  • That's because of recycling, you will have to set the default background in adapter getView method. – Niko Jan 06 '14 at 16:02
  • can you explain more? how can i do that? – Ali Abdolahi Jan 06 '14 at 16:03
  • oops, you mean, i have to get view and setBackgroundColor() for that? – Ali Abdolahi Jan 06 '14 at 16:05
  • In the adapter getView, where you inflate the View to be used, you get the pointer to persian TextView and call setBackgroundColor() for that, possibly transparent by default? Same way you set it later when getting the pointer with ListView getChild – Niko Jan 06 '14 at 16:06
  • another point, background color for sibiling row's change to black now! whats the problem? – Ali Abdolahi Jan 06 '14 at 16:20
  • Did you update the adapter getView to set the background color? – Niko Jan 06 '14 at 16:24
  • yes, i do, i add --> LinearLayout mL = (LinearLayout) vi.findViewById(R.id.custom_bg); mL.setBackgroundColor( Color.TRANSPARENT ); i update the background of view in a runnable every 300ms – Ali Abdolahi Jan 06 '14 at 16:26
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44633/discussion-between-niko-and-ali-abdolahi) – Niko Jan 06 '14 at 16:27
0

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

Community
  • 1
  • 1
DArkO
  • 15,880
  • 12
  • 60
  • 88