问题
Problem
I'm trying to create a ListView
with selectable items. I want to be able to click on an item in the ListView
and have the item change color in the list, and then go on and do something else with the data from the row.
I'm using a SimpleAdapter
.
How do I make it so that when I tap on a row, it turns a different color, and then when I tap on a different row, the new row is selected and changed to a new color, and the old row changes back to normal?
Code
Here is my code so far. The DBTools
class is has all of the data that I want to be displayed in my ListView
organized and taken care of. The getAllReceivers()
method returns an ArrayList
of HashMap<String, String>
s that have all of my data.
MainActivity.java:
public class MainActivity extends ListActivity {
DBTools dbTools = new DBTools(this);
ArrayList<HashMap<String, String>> receiverList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().hide();
setContentView(R.layout.activity_main);
receiverList = dbTools.getAllReceivers();
dbTools.close();
ListView listView = getListView();
if(receiverList.size() != 0) {
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] {"receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath});
setListAdapter(adapter);
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black" >
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="My List" />
</TableRow>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:id="@android:id/list" />
</TableLayout>
receiver_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tableRow" >
<TextView
android:id="@+id/receiverId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<TextView
android:id="@+id/receiverName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Robotronics" />
<TextView
android:id="@+id/fullPath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123.45.678.910:8088/robtrox/find" />
</TableRow>
回答1:
Solution
The solution to this problem is very simple. We need to add an OnItemClickListener
to our ListView
to listen for clicks and respond accordingly.
So, in the onCreate()
method, once you've made sure that you set of data isn't empty, you're going to want to Override the onItemClick()
method to listen for the click and change the color. You're also going to want to keep track of which item you selected for the later steps, so add public int selectionId = -1;
at the top of your class. Furthermore, you'll need to let the ListAdapter
know that you changed something by calling ((SimpleAdapter) getListAdapter()).notifyDataSetChanged()
.
if(receiverList.size() != 0) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int index, long id) {
view.setBackgroundColor(Color.RED);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
selectionId = Integer.valueOf(receiverIdTextView.getText().toString());
((SimpleAdapter) getListAdapter()).notifyDataSetChanged();
}
});
SimpleAdapter adapter = getNewAdapter();
setListAdapter(adapter);
}
Great! Now we have a working system that will change the color of the row that you tap. But we're not done yet. We need to make sure that the previous selection changes back to the normal color.
For this, we are going to use override the SimpleAdapter
's getView()
method, which is called everytime the ListView
goes to draw the items being displayed in it.
It only actually displays the items it needs to - the ones that you can see. It does not render the ones above or below your screen. So if you have 200 items in a ListView
, only 5 or 6, depending on the size of your screen and the size of the items, are being rendered at a time.
To override the getView()
method, go up to where you initialize the adapter
and change the code to this:
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] { "receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath}) {
@Override
public View getView (int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
if(receiverIdTextView.getText().toString().equals(String.valueOf(selectionId))) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.WHITE);
}
return view;
}
};
Every time one of the rows is drawn, since the getView()
will get called, the ListView
will check if the current view
has the id of row you selected. If it doesn't, it'll change the background color to white. If it does, it'll change the background color to red.
And voila! That's it! Now you are setting the background color to red when you click on an item in the ListView
.
Final Code
MainActivity.java:
public class MainActivity extends ListActivity {
DBTools dbTools = new DBTools(this);
ArrayList<HashMap<String, String>> receiverList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().hide();
setContentView(R.layout.activity_main);
receiverList = dbTools.getAllReceivers();
dbTools.close();
ListView listView = getListView();
if(receiverList.size() != 0) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int index, long id) {
view.setBackgroundColor(Color.RED);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
selectionId = Integer.valueOf(receiverIdTextView.getText().toString());
((SimpleAdapter) getListAdapter()).notifyDataSetChanged();
}
});
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] { "receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath}) {
@Override
public View getView (int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
if(receiverIdTextView.getText().toString().equals(String.valueOf(selectionId))) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.WHITE);
}
return view;
}
};
setListAdapter(adapter);
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black" >
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="My List" />
</TableRow>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:id="@android:id/list" />
</TableLayout>
receiver_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tableRow" >
<TextView
android:id="@+id/receiverId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<TextView
android:id="@+id/receiverName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Robotronics" />
<TextView
android:id="@+id/fullPath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123.45.678.910:8088/robtrox/find" />
</TableRow>
来源:https://stackoverflow.com/questions/26830505/create-a-listview-with-selectable-rows-change-background-color-of-listview-rows