javaandroidandroid-listviewandroid-adapter

Android Studio - Java - Difficulty Highlighting ListView Item Background Color


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!


Solution

  • 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.