每次刷新()时,Android的Pull-to-Refresh双倍大小的ListView

时间:2013-01-17 20:35:21

标签: android listview

每次刷新(使用chrisbanes库)时,我的ListView都会将所有“新”数据附加到旧数据的末尾,而不是替换它。我已经检查了我的Json解析器,它返回了我的ArrayList,它肯定是 NOT ,我不小心在列表本身加倍。

我尝试了各种各样的“notifyDataSetChanged()”和“.invalidate()”,我似乎无法说服我的ListView完全重新填充自己。它在方向转换上正常工作,我意识到这是一个线索,但我似乎无法弄清楚在这种情况下有什么不同。

下面的代码,感谢任何提示!

public class VoicemailsPME extends Activity{

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.voicemails_pme);

    listView = (PullToRefreshListView) findViewById(R.id.pulllist);

    final String username = getIntent().getExtras().getString("username"); 
    final String password = getIntent().getExtras().getString("password");
    mailboxId = getIntent().getExtras().getString("mailboxId");

    m_voicemails = new ArrayList<Voicemail>();

    mHandlerFirst.post(new Runnable() {

        @Override
        public void run() {
            CheckConnectionTask CCT = new CheckConnectionTask(VoicemailsPME.this);
            CCT.execute(username, password);
            firstTime = false;
        }
    });

    listView.setOnRefreshListener(new OnRefreshListener<ListView>() {

        @Override
        public void onRefresh(PullToRefreshBase<ListView> lv) {
            lv.invalidate();
            mHandler.post(new Runnable() {                  
                @Override
                public void run() {
                    CheckConnectionTask CCT = new CheckConnectionTask(VoicemailsPME.this);
                    CCT.execute(username, password);
                }
            });
        }
    });

    this.m_adapter = new OrderAdapter(this, R.layout.voicemails_pme_row, m_voicemails);
    listView.setAdapter(m_adapter);
}

private Runnable returnRes = new Runnable() {

    @Override
    public void run() {
        if(m_voicemails != null && m_voicemails.size() > 0){
            for(int i=0;i<m_voicemails.size();i++)
                m_adapter.add(m_voicemails.get(i));
        }
    }
};

private void getVoicemails(){
    try{
        //Log.d("Data right before Json Parse", data);
        Json jsonParser = new Json(data);

        m_voicemails = jsonParser.getVoicemailsPME();
    } catch (Exception e) {
        Log.e("BACKGROUND_PROC", e.getMessage());
    }
    runOnUiThread(returnRes);
}

private class OrderAdapter extends ArrayAdapter<Voicemail> {

    private ArrayList<Voicemail> items;

    public OrderAdapter(Context context, int textViewResourceId, ArrayList<Voicemail> items) {
        super(context, textViewResourceId, items);
        this.items = items;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Voicemail vm = items.get(position);
        View v = convertView;

        if (v == null) {
            LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.voicemails_pme_row, null);
        }
        if (vm != null) {
            TextView tt = (TextView) v.findViewById(R.id.toptext);
            TextView bt = (TextView) v.findViewById(R.id.bottomtext);
            TextView nm = (TextView) v.findViewById(R.id.length);

            if (tt != null) 
            {
                tt.setText(vm.getPhoneNumber());
                if(vm.getNewStatus())
                    tt.setTypeface(null, Typeface.BOLD);
            }

            if(bt != null)
            {
                bt.setText(vm.getDate());
            }

            if(nm != null)
            {
                nm.setText(vm.getLength());
            }
        }
        return v;
    }
}

class CheckConnectionTask extends AsyncTask<String, Void, String> {
    private VoicemailsPME activity;
    private ProgressDialog dialog;
    private Context context;

    public CheckConnectionTask(VoicemailsPME activity)
    {
        this.activity = activity;
        context = activity;
        dialog = new ProgressDialog(context);
    }

    String username, password, str;
    @Override
    protected void onPreExecute() {
        if(firstTime)
        {
            this.dialog.setMessage("Loading...");
            this.dialog.show();
        }
    }


    @Override
    protected String doInBackground(String...arg0)
    {
        username = arg0[0];
        password = arg0[1];

        DefaultHttpClient httpclient = new DefaultHttpClient();
        Credentials creds = new UsernamePasswordCredentials(username, password);
        httpclient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), creds);

        try{
            HttpPost post = new HttpPost("https://www.my.patlive.com/api/v1.0/Mailbox/" + mailboxId + "/messages?format=json");

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);

            nameValuePairs.add(new BasicNameValuePair("username", username));
            nameValuePairs.add(new BasicNameValuePair("password", password));

            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            HttpResponse response = httpclient.execute(post);
            str = inputStreamToString(response.getEntity().getContent()).toString();    

            if(str.contains("\"ErrorCode\":0"))
            {
                //data = str;
                return str;
            }

        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();}
        return str;
    }

    @Override
    protected void onPostExecute(String newData)
    {
        if(dialog.isShowing())
        {
            dialog.dismiss();
        }
        data = newData;
        getVoicemails();

        m_adapter.notifyDataSetChanged();

        listView.onRefreshComplete();
    }
}

}

1 个答案:

答案 0 :(得分:1)

认为你的getVoicemail()方法是罪魁祸首。

由于适配器的工作方式,它使用您最初提供的后备阵列(m_voicemails),当您刷新它时,您创建一个新列表,但原始的列表不会被清除,然后您只需添加除此之外。

public void run() {
    //Try adding m_adapter.clear() here
    if(m_voicemails != null && m_voicemails.size() > 0){
        for(int i=0;i<m_voicemails.size();i++)
            m_adapter.add(m_voicemails.get(i)); 
    }
}

我发现将数据列表与适配器分开,然后将数据提供给适配器(使用set而不是add)更清楚。