0

(chrisbanesライブラリを使用して)更新するたびに、ListViewは、古いデータを置き換えるのではなく、古いデータの最後に追加されたすべての「新しい」データを取得します。ArrayListを返すJsonパーサーを既に確認しましたが、リスト自体が誤って2倍になっているわけではありません。

あらゆる種類の「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();
    }
}

}

4

1 に答える 1

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)); 
    }
}

データのリストをアダプターとは別に保持し、そのデータをアダプターにフィードする方が明確であることがわかりました(追加ではなくセットを使用)。

于 2013-01-17T20:55:20.783 に答える