列表视图未从具有重复行的数据库中正确填充
Listview is not populated correctly from database with duplicate rows
我正在使用 AsyncTask
通过 JSON 数组从 mysql 数据库填充 Listview
。问题是我所有的项目都被显示了,除了最后一行的列表视图有重复的条目。
我的 File 来自数据库,因为我按升序导出它们
Check this explain better what is happening
还有我的代码:
public class JsonReadTask extends AsyncTask<String , Void, List<ProductList>> {
public JsonReadTask() {
super();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity(), ProgressDialog.THEME_DEVICE_DEFAULT_DARK);
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setMessage(getString(R.string.get_stocks));
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.setInverseBackgroundForced(true);
pDialog.show();
}
@Override
protected List<ProductList> doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(
response.getEntity().getContent()).toString();
customList = new ArrayList<>();
JSONObject jsonResponse = new JSONObject(jsonResult);
//JSONArray jsonMainNode = jsonResponse.optJSONArray("beverages");
JSONArray array = jsonResponse.getJSONArray("beverages");
for (int i = 0; i < array.length(); i++) {
JSONObject jsonChildNode = array.getJSONObject(i);
String name = jsonChildNode.getString("name");
String price = jsonChildNode.getString("price");
String image = jsonChildNode.getString("image");
customList.add(new ProductList(image, name, price));
}
return customList;
} catch (Exception e) {
e.printStackTrace();
getActivity().finish();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
} catch (Exception e) {
getActivity().finish();
}
return answer;
}
@Override
protected void onPostExecute(List<ProductList> customList) {
if(customList == null){
Log.d("ERORR", "No result to show.");
return;
}
ListDrawer(customList);
pDialog.dismiss();
}
}// end async task
public void accessWebService() {
JsonReadTask task = new JsonReadTask();
task.execute(new String[]{url});
}
public void ListDrawer(List<ProductList> customList) {
adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, customList);
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
我的适配器代码虽然我认为是无关紧要的,因为它在咖啡和零食上工作得很好:
public class ProductListAdapter extends ArrayAdapter<ProductList> {
public ProductListAdapter(Context context, int layoutId, List<ProductList> items) {
super(context, layoutId, items);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View arrayView = convertView;
ViewHolderItems holder;
ProductList currentPosition = null;
if(arrayView == null){
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
arrayView = vi.inflate(R.layout.list_item, parent, false);
currentPosition = getItem(position);
holder = new ViewHolderItems();
holder.viewName = (TextView)arrayView.findViewById(R.id.product_name_coffee);
holder.viewPrice = (TextView)arrayView.findViewById(R.id.product_price_coffee);
holder.viewImage = (ImageView)arrayView.findViewById(R.id.product_image_coffee);
arrayView.setTag(holder);
}else{
holder = (ViewHolderItems) arrayView.getTag();
}
if(currentPosition != null){
holder.viewName.setText(currentPosition.getName());
holder.viewPrice.setText(currentPosition.getPrice());
Ion.with(holder.viewImage).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).load(currentPosition.getImage());
}
return arrayView;
}
static class ViewHolderItems {
TextView viewName, viewPrice;
ImageView viewImage;
}
}
我的php代码:
<?php
try {
$handler = new PDO('mysql:host=localhost;dbname=database', 'root', 'password');
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
echo $e->getMessage();
die();
}
$query = $handler->query('SELECT * FROM beverages ORDER BY `name` ASC');
$records = array();
$records = $query->fetchAll(PDO::FETCH_ASSOC);
$json['beverages'] = $records;
echo json_encode($json);
知道为什么会这样吗???
尝试在 onCreate() 中初始化适配器
List<ProductList> list;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, list);
}
更新用于调用数组适配器构造函数的变量(在这种情况下,我声明了另一个全局变量 List 列表并将此变量传递给数组适配器构造函数)
public void ListDrawer(List<ProductList> customList) {
list = customList;
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
我认为问题出在列表视图适配器的 getView
方法中。我会这样修改它:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolderItems holder;
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolderItems();
holder.viewName = (TextView)convertView.findViewById(R.id.product_name_coffee);
holder.viewPrice = (TextView)convertView.findViewById(R.id.product_price_coffee);
holder.viewImage = (ImageView)convertView.findViewById(R.id.product_image_coffee);
convertView.setTag(holder);
} else {
holder = (ViewHolderItems) convertView.getTag();
}
holder.viewName.setText(getItem(position).getName());
holder.viewPrice.setText(getItem(position).getPrice());
Ion.with(holder.viewImage).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).load(getItem(position).getImage());
return convertView;
}
看起来问题出在您的 getView() 方法中,具体是这段代码:
if(currentPosition != null){
holder.viewName.setText(currentPosition.getName());
holder.viewPrice.setText(currentPosition.getPrice());
Ion.with(holder.viewImage).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).load(currentPosition.getImage());
}
只有当 currentPosition
不为空时才会更新视图的行——只有当 convertView
为 null
时才会发生这种情况。如果该行的数据不会更新,它只会使用当前在 convertView 中的数据。这就是为什么有些数据看起来是重复的。
要更正此问题,只需删除环绕 if
条件并保持其中的三行不变即可。
我正在使用 AsyncTask
通过 JSON 数组从 mysql 数据库填充 Listview
。问题是我所有的项目都被显示了,除了最后一行的列表视图有重复的条目。
我的 File 来自数据库,因为我按升序导出它们
Check this explain better what is happening
还有我的代码:
public class JsonReadTask extends AsyncTask<String , Void, List<ProductList>> {
public JsonReadTask() {
super();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity(), ProgressDialog.THEME_DEVICE_DEFAULT_DARK);
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setMessage(getString(R.string.get_stocks));
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.setInverseBackgroundForced(true);
pDialog.show();
}
@Override
protected List<ProductList> doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(
response.getEntity().getContent()).toString();
customList = new ArrayList<>();
JSONObject jsonResponse = new JSONObject(jsonResult);
//JSONArray jsonMainNode = jsonResponse.optJSONArray("beverages");
JSONArray array = jsonResponse.getJSONArray("beverages");
for (int i = 0; i < array.length(); i++) {
JSONObject jsonChildNode = array.getJSONObject(i);
String name = jsonChildNode.getString("name");
String price = jsonChildNode.getString("price");
String image = jsonChildNode.getString("image");
customList.add(new ProductList(image, name, price));
}
return customList;
} catch (Exception e) {
e.printStackTrace();
getActivity().finish();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
} catch (Exception e) {
getActivity().finish();
}
return answer;
}
@Override
protected void onPostExecute(List<ProductList> customList) {
if(customList == null){
Log.d("ERORR", "No result to show.");
return;
}
ListDrawer(customList);
pDialog.dismiss();
}
}// end async task
public void accessWebService() {
JsonReadTask task = new JsonReadTask();
task.execute(new String[]{url});
}
public void ListDrawer(List<ProductList> customList) {
adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, customList);
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
我的适配器代码虽然我认为是无关紧要的,因为它在咖啡和零食上工作得很好:
public class ProductListAdapter extends ArrayAdapter<ProductList> {
public ProductListAdapter(Context context, int layoutId, List<ProductList> items) {
super(context, layoutId, items);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View arrayView = convertView;
ViewHolderItems holder;
ProductList currentPosition = null;
if(arrayView == null){
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
arrayView = vi.inflate(R.layout.list_item, parent, false);
currentPosition = getItem(position);
holder = new ViewHolderItems();
holder.viewName = (TextView)arrayView.findViewById(R.id.product_name_coffee);
holder.viewPrice = (TextView)arrayView.findViewById(R.id.product_price_coffee);
holder.viewImage = (ImageView)arrayView.findViewById(R.id.product_image_coffee);
arrayView.setTag(holder);
}else{
holder = (ViewHolderItems) arrayView.getTag();
}
if(currentPosition != null){
holder.viewName.setText(currentPosition.getName());
holder.viewPrice.setText(currentPosition.getPrice());
Ion.with(holder.viewImage).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).load(currentPosition.getImage());
}
return arrayView;
}
static class ViewHolderItems {
TextView viewName, viewPrice;
ImageView viewImage;
}
}
我的php代码:
<?php
try {
$handler = new PDO('mysql:host=localhost;dbname=database', 'root', 'password');
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
echo $e->getMessage();
die();
}
$query = $handler->query('SELECT * FROM beverages ORDER BY `name` ASC');
$records = array();
$records = $query->fetchAll(PDO::FETCH_ASSOC);
$json['beverages'] = $records;
echo json_encode($json);
知道为什么会这样吗???
尝试在 onCreate() 中初始化适配器
List<ProductList> list;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
adapter = new ProductListAdapter(getActivity().getApplicationContext(), R.layout.list_item, list);
}
更新用于调用数组适配器构造函数的变量(在这种情况下,我声明了另一个全局变量 List 列表并将此变量传递给数组适配器构造函数)
public void ListDrawer(List<ProductList> customList) {
list = customList;
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
我认为问题出在列表视图适配器的 getView
方法中。我会这样修改它:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolderItems holder;
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolderItems();
holder.viewName = (TextView)convertView.findViewById(R.id.product_name_coffee);
holder.viewPrice = (TextView)convertView.findViewById(R.id.product_price_coffee);
holder.viewImage = (ImageView)convertView.findViewById(R.id.product_image_coffee);
convertView.setTag(holder);
} else {
holder = (ViewHolderItems) convertView.getTag();
}
holder.viewName.setText(getItem(position).getName());
holder.viewPrice.setText(getItem(position).getPrice());
Ion.with(holder.viewImage).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).load(getItem(position).getImage());
return convertView;
}
看起来问题出在您的 getView() 方法中,具体是这段代码:
if(currentPosition != null){
holder.viewName.setText(currentPosition.getName());
holder.viewPrice.setText(currentPosition.getPrice());
Ion.with(holder.viewImage).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).load(currentPosition.getImage());
}
只有当 currentPosition
不为空时才会更新视图的行——只有当 convertView
为 null
时才会发生这种情况。如果该行的数据不会更新,它只会使用当前在 convertView 中的数据。这就是为什么有些数据看起来是重复的。
要更正此问题,只需删除环绕 if
条件并保持其中的三行不变即可。