ListView的Android notifyDataSetChanged()不起作用

时间:2014-09-03 05:45:20

标签: android listview

ListView将任何项目附加到不会刷新的项目以查看新插入的项目。我添加和刷新ListView的功能是:

public void getReceivedSMSFromWebService(long start, long count) throws Exception{

    getReceivedSMS(start, count);
    Cursor cursor = db.getAllReceivedSMSFromDatabase();
    cursor.moveToFirst();
    while (cursor.moveToNext()) {
        ReceiveFields tmp = new ReceiveFields();
        tmp.setLastId( Long.valueOf(cursor.getString(cursor.getColumnIndex("lastId"))) );
        tmp.setSmsNumber   ( cursor.getString(cursor.getColumnIndex("lastId")) );
        tmp.setMobileNumber( cursor.getString(cursor.getColumnIndex("mobileNumber")) );
        tmp.setSenderName  ( cursor.getString(cursor.getColumnIndex("senderName")) );
        tmp.setSmsBody     ( cursor.getString(cursor.getColumnIndex("smsBody")) );
        tmp.setReceiveDate ( cursor.getString(cursor.getColumnIndex("receiveDate")) );
        rows.add(tmp);
    }

    cursor.close();
    receiveListView.notifyDataSetChanged();
    Log.e( "++++++++++++++++++++++++ receiveListView COUNT " , String.valueOf( receiveListView.getCount() ) );
}

rows就是private List<ReceiveFields> rows;ReceiveFields是数据类结构:

public class ReceiveFields {

    public long lastId;
    public String smsNumber;
    public String mobileNumber;
    public String senderName;
    public String smsBody;
    public String receiveDate;
    private Context ctx;
}

因为receiveListView.notifyDataSetChanged();无效。但在我用这个函数测试之后:

private void setReceivedSMSToListView() {
    receiveListView = new ViewReceivedSMSDetailes(getActivity(), rows);
    setListAdapter(receiveListView);
}

正常工作,可以显示新插入的项目。问题是什么以及为什么notifyDataSetChanged无法正常工作?数据可以成功添加,我没有添加项目的问题。这个类标题是:

public class ReceivedSMS extends ListFragment implements AbsListView.OnScrollListener 

ReceivedSMS课程:

public class ReceivedSMS extends ListFragment implements AbsListView.OnScrollListener {

    public List<ReceiveFields> rows;
    private int prevVisibleItem;    
    private TSMS tsms;
    private String username;
    private String password;
    public Long getLastID;
    private boolean isFirstTime;
    private Context context;    
    private DatabaseHandler db;    
    private SQLiteDatabase dbHelper;    
    private ViewReceivedSMSDetailes receiveListView;

    public ReceivedSMS(Context context, String username, String password) {
        this.username = username;
        this.password = password;
        this.context = context;
    }

    public ReceivedSMS(String username, String password, long start, long count, Context context) {
        this.username = username;
        this.password = password;
        this.context = context;
        tsms = new TSMS(context, new User("tsms_ir", "1234567"));
        try {
            getReceivedSMS(start, count);
        } catch (Exception e1) {
            e1.printStackTrace();
            Log.e("Error in getReceivedSMS(start, count); ", "");
        }
    }

    public ReceivedSMS(Context context) {
        this.context = context;
        rows = getReceivedSMSFromDB();
    }

    public void getReceivedSMSFromWebService(long start, long count) throws Exception{
        getReceivedSMS(start, count);
        Cursor cursor = db.getAllReceivedSMSFromDatabase();
        cursor.moveToFirst();
        List<ReceiveFields> tmp = new ArrayList<ReceiveFields>();

        while (cursor.moveToNext()) {
            tmp.add(new ReceiveFields(
                    Long.valueOf(cursor.getString(cursor.getColumnIndex("lastId"))),
                    cursor.getString(cursor.getColumnIndex("smsNumber")),
                    cursor.getString(cursor.getColumnIndex("mobileNumber")),
                    cursor.getString(cursor.getColumnIndex("senderName")),
                    cursor.getString(cursor.getColumnIndex("smsBody")),
                    cursor.getString(cursor.getColumnIndex("receiveDate"))));
        }
        cursor.close();
        this.rows = tmp;
        receiveListView.notifyDataSetChanged();

        Log.e( "++++++++++++++++++++++++ receiveListView COUNT " , String.valueOf( receiveListView.getCount() ) );

    }

