在自定义 ArrayAdapter 上更新 ListView
Updating ListView On Custom ArrayAdapter
如果这与其他线程类似,我深表歉意,但我还没有找到关于如何在我的自定义 ArrayAdapter 中更新 ListView 的好的解决方案。
我正在扩展 FragmentActivity 以创建用于添加/更新新列表条目的自定义对话框弹出窗口(工作正常),但我似乎无法在进行更改后更新 ServerActivityArrayAdapter 中的 ListView .
显然,adapter.notifyDataSetChanged();在 ServersActivity class 中是不够的,但我不知道如何在 ServerDialog 弹出窗口中单击保存按钮后更新我的 ListView。任何帮助将不胜感激!
public class ServersActivity extends FragmentActivity {
private List<Server> server;
private ListView lv;
private ServerActivityArrayAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.server_list);
server = getServers();
lv = (ListView) findViewById(android.R.id.list);
adapter = new ServerActivityArrayAdapter(this, R.layout.server_list_item, server);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
showServerDialog(position);
}
});
}
...
private void showServerDialog(int position) {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
ServerDialog serverDialog = new ServerDialog(position);
ServerDialog.newInstance();
serverDialog.show(fragmentManager, "server_dialog");
}
ServerDialog class 用于添加新的列表条目
public class ServerDialog extends DialogFragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.settings_fragment, container);
context = getActivity().getApplicationContext();
dbh = new DbHandler(context);
etName = (EditText) view.findViewById(R.id.etName);
etAddress = (EditText) view.findViewById(R.id.etAddress);
etPort = (EditText) view.findViewById(R.id.etPort);
swtchNumDoors = (Switch) view.findViewById(R.id.swtchNumDoors);
Button btnSave = (Button) view.findViewById(R.id.btnSave);
loadData();
String title = (!newServer) ? "Edit Server" : "Add A New Server " + ID;
getDialog().setTitle(title);
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
server[ID] = String.valueOf(ID);
server[SERVER_NAME] = etName.getText().toString();
server[ADDRESS] = etAddress.getText().toString();
server[PORT] = etPort.getText().toString();
if (server[ADDRESS].isEmpty() || server[PORT].isEmpty()) {
Toast.makeText(context, "Invalid Entry", Toast.LENGTH_LONG).show();
} else {
saveData();
// TODO - notify ServersActivity of change
}
}
});
return view;
}
public class ServerActivityArrayAdapter extends ArrayAdapter<Server> {
private int layout;
private String[][] values;
private int defServer;
private static LayoutInflater inflater;
ServerActivityArrayAdapter class 用于显示 ListView
public ServerActivityArrayAdapter(Context context, int layout, List<Server> servers) {
super(context, layout, servers);
this.layout = layout;
int i = 0;
values = new String[servers.size()][5];
for (Server server : servers) {
values[i][0] = Integer.toString(server.id);
values[i][1] = server.name;
values[i][2] = server.address;
values[i][3] = Integer.toString(server.port);
values[i][4] = Integer.toString(server.num_doors);
defServer = (server.default_server) ? i : 0;
i++;
}
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
private static class ViewHolder {
private TextView tvServerName;
private CheckBox cbDefault;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View v = convertView;
try {
if(v == null) {
v = inflater.inflate(layout, parent, false);
holder = new ViewHolder();
holder.tvServerName = (TextView) v.findViewById(R.id.tvServerName);
holder.cbDefault = (CheckBox) v.findViewById(R.id.cbDefault);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.tvServerName.setText(values[position][1]);
holder.cbDefault.setChecked(defServer==position);
} catch (Exception e){
System.out.println(e);
}
return v;
}
您可以使用一个接口,并在其中包含一个名为 updateListView() 的方法。
在您的 FragmentActivity 中实现此接口。在实现的方法中,添加更新listView的代码。
然后在对话框的按钮代码中调用 ((Interfacename) getActivity).updateListView()
您的问题出在适配器的实现上。您正在使用 List<Server>
对象(超级调用)实例化 ArrayAdapter
,然后创建您自己的二维数组 values
来包含数据。您将 values
数组用于 getView()
方法,但没有提及或通过代码显示您实际如何修改该数据以更新适配器。
您应该回拨适配器进行更新。 EG,调用 add()
、remove()
等。您只提到更新数据库,这与更新适配器无关。它无论如何都没有链接到数据库。即使您在适配器上调用前面提到的 mutate 方法,它们也不会工作,除非您特别 override
它们。默认 ArrayAdapter
实现将修改 List<Server>
数据,而不是您创建的 values
双维数组。
但是,如果您发现自己 override
那些支持 values
双维数组的变异方法...那么子类化 ArrayAdapter
就没有意义了。 ArrayAdapter
的部分要点是为您处理所有数据管理。在这种情况下,您应该继承 BaseAdapter
.
如果这与其他线程类似,我深表歉意,但我还没有找到关于如何在我的自定义 ArrayAdapter 中更新 ListView 的好的解决方案。
我正在扩展 FragmentActivity 以创建用于添加/更新新列表条目的自定义对话框弹出窗口(工作正常),但我似乎无法在进行更改后更新 ServerActivityArrayAdapter 中的 ListView .
显然,adapter.notifyDataSetChanged();在 ServersActivity class 中是不够的,但我不知道如何在 ServerDialog 弹出窗口中单击保存按钮后更新我的 ListView。任何帮助将不胜感激!
public class ServersActivity extends FragmentActivity {
private List<Server> server;
private ListView lv;
private ServerActivityArrayAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.server_list);
server = getServers();
lv = (ListView) findViewById(android.R.id.list);
adapter = new ServerActivityArrayAdapter(this, R.layout.server_list_item, server);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
showServerDialog(position);
}
});
}
...
private void showServerDialog(int position) {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
ServerDialog serverDialog = new ServerDialog(position);
ServerDialog.newInstance();
serverDialog.show(fragmentManager, "server_dialog");
}
ServerDialog class 用于添加新的列表条目
public class ServerDialog extends DialogFragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.settings_fragment, container);
context = getActivity().getApplicationContext();
dbh = new DbHandler(context);
etName = (EditText) view.findViewById(R.id.etName);
etAddress = (EditText) view.findViewById(R.id.etAddress);
etPort = (EditText) view.findViewById(R.id.etPort);
swtchNumDoors = (Switch) view.findViewById(R.id.swtchNumDoors);
Button btnSave = (Button) view.findViewById(R.id.btnSave);
loadData();
String title = (!newServer) ? "Edit Server" : "Add A New Server " + ID;
getDialog().setTitle(title);
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
server[ID] = String.valueOf(ID);
server[SERVER_NAME] = etName.getText().toString();
server[ADDRESS] = etAddress.getText().toString();
server[PORT] = etPort.getText().toString();
if (server[ADDRESS].isEmpty() || server[PORT].isEmpty()) {
Toast.makeText(context, "Invalid Entry", Toast.LENGTH_LONG).show();
} else {
saveData();
// TODO - notify ServersActivity of change
}
}
});
return view;
}
public class ServerActivityArrayAdapter extends ArrayAdapter<Server> {
private int layout;
private String[][] values;
private int defServer;
private static LayoutInflater inflater;
ServerActivityArrayAdapter class 用于显示 ListView
public ServerActivityArrayAdapter(Context context, int layout, List<Server> servers) {
super(context, layout, servers);
this.layout = layout;
int i = 0;
values = new String[servers.size()][5];
for (Server server : servers) {
values[i][0] = Integer.toString(server.id);
values[i][1] = server.name;
values[i][2] = server.address;
values[i][3] = Integer.toString(server.port);
values[i][4] = Integer.toString(server.num_doors);
defServer = (server.default_server) ? i : 0;
i++;
}
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
private static class ViewHolder {
private TextView tvServerName;
private CheckBox cbDefault;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View v = convertView;
try {
if(v == null) {
v = inflater.inflate(layout, parent, false);
holder = new ViewHolder();
holder.tvServerName = (TextView) v.findViewById(R.id.tvServerName);
holder.cbDefault = (CheckBox) v.findViewById(R.id.cbDefault);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.tvServerName.setText(values[position][1]);
holder.cbDefault.setChecked(defServer==position);
} catch (Exception e){
System.out.println(e);
}
return v;
}
您可以使用一个接口,并在其中包含一个名为 updateListView() 的方法。
在您的 FragmentActivity 中实现此接口。在实现的方法中,添加更新listView的代码。
然后在对话框的按钮代码中调用 ((Interfacename) getActivity).updateListView()
您的问题出在适配器的实现上。您正在使用 List<Server>
对象(超级调用)实例化 ArrayAdapter
,然后创建您自己的二维数组 values
来包含数据。您将 values
数组用于 getView()
方法,但没有提及或通过代码显示您实际如何修改该数据以更新适配器。
您应该回拨适配器进行更新。 EG,调用 add()
、remove()
等。您只提到更新数据库,这与更新适配器无关。它无论如何都没有链接到数据库。即使您在适配器上调用前面提到的 mutate 方法,它们也不会工作,除非您特别 override
它们。默认 ArrayAdapter
实现将修改 List<Server>
数据,而不是您创建的 values
双维数组。
但是,如果您发现自己 override
那些支持 values
双维数组的变异方法...那么子类化 ArrayAdapter
就没有意义了。 ArrayAdapter
的部分要点是为您处理所有数据管理。在这种情况下,您应该继承 BaseAdapter
.