问题
我正在尝试使用可选项创建ListView.我希望能够单击ListView中的项目并让项目在列表中更改颜色,然后继续使用行中的数据执行其他操作.
我正在使用SimpleAdapter.
如何制作它,以便当我点击一行时,它会变成另一种颜色,然后当我点击另一行时,新行被选中并更改为新颜色,旧行变回正常?
码
到目前为止,这是我的代码. DBTools类具有我希望在ListView中显示的所有数据,并且需要处理. getAllReceivers()方法返回包含所有数据的HashMap< String,String>的ArrayList.
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>
解决方法:
解
这个问题的解决方案非常简单.我们需要在ListView中添加一个OnItemClickListener来监听点击并做出相应的响应.
因此,在onCreate()方法中,一旦确定数据集不为空,您就会想要覆盖onItemClick()方法来侦听单击并更改颜色.您还希望跟踪为后面的步骤选择的项目,因此添加public int selectionId = -1;在你的班级顶部.此外,您需要通过调用((SimpleAdapter)getListAdapter()).notifyDataSetChanged()让ListAdapter知道您更改了某些内容.
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);
}
大!现在我们有一个工作系统,可以改变你点击的行的颜色.但我们还没有完成.我们需要确保先前的选择更改回正常颜色.
为此,我们将使用覆盖SimpleAdapter的getView()方法,每次ListView用于绘制其中显示的项目时都会调用该方法.
它实际上只显示它需要的项目 – 你可以看到的项目.它不会渲染屏幕上方或下方的那些.因此,如果ListView中有200个项目,则一次只渲染5或6个,具体取决于屏幕大小和项目大小.
要覆盖getView()方法,请转到初始化适配器的位置并将代码更改为:
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;
}
};
每次绘制其中一行时,由于将调用getView(),ListView将检查当前视图是否具有您选择的行ID.如果没有,它会将背景颜色更改为白色.如果是,它会将背景颜色更改为红色.
瞧!而已!现在,当您单击ListView中的项目时,您将背景颜色设置为红色.
最终守则
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>