ListView 不刷新 notifydatasetchanged
ListView doesn't refresh with notifydatasetchanged
我有一个 MySQL 数据库,其中两列显示在 android ListView
中。我使用 Retrofit 1.9 从 MySQL 获取数据。 ListView
的适配器是 BaseAdapter
而我没有 DatabaseHelper
class。当我从我的手机 phone 向 ListView
添加数据时,它不会刷新 ListView
。我必须关闭并重新启动应用程序。我尝试用 listViewAdapter.notifyDataSetChanged();
.
刷新
这是列表视图所在的片段:
public class rightFragment extends Fragment {
String BASE_URL = "http://awebsite.com";
View view;
ListView listView;
ListViewAdapter listViewAdapter;
Button buttondisplay;
Button buttonadd;
EditText new_id;
EditText newWordFra;
EditText newWordDeu;
ArrayList<String> id = new ArrayList<>();
ArrayList<String> fra = new ArrayList<>();
ArrayList<String> deu = new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(com.example.geeko.Deu.R.layout.fragment_right, container, false);
listView = (ListView) view.findViewById(com.example.geeko.Deu.R.id.listView); //<<<< ADDED NOTE use your id
listViewAdapter = new ListViewAdapter(getActivity(), id, fra, deu);
displayData();
buttondisplay = (Button) view.findViewById(com.example.geeko.Deu.R.id.buttondisplay);
buttonadd = (Button) view.findViewById(com.example.geeko.Deu.R.id.buttonadd);
buttondelete = (Button) view.findViewById(com.example.geeko.Deu.R.id.newID);
newWordFra = (EditText) view.findViewById(com.example.geeko.Deu.R.id.newWordFra);
newWordDeu = (EditText) view.findViewById(com.example.geeko.Deu.R.id.newWordDeu);
buttonadd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Toast.makeText(MainActivity.this , "button add", Toast.LENGTH_LONG).show();
insert_data();
listViewAdapter.notifyDataSetChanged();
}
});
buttondisplay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (buttondisplay.getText().toString().contains("Show")) {
listView.setAdapter(listViewAdapter);
buttondisplay.setText("Hide");
} else {
listView.setAdapter(null);
buttondisplay.setText("Show");
}
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long ids) {
new_id.setText(id.get(position));
newWordFra.setText(fra.get(position));
newWordDeu.setText(deu.get(position));
}
});
return view;
}
public void insert_data() {
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(BASE_URL) //Setting the Root URL
.build();
AppConfig.insert api = adapter.create(AppConfig.insert.class);
api.insertData(
newWordFra.getText().toString(),
newWordDeu.getText().toString(),
new Callback<Response>() {
@Override
public void success(Response result, Response response) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
String resp;
resp = reader.readLine();
Log.d("success", "" + resp);
JSONObject jObj = new JSONObject(resp);
int success = jObj.getInt("success");
if(success == 1){
Toast.makeText(getActivity(), "Successfully inserted", Toast.LENGTH_SHORT).show();
} else{
Toast.makeText(getActivity(), "Insertion Failed", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
Log.d("Exception", e.toString());
} catch (JSONException e) {
Log.d("JsonException", e.toString());
}
}
@Override
public void failure(RetrofitError error) {
Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
}
}
);
}
public void displayData() {
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(BASE_URL) //Setting the Root URL
.build();
AppConfig.read api = adapter.create(AppConfig.read.class);
api.readData(new Callback<JsonElement>() {
@Override
public void success(JsonElement result, Response response) {
String myResponse = result.toString();
Log.d("response", "" + myResponse);
try {
JSONObject jObj = new JSONObject(myResponse);
int success = jObj.getInt("success");
if (success == 1) {
JSONArray jsonArray = jObj.getJSONArray("details");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jo = jsonArray.getJSONObject(i);
id.add(jo.getString("id"));
fra.add(jo.getString("fra"));
deu.add(jo.getString("deu"));
}
listView.setAdapter(listViewAdapter);
} else {
Toast.makeText(getActivity(), "No Details Found", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
Log.d("exception", e.toString());
}
}
@Override
public void failure(RetrofitError error) {
Log.d("Failure", error.toString());
Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
}
}
);
}
}
这是 listViewAdpater class :
public class ListViewAdapter extends BaseAdapter {
private final Context context;
private ArrayList<String> id = new ArrayList<String>();
private ArrayList<String> fra = new ArrayList<String>();
private ArrayList<String> deu = new ArrayList<String>();
LayoutInflater layoutInflater;
public ListViewAdapter(Context ctx, ArrayList<String> id, ArrayList<String> fra, ArrayList<String> deu) {
this.context = ctx;
this.id = id;
this.fra = fra;
this.deu = deu;
}
@Override
public int getCount() {
return id.size();
}
@Override
public Object getItem(int position) {
return id.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint("ViewHolder")
@Override
public View getView(final int position, View view, ViewGroup parent) {
final Holder holder;
if (view == null) {
layoutInflater = (LayoutInflater) context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.list_item, null);
holder = new Holder();
holder.txt_fra = (TextView) view.findViewById(R.id.fra);
holder.txt_deu = (TextView) view.findViewById(R.id.deu);
view.setTag(holder);
} else {
holder = (Holder) view.getTag();
}
holder.txt_fra.setText(fra.get(position));
holder.txt_deu.setText(deu.get(position));
return view;
}
static class Holder {
TextView txt_fra, txt_deu;
}
}
我应该创建一个方法来刷新我的 ListView
吗?
首先,我建议删除适配器中不必要的变量初始化:
private ArrayList<String> id = new ArrayList<String>();
private ArrayList<String> fra = new ArrayList<String>();
private ArrayList<String> deu = new ArrayList<String>();
通过从您的片段分配指针,您已经分配了一个初始化的 ArrayList。您希望两个指针都指向同一个 ArrayList 对象,因此更改适用于两者。
显然,适配器中存储的数据未正确更新。我建议调试您的应用程序 - 设置断点,以便您可以看到适配器在更新后存储的数据。
notifyDataSetChanged()
已经实现了编写更新方法的想法。只需覆盖适配器中的方法并在调用 super.notifyDataSetChanged()
之前进行最终更改。
如果您对这些更改有任何成功,请告诉我们。
buttonadd.setOnClickListener(new View.OnClickListener() {
...
insert_data();
listViewAdapter.notifyDataSetChanged();
}
});
在您的 onClickListener
中,您正在调用 insert_data()
,然后是 listViewAdapter.notifyDataSetChanged()
insert_data()
方法正在发送网络请求以检索数据以填充列表。但是,您在网络请求完成之前调用 notifyDataSetChanged
。这就是为什么 listView
是空的,并且会一直是空的。您需要在网络请求之后以及在 ArrayList
中填充数据以调用 notifyDataSetChanged
之后等待。
我们怎么知道网络请求完成了?只需在回调结束时(您已实现):
new Callback<Response>() {
@Override
public void success(Response result, Response response) {...
在success
方法的最后,调用listViewAdapter.notifyDataSetChanged()
方法。
希望这是有道理的!尝试一下,让我们知道会发生什么
我找到了一个解决方案。我在方法 insert_data.
中添加了 getActivity.recreate();
public void success(Response result, Response response) {
try {
BufferedReader reader = new BufferedReader
(new InputStreamReader(result.getBody().in()));
String resp;
resp = reader.readLine();
Log.d("success", "" + resp);
JSONObject jObj = new JSONObject(resp);
int success = jObj.getInt("success");
if(success == 1){
Toast.makeText(getActivity(), "Successfully inserted",
Toast.LENGTH_SHORT).show();
getActivity().recreate();
} else{
Toast.makeText(getActivity(), "Insertion Failed",
Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
Log.d("Exception", e.toString());
} catch (JSONException e) {
Log.d("JsonException", e.toString());
}
}
我不确定这是最好的解决方案,但它确实有效。
我有一个 MySQL 数据库,其中两列显示在 android ListView
中。我使用 Retrofit 1.9 从 MySQL 获取数据。 ListView
的适配器是 BaseAdapter
而我没有 DatabaseHelper
class。当我从我的手机 phone 向 ListView
添加数据时,它不会刷新 ListView
。我必须关闭并重新启动应用程序。我尝试用 listViewAdapter.notifyDataSetChanged();
.
这是列表视图所在的片段:
public class rightFragment extends Fragment {
String BASE_URL = "http://awebsite.com";
View view;
ListView listView;
ListViewAdapter listViewAdapter;
Button buttondisplay;
Button buttonadd;
EditText new_id;
EditText newWordFra;
EditText newWordDeu;
ArrayList<String> id = new ArrayList<>();
ArrayList<String> fra = new ArrayList<>();
ArrayList<String> deu = new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(com.example.geeko.Deu.R.layout.fragment_right, container, false);
listView = (ListView) view.findViewById(com.example.geeko.Deu.R.id.listView); //<<<< ADDED NOTE use your id
listViewAdapter = new ListViewAdapter(getActivity(), id, fra, deu);
displayData();
buttondisplay = (Button) view.findViewById(com.example.geeko.Deu.R.id.buttondisplay);
buttonadd = (Button) view.findViewById(com.example.geeko.Deu.R.id.buttonadd);
buttondelete = (Button) view.findViewById(com.example.geeko.Deu.R.id.newID);
newWordFra = (EditText) view.findViewById(com.example.geeko.Deu.R.id.newWordFra);
newWordDeu = (EditText) view.findViewById(com.example.geeko.Deu.R.id.newWordDeu);
buttonadd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Toast.makeText(MainActivity.this , "button add", Toast.LENGTH_LONG).show();
insert_data();
listViewAdapter.notifyDataSetChanged();
}
});
buttondisplay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (buttondisplay.getText().toString().contains("Show")) {
listView.setAdapter(listViewAdapter);
buttondisplay.setText("Hide");
} else {
listView.setAdapter(null);
buttondisplay.setText("Show");
}
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long ids) {
new_id.setText(id.get(position));
newWordFra.setText(fra.get(position));
newWordDeu.setText(deu.get(position));
}
});
return view;
}
public void insert_data() {
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(BASE_URL) //Setting the Root URL
.build();
AppConfig.insert api = adapter.create(AppConfig.insert.class);
api.insertData(
newWordFra.getText().toString(),
newWordDeu.getText().toString(),
new Callback<Response>() {
@Override
public void success(Response result, Response response) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
String resp;
resp = reader.readLine();
Log.d("success", "" + resp);
JSONObject jObj = new JSONObject(resp);
int success = jObj.getInt("success");
if(success == 1){
Toast.makeText(getActivity(), "Successfully inserted", Toast.LENGTH_SHORT).show();
} else{
Toast.makeText(getActivity(), "Insertion Failed", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
Log.d("Exception", e.toString());
} catch (JSONException e) {
Log.d("JsonException", e.toString());
}
}
@Override
public void failure(RetrofitError error) {
Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
}
}
);
}
public void displayData() {
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(BASE_URL) //Setting the Root URL
.build();
AppConfig.read api = adapter.create(AppConfig.read.class);
api.readData(new Callback<JsonElement>() {
@Override
public void success(JsonElement result, Response response) {
String myResponse = result.toString();
Log.d("response", "" + myResponse);
try {
JSONObject jObj = new JSONObject(myResponse);
int success = jObj.getInt("success");
if (success == 1) {
JSONArray jsonArray = jObj.getJSONArray("details");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jo = jsonArray.getJSONObject(i);
id.add(jo.getString("id"));
fra.add(jo.getString("fra"));
deu.add(jo.getString("deu"));
}
listView.setAdapter(listViewAdapter);
} else {
Toast.makeText(getActivity(), "No Details Found", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
Log.d("exception", e.toString());
}
}
@Override
public void failure(RetrofitError error) {
Log.d("Failure", error.toString());
Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
}
}
);
}
}
这是 listViewAdpater class :
public class ListViewAdapter extends BaseAdapter {
private final Context context;
private ArrayList<String> id = new ArrayList<String>();
private ArrayList<String> fra = new ArrayList<String>();
private ArrayList<String> deu = new ArrayList<String>();
LayoutInflater layoutInflater;
public ListViewAdapter(Context ctx, ArrayList<String> id, ArrayList<String> fra, ArrayList<String> deu) {
this.context = ctx;
this.id = id;
this.fra = fra;
this.deu = deu;
}
@Override
public int getCount() {
return id.size();
}
@Override
public Object getItem(int position) {
return id.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint("ViewHolder")
@Override
public View getView(final int position, View view, ViewGroup parent) {
final Holder holder;
if (view == null) {
layoutInflater = (LayoutInflater) context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.list_item, null);
holder = new Holder();
holder.txt_fra = (TextView) view.findViewById(R.id.fra);
holder.txt_deu = (TextView) view.findViewById(R.id.deu);
view.setTag(holder);
} else {
holder = (Holder) view.getTag();
}
holder.txt_fra.setText(fra.get(position));
holder.txt_deu.setText(deu.get(position));
return view;
}
static class Holder {
TextView txt_fra, txt_deu;
}
}
我应该创建一个方法来刷新我的 ListView
吗?
首先,我建议删除适配器中不必要的变量初始化:
private ArrayList<String> id = new ArrayList<String>();
private ArrayList<String> fra = new ArrayList<String>();
private ArrayList<String> deu = new ArrayList<String>();
通过从您的片段分配指针,您已经分配了一个初始化的 ArrayList。您希望两个指针都指向同一个 ArrayList 对象,因此更改适用于两者。
显然,适配器中存储的数据未正确更新。我建议调试您的应用程序 - 设置断点,以便您可以看到适配器在更新后存储的数据。
notifyDataSetChanged()
已经实现了编写更新方法的想法。只需覆盖适配器中的方法并在调用 super.notifyDataSetChanged()
之前进行最终更改。
如果您对这些更改有任何成功,请告诉我们。
buttonadd.setOnClickListener(new View.OnClickListener() {
...
insert_data();
listViewAdapter.notifyDataSetChanged();
}
});
在您的 onClickListener
中,您正在调用 insert_data()
,然后是 listViewAdapter.notifyDataSetChanged()
insert_data()
方法正在发送网络请求以检索数据以填充列表。但是,您在网络请求完成之前调用 notifyDataSetChanged
。这就是为什么 listView
是空的,并且会一直是空的。您需要在网络请求之后以及在 ArrayList
中填充数据以调用 notifyDataSetChanged
之后等待。
我们怎么知道网络请求完成了?只需在回调结束时(您已实现):
new Callback<Response>() {
@Override
public void success(Response result, Response response) {...
在success
方法的最后,调用listViewAdapter.notifyDataSetChanged()
方法。
希望这是有道理的!尝试一下,让我们知道会发生什么
我找到了一个解决方案。我在方法 insert_data.
中添加了getActivity.recreate();
public void success(Response result, Response response) {
try {
BufferedReader reader = new BufferedReader
(new InputStreamReader(result.getBody().in()));
String resp;
resp = reader.readLine();
Log.d("success", "" + resp);
JSONObject jObj = new JSONObject(resp);
int success = jObj.getInt("success");
if(success == 1){
Toast.makeText(getActivity(), "Successfully inserted",
Toast.LENGTH_SHORT).show();
getActivity().recreate();
} else{
Toast.makeText(getActivity(), "Insertion Failed",
Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
Log.d("Exception", e.toString());
} catch (JSONException e) {
Log.d("JsonException", e.toString());
}
}
我不确定这是最好的解决方案,但它确实有效。