未从具有重复行的数据库正确填充Listview

时间:2015-01-30 18:51:59

标签: php android mysql listview

我正在使用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);

知道为什么会这样吗???

3 个答案:

答案 0 :(得分:0)

尝试在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);
}

答案 1 :(得分:0)

我认为问题出在列表视图适配器的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;
}

答案 2 :(得分:0)

看起来问题出在你的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不为空时才会更新视图的行 - 只有在convertViewnull时才会发生这种情况。如果行的数据不会更新,它将只使用当前在convertView中的内容。这就是为什么有些数据看起来会重复的原因。

要纠正这个问题,只需删除包裹if条件并保留其中的三条线。