Krang
Krang

Reputation: 53

How to disable a single row and change its background color in a listview, without a button (or a method if possible)?

The title of this post says it all.

This code works without any problems:

package abc.AvailableCars;

import android.graphics.Color;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class carListActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.car_list_layout);

final ListView carListview = (ListView) findViewById(R.id.list_view);

final Button dButton = (Button) findViewById(R.id.disable_button);

String[] cars = {"Maxima GXE", "Passat", "Focus SE", "Mazda6", "Avalon", :Sentra GXE"};

final List<String> list_of_cars = new ArrayList<String>(Arrays.asList(cars));

final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
        (this, android.R.layout.simple_list_item_1, list_of_cars);

carListview.setAdapter(arrayAdapter);

dButton.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
int chosenRow = 3;

carListview.getChildAt(3).setEnabled(false);
carListview.getChildAt(3).setBackgroundColor(Color.parseColor("#3f51b5"));

}

});

}

}

This is in my listview .xml file:

<Button
    android:id="@+id/disable_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Disable A Row"
    />

But, when I comment-out everything that belongs to the button, like below, and the Car List class is called, the app crashes with the error in the Logcat: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setEnabled(boolean)' on a null object reference:

final ListView carListview = (ListView) findViewById(R.id.list_view);
//final Button dButton = (Button) findViewById(R.id.disable_button);

String[] cars = {"Maxima GXE", "Passat", "Focus SE", "Mazda6", "Avalon"};

final List<String> list_of_cars = new ArrayList<String>(Arrays.asList(cars));

final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
        (this, android.R.layout.simple_list_item_1, list_of_cars);

carListview.setAdapter(arrayAdapter);

//dButton.setOnClickListener(new View.OnClickListener() {

//@Override
//public void onClick(View v) {

int chosenRow = 3;

carListview.getChildAt(chosenRow).setEnabled(false);
carListview.getChildAt(chosenRow).setBackgroundColor(Color.parseColor("#3f51b5"));

}

//});

}

//}

I'm not an Android newbie anymore, but this is eluding me.

I want the chosen row to be disabled and the color set as soon as the listview is shown.

How can I do this programmatically without a button?

I have tried every variation I can think of, getView(), even a fake click.

Just in case it makes a difference, this code is in a separate class and file than the MainActivity.java file, and is called in that file.

There has to be a simple answer. What do I need to change?

Please be verbose.

Thank you.

Upvotes: 0

Views: 430

Answers (2)

Krang
Krang

Reputation: 53

From my understanding, since listViews are views, they have to be Overridden for some things to be changed in them.

I chose not to disable the required rows, but check for them in code.

The complete code that works is below.
Some credit goes to Raghunandan for his/her answer at- Android - Change background color of specific item of ListView

Again, sorry, but the indentation of the code wouldn't work correctly for some reason.

import android.graphics.Color;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CarListActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.car_list_layout);

final ListView carListview = (ListView) findViewById(R.id.list_view);

String[] cars = {"European Cars:", "Mercedes", "Passat", "Bently", "Porsche", "BMW", "Yugo","Land Rover",
"Japanese Cars:", "Maxima GXE", "Mazda6", "Avalon", "Toyota", "Honda", ""};

final List<String> list_of_cars = new ArrayList<String>(Arrays.asList(cars));

final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
        (this, android.R.layout.simple_list_item_1, list_of_cars);

//------------------------------------------

carListview.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list_of_cars) {
// Since listViews are views, they have to be Overrdden for some things to be changed in them.
@Override
public View getView(int rowPosition, View convertView, ViewGroup parent) {

View row = super.getView(rowPosition, convertView, parent);

//------------------------------------------

// This works.  I have only tried this for two rows, the two I wanted.  I expected this line to crash the app, but it didn't.
if(getItem(rowPosition).equals("European Cars:") || getItem(rowPosition).equals("Japanese Cars:")) {

// Make the two rows have a white background color.
row.setBackgroundColor(Color.WHITE);  // this command WORKS fine by itself.

// row.setEnabled(false); this command caused "bleeding" over into other rows, so I will check for the rows in a condition.

}  // both of the getItems end here.

 else {

// All of the other rows should have this color.
row.setBackgroundColor(Color.parseColor("#EEE8AA"));
                                         // the default color

}  // else ends here.

//------------------------------------------

return row;

//------------------------------------------

}  // getView ends here.

});  // carListview.setAdapter ends here.

}  // onCreate ends here.

}  // CarListActivity ends here.

Thanks, and I hope this helps others.

Upvotes: 0

C0D3LIC1OU5
C0D3LIC1OU5

Reputation: 8680

You are calling carListview.getChildAt(chosenRow) when you set up your list view, in onCreate. Your list view is not ready yet. Try moving this code to your onResume - should look something like this:

@Override
public void onResume(){
    super.onResume();

    arrayAdapter.notifyDataSetChanged();

    int chosenRow = 3;

    carListview.getChildAt(chosenRow).setEnabled(false);

    carListview.getChildAt(chosenRow).setBackgroundColor(Color.parseColor("#3f51b5"));
 }

This is a pretty simple case - your chosenRow number is generated by you. You might need a custom Adapter if you need it to be algorithmic or user-driven. Have a look at this tutorial.

Upvotes: 1

Related Questions