    public List<ReceiveFields> getReceivedSMS(long start, long count) throws UnsupportedEncodingException {

        tsms = new TSMS(context, new User("tsms_ir", "1234567"));
        try {
            rows = tsms.getReceivedSMS(start, count);
            saveRowsintoDatabase( rows );
        } catch (TException e) {
            e.printStackTrace();
            Log.e(getClass().toString(), "ERROR IN Fetch SMS From WebService List<ReceiveFields> getReceivedSMS(long start, long count) "+ String.valueOf(e));
        }
        return rows;
    }

    public void addToCurrentList (List<ReceiveFields> receiveRow ){
        rows.addAll(receiveRow);
    }

    public void saveRowsintoDatabase( List<ReceiveFields> receiveRow ){
        /*
         *  SAVE fetched from web service to database
         */
        for( ReceiveFields rf:receiveRow) {
            String splitDate[] = rf.getReceiveDate().split("/");

            CalendarTool ct = new CalendarTool(
                            Integer.valueOf(splitDate[0]),
                            Integer.valueOf(splitDate[1]),
                            Integer.valueOf(splitDate[2]));
            try {
                /*
                 * Find Duplicate row if not exist then can be write into DataBase
                 */
                String selectQuery = "SELECT lastId FROM ReceiveFields WHERE lastId = ? ";
                String[] args = {String.valueOf(rf.lastId)};
                Cursor cursor = dbHelper.rawQuery(selectQuery, args);
                if (!cursor.moveToFirst()) {
                    db.addReceivedToDataBase(new ReceiveFields(
                            Long.valueOf(rf.lastId), rf.getSmsNumber(),
                            rf.getMobileNumber(), URLDecoder.decode(rf.getSenderName(), "UTF-8"),
                            URLDecoder.decode(rf.getSmsBody(), "UTF-8"), ct.getGregorianDate()));
                }
                cursor.close();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                Log.e(getClass().toString(),"Error in db.addReceivedToDataBase(new ReceiveFields("+ String.valueOf(e));
            }
        }
    }

    public List<ReceiveFields> getReceivedSMSFromDB() {
        tsms = new TSMS(context);
        return tsms.getReceivedSMSFromDB();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        db = new DatabaseHandler(context);
        dbHelper = db.getWritableDatabase();
        setReceivedSMSToListView();
    }

    private void setReceivedSMSToListView() {
        receiveListView = new ViewReceivedSMSDetailes(getActivity(), rows);
        setListAdapter(receiveListView);
    }

    public long getLastID() {
        return rows.get(rows.size() - 1 ).getLastId();
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // Always call the superclass so it can save the view hierarchy state
        super.onCreate(savedInstanceState);
        getListView().setOnScrollListener(this);
    }

    @Override
    public void onListItemClick(ListView list, View v, int position, long id) {
        Toast.makeText(getActivity(), getListView().getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show();
    }

    @Override
    public void onScrollStateChanged(AbsListView absListView, int i) {
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (prevVisibleItem != firstVisibleItem) {
            //if (prevVisibleItem < firstVisibleItem)
            //    Log.i("info","");
            //else
            //    Log.e(getClass().toString(), "UP");
            prevVisibleItem = firstVisibleItem;

            if (firstVisibleItem == 0 && !isFirstTime) {
                Log.i("Info", "residam avval");
            }
            if ((firstVisibleItem + visibleItemCount) == totalItemCount) {
                Log.e("getReceivedSMS FUNCTION ", String.valueOf(getLastID()));
                try {
                    getReceivedSMSFromWebService(getLastID(), 20);
                } catch (Exception e) {
                    e.printStackTrace();    
                    Log.e(getClass().toString() , "Error in receive from WebService when scroll is in bottom of list "+ e);
                }
                Log.i("Info", "Connecting to server for get old messages if scrolling down finished");
            }
        }
    }
}

ADAPTER:

public class ViewReceivedSMSDetailes extends BaseAdapter {
    private LayoutInflater inflater;
    private List<ReceiveFields> row;
    public ViewReceivedSMSDetailes(Context context, List<ReceiveFields> row) {
        this.row = row;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return row.size();
    }

    @Override
    public ReceiveFields getItem(int position) {
        return row.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.received_sms_list_fragment, null);
        }

        TextView tv_smsBody = (TextView)convertView.findViewById(R.id.receive_SmsBody);    
        TextView tv_Mobile  = (TextView)convertView.findViewById(R.id.receive_Mobile);
        tv_smsBody.setText(getItem(position).getMobileNumber());
        tv_Mobile.setText(getItem(position).getMobileNumber());
        return convertView;
    }
}

更新 getReceivedSMSFromWebService功能:

