【问题标题】:Listview isn't updating in FragmentListview 没有在 Fragment 中更新
【发布时间】:2016-11-10 06:37:13
【问题描述】:

我确定updateFromDatabase() 函数有效,我使用打印语句查看放入mCoordinatesArray 的条目在那里而不是空字符串。但是,当我重新启动应用程序时,片段永远不会使用数据库中的项目填充列表视图。我认为这与片段生命周期有关,但我不知道。

此外,当我第一次不重新启动应用程序并运行它时,列表视图运行良好。当我旋转或重新启动应用程序时,列表视图不再填充。

public class LocalFragment extends Fragment{

private ListView mLocalList;
private ArrayAdapter<String> adapter;
private ArrayList<String> mCoordinatesArray;
private BroadcastReceiver mBroadcastReceiver;
private LocationBaseHelper mDatabase;
private DateFormat dateFormat;
private String dateString;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    View v = inflater.inflate(R.layout.fragment_local,container,false);
    // SQLite Setup
    mDatabase = new LocationBaseHelper(getActivity());

    mLocalList = (ListView) v.findViewById(R.id.lv_local);
    mCoordinatesArray = new ArrayList<>();
    adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mCoordinatesArray);
    if(!mDatabase.size().equals("0")){
        updateFromDatabase();
    }
    mLocalList.setAdapter(adapter);
    return v;
}

@Override
public void onResume() {
    super.onResume();

    if(mBroadcastReceiver == null){
        mBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                dateFormat = new SimpleDateFormat("MM/dd HH:mm:ss a");
                dateString = dateFormat.format(new Date());

                String[] data = intent.getStringExtra("coordinates").split(" ");
                mDatabase.insertEntry(dateString,data[0],data[1]);
                System.out.println(mDatabase.size());

                mCoordinatesArray.add(dateString + " " + data[0] + " " + data[1]);
                adapter.notifyDataSetChanged();
            }
        };
    }
    getActivity().registerReceiver(mBroadcastReceiver, new IntentFilter("location_update"));
}

@Override
public void onDestroy() {
    super.onDestroy();
    if(mBroadcastReceiver!=null){
        getActivity().unregisterReceiver(mBroadcastReceiver);
    }
}

// THIS METHOD CAN BE USED TO UPDATE THE ARRAY HOLDING COORDINATES FROM THE LOCAL DATABASE
private void updateFromDatabase(){
    //mCoordinatesArray.clear();
    mCoordinatesArray = mDatabase.getEntireDatabase();
    adapter.notifyDataSetChanged();
}

}

这是我的 Helper 类,以防万一,但我认为问题不在这里。

public class LocationBaseHelper extends SQLiteOpenHelper {

private static final int VERSION = 1;
private static final String D​A​T​A​B​A​S​E​_​N​A​M​E​ = "locationBase.db";

public LocationBaseHelper(Context context) {
    super(context, D​A​T​A​B​A​S​E​_​N​A​M​E​, null, VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("create table " +    LocationTable.NAME              + " ("      +
                                    LocationTable.Cols.DATE_TIME    + " text, " +
                                    LocationTable.Cols.LATITUDE     + " text, " +
                                    LocationTable.Cols.LONGITUDE    + " text )"
    );
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

public void insertEntry(String date_time, String latitude, String longitude){
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues content = new ContentValues();
    content.put(LocationTable.Cols.DATE_TIME,date_time);
    content.put(LocationTable.Cols.LATITUDE,latitude);
    content.put(LocationTable.Cols.LONGITUDE,longitude);
    db.insert(LocationTable.NAME,null,content);
}

public ArrayList<String> getEntireDatabase(){
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery("SELECT * FROM " + LocationTable.NAME,null);
    cursor.moveToFirst();

    ArrayList<String> values = new ArrayList<>();

    do{
        String value = (String) cursor.getString(cursor.getColumnIndex(LocationTable.Cols.DATE_TIME)) + " " +
                       (String) cursor.getString(cursor.getColumnIndex(LocationTable.Cols.LATITUDE))  + " " +
                       (String) cursor.getString(cursor.getColumnIndex(LocationTable.Cols.LONGITUDE));
        values.add(0,value);

    }while(cursor.moveToNext());

    return values;
}

public String size(){
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM " + LocationTable.NAME,null);
    cursor.moveToFirst();
    return cursor.getString(0);
}
}

【问题讨论】:

  • 你能展示你的 LocationBaseHelper 类吗?
  • 好的,但我很确定它工作正常。这与我确信的列表视图有关。
  • 尝试在片段的 onActivityCreated() 函数中移动 UI 以外的逻辑,它在 onCreateView() 之后调用,并确保 Activity 已准备好进行通信
  • 同样的问题 :(

标签: java android listview android-fragments android-lifecycle


【解决方案1】:

通过调用mCoordinatesArray = mDatabase.getEntireDatabase();,您正在更改mCoordinatesArray 的引用,而适配器仍保留旧的引用,因此它看不到任何更改。

与其创建mCoordinateArray 的新实例,不如只更新它包含的值,例如:

mCoordinateArray.clear();
mCoordinateArray.addAll(mDatabase.getData());
adapter.notifyDataSetChange();

这样您正在更改适配器引用的数据,而不是创建适配器不知道的全新数据集。

【讨论】:

  • 天哪,我爱你,我不知道更改引用毁了它
【解决方案2】:

尝试重新创建您的 ArrayAdapter,而不是使用 .notifyDataSetChanged():

// update Data
mCoordinatesArray = mDatabase.getEntireDatabase();
// create new adapter with new updated array
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mCoordinatesArray);
// set adapter for the listview
mLocalList.setAdapter(adapter);

【讨论】:

    【解决方案3】:

    您可以将此方法放在您的片段中,并从附加到片段的活动中调用。

    public void updateList(List<?> result) {
    
        if (multimediaListRent.size()>0) {
            multimediaGridView.setAdapter(gridMediaListAdapter);
            multimediaListRent.clear();
        }
    
        gridMediaListAdapter.notifyDataSetChanged();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-06
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多