Introduction:
I am encountering an issue with highlighting the background color of ListView
items in my Android application. Despite my attempts to modify the background color programmatically, the changes are not reflected in the UI.
Problem Description:
I am trying to dynamically change the background color of ListView
items based on certain conditions, such as matching a specific song name. However, even though my code executes without errors and logs indicate that the matching logic is functioning correctly, the UI does not reflect the changes. The background color remains unchanged.
Initialization of ListView
and Adapter
:
ListView songsListView = findViewById(R.id.songsListView);
SongsAdapter songsAdapter = new SongsAdapter(context, songNames);
songsListView.setAdapter(songsAdapter);
Attempt to Change Background Color within Loop:
// Find and highlight the song using the adapter
for (int i = 0; i < songsAdapter.getCount(); i++) {
String tempSongName = songsAdapter.getItem(i);
// Log information about the song
Log.d("SttList", "(SetListMasterViewActivity) line #222 - ChildViewInfo - Child view index: " + i);
Log.d("SttList", "(SetListMasterViewActivity) line #223 - ChildViewInfo - tempSongName: " + tempSongName + ", lastViewedSongName: " + (i + 1) + ") " + lastViewedSongName);
// Check if the song name matches the last viewed song name
if (tempSongName != null && tempSongName.equalsIgnoreCase((i + 1) + ") " + lastViewedSongName)) {
// Highlight the corresponding ListView item
View childView = songsAdapter.getView(i, null, songsListView);
if (childView instanceof TextView) {
TextView textView = (TextView) childView;
textView.setBackgroundColor(Color.YELLOW);
// Log the match
Log.d("SttList", "(SetListMasterViewActivity) line #226 - ChildViewInfo - Match found for song: " + lastViewedSongName);
// Exit the loop once the match is found
break;
}
}
}
xml:
<!-- list_item_song.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Song Number -->
<TextView
android:id="@+id/itemNumberTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_marginEnd="8dp"/>
<!-- Song Name -->
<TextView
android:id="@+id/songNameTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="16sp" />
<!-- Divider -->
<View
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="#888888" />
</LinearLayout>
In my adapter
class - SongListAdapter
:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item_song, parent, false);
}
// Get the item for this position
String songName = getItem(position);
// Find views in the layout
TextView itemNumberTextView = convertView.findViewById(R.id.itemNumberTextView);
TextView songNameTextView = convertView.findViewById(R.id.songNameTextView);
// Set the song number
itemNumberTextView.setText((position + 1) + ")");
// Set the song name
songNameTextView.setText(songName);
// Set background color
int backgroundColor = mBackgroundColors.get(position, 0); // Default is transparent
convertView.setBackgroundColor(backgroundColor);
return convertView;
}
I Have Tried:
Trying to change the background color from the Adapter
class:
public void updateItemBackground(int position, int color) {
mBackgroundColors.put(position, color);
notifyDataSetChanged();
}
with the adapter defined at the class level:
private SongListAdapter adapter;`
and populated here:
adapter = new SongListAdapter(this, songNames);
and being used to call the updateItemBackground
method here, from within my loop:
if (childView instanceof TextView) {
adapter.updateItemBackground(i, Color.YELLOW);
// Log the match
Log.d("SttList", "(SetListMasterViewActivity) line #226 - ChildViewInfo - Match found for song: " + lastViewedSongName);
// Exit the loop once the match is found
break;
}
But I got a NullPointerException
error - which I was able to fix via @Upendra Shah's
comment but still cannot highlight the item within the ListView
.
Thank you for reading!
I had this class level variable:
private List<Songs> songsList;
but I also had another List
variable and was mixing the use to access my List
. I removed the redundant object and rewrote my code to only use the songsList
object. By doing this I was able to isolate my object without confusing with multiple objects doing the same function.
Additionally, using this to my parent class to call the Adapter
class (SongListAdapter
), using this variable:
private SongListAdapter songsAdapter;
and passing into my Adapter
class:
songsAdapter = new SongListAdapter(this, new ArrayList<>());
songsListView.setAdapter(songsAdapter);
I was able to call this method in my onActivityResult
(parent class):
public void updateItemBackground(int position, int color) {
// Reset all background colors to transparent
mBackgroundColors.clear();
notifyDataSetChanged();
// Log the reset action
Log.d("SttList", "(UpdateBackground) Resetting background colors");
int adjustmentFactor = 50;
int lighterColor = Color.rgb(
Math.min(Color.red(Color.DKGRAY) + adjustmentFactor, 255),
Math.min(Color.green(Color.DKGRAY) + adjustmentFactor, 255),
Math.min(Color.blue(Color.DKGRAY) + adjustmentFactor, 255)
);
// Set the background color of the specific item
mBackgroundColors.put(position, lighterColor);
notifyDataSetChanged();
}
These actions were able to highlight the List
at the appropriate array index.