public void getReceivedSMSFromWebService(long start, long count) throws Exception{
    getReceivedSMS(start, count);
    Cursor cursor = db.getAllReceivedSMSFromDatabase();
    cursor.moveToFirst();
    List<ReceiveFields> tmp = new ArrayList<ReceiveFields>();

    while (cursor.moveToNext()) {
        tmp.add(new ReceiveFields(
                Long.valueOf(cursor.getString(cursor.getColumnIndex("lastId"))),
                cursor.getString(cursor.getColumnIndex("smsNumber")),
                cursor.getString(cursor.getColumnIndex("mobileNumber")),
                cursor.getString(cursor.getColumnIndex("senderName")),
                cursor.getString(cursor.getColumnIndex("smsBody")),
                cursor.getString(cursor.getColumnIndex("receiveDate"))));
        this.rows = tmp;
    }
    cursor.close();
    receiveListView.setRow(tmp);
    receiveListView.notifyDataSetChanged();

    Log.e( "++++++++++++++++++++++++ receiveListView COUNT " , String.valueOf( receiveListView.getCount() ) );

}

适配器

public void setRow(List<ReceiveFields> row) {
    this.row = row;
}

3 个答案:

答案 0 :(得分:2)

由于您没有填充Adapter's List的数据,您的新数据不会显示在ListView

有两种方法可以使这些数据出现在ListView

  • 将新列表设置为适配器

为此你需要在Adapter类中创建一个方法

public void setRow(List<ReceiveFields> row) {
    this.row = row;
}

在添加或删除其他列表中的数据之后,您需要在关闭游标之后和getReceivedSMSFromWebService

之前在方法notifyDataSetChanged()中将该列表设置为适配器
cursor.close();
receiveListView.setRow(row);
receiveListView.notifyDataSetChanged();
  • 再次设置AddAdapter()

另一种选择是使用带有填充数据的新List再次设置适配器。因为你已经为它创建了一个方法,所以你只需要调用那个方法。

setReceivedSMSToListView();

更新:

尝试使用以下方法:

public void getReceivedSMSFromWebService(long start, long count) throws Exception{
    getReceivedSMS(start, count);
    Cursor cursor = db.getAllReceivedSMSFromDatabase();
    cursor.moveToFirst();
    // List<ReceiveFields> tmp = new ArrayList<ReceiveFields>();

    while (cursor.moveToNext()) {
        ReceiveFields mReceiveFields = new ReceiveFields();
        mReceiveFields.setLastId(Long.valueOf(cursor.getString(cursor.getColumnIndex("lastId"))));
        mReceiveFields.setSmsNumber(cursor.getString(cursor.getColumnIndex("lastId")));
        mReceiveFields.setMobileNumber(cursor.getString(cursor.getColumnIndex("mobileNumber")));
        mReceiveFields.setSenderName(cursor.getString(cursor.getColumnIndex("senderName")));
        mReceiveFields.setSmsBody(cursor.getString(cursor.getColumnIndex("smsBody")));
        mReceiveFields.setReceiveDate(cursor.getString(cursor.getColumnIndex("receiveDate")));
        // while here you are creating new List named **tmp** and 
        // assining to the rows which will delete your old data of rows list
        // add object directly to the rows list
        this.rows.add(mReceiveFields);
    }
    cursor.close();
    // here you are you are assigning **tmp** as setRow() instead of that
    receiveListView.setRow(rows);
    receiveListView.notifyDataSetChanged();

    Log.e( "++++++++++++++++++++++++ receiveListView COUNT " , String.valueOf( receiveListView.getCount() ) );
}

答案 1 :(得分:0)

如果传递给适配器的列表未在循环中逐个填充,则

adapter.notifyDataSetChanged()不起作用。换句话说,如果将列表分配给要传递给适配器的列表,则adapter.notifyDataSetChanged()将不起作用。例如,你在这里做.. ..

this.rows = tmp;

这里的行是您传递给适配器的列表,而tmp是另一个列表,如果您这样做了,您已经完成了,即将列表分配给您在适配器中传递的列表,notify.dataSetChanged()将不会工作。因此,解决方案是您应该将值直接添加到行列表,而不是先将其添加到tmp列表,然后将该列表分配给行列表。

答案 2 :(得分:0)

尝试替换它:

if (convertView == null) {
    convertView = inflater.inflate(R.layout.received_sms_list_fragment, null);
}

用这个:

if (convertView == null) {
    convertView = inflater.inflate(R.layout.received_sms_list_fragment, parent);
}