android listview 不更新

Posted

技术标签:

【中文标题】android listview 不更新【英文标题】:android listview doesn't update 【发布时间】:2015-12-29 09:39:58 【问题描述】:

我在使用从 sqlite 数据库填充的 listView 的日期范围时遇到问题,代码完美运行,但是我遇到的问题是 listView 在我没有更新(刷新)时选择另一个日期范围(当我再次触摸“搜索”按钮时),虽然数据适配器确实从数据库中获取了数据(通过使用logcat 确保了这一点)但不会在listView 中打印它。我无法使用函数notifyDataSetChanged(),它不起作用,并且每当我在add() 之后使用它时,应用程序就会崩溃。

这里是代码:-

public class ProductionCommentsActivity extends Activity implements View.OnClickListener 
private DBHandler dbHandler;
private ListView listView;
private Context context;
private ArrayList<String> results = new ArrayList<String>();
private ArrayAdapter adapter;
private static String newline = System.getProperty("line.separator");//a variable for line break
private EditText editTextFrom, editTextTo;
private DatePickerDialog datePickerDialogFrom, datePickerDialogTo;
private SimpleDateFormat simpleDateFormat;
private String fromDate,toDate ; // variables to store the chosen dates

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_production_comments);

    dbHandler = new DBHandler(this, dbHandler.DATABASE_NAME_PRODUCTION, null, 1);
    try 
        dbHandler.copyDataBase();
        Log.d("copydb", dbHandler.getDatabaseName());
     catch (IOException e) 
        e.printStackTrace();
        Log.d("copydb",e.getMessage());
    

    //defining list view
    listView = (ListView) findViewById(R.id.listView);

    //defining edit texts properties
    editTextFrom = (EditText) findViewById(R.id.editTextFrom);
    editTextFrom.setInputType(InputType.TYPE_NULL);
    editTextFrom.requestFocus();

    editTextTo = (EditText) findViewById(R.id.editTextTo);
    editTextTo.setInputType(InputType.TYPE_NULL);

    //setting up the date format
    simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
    setDateTimeField();
    context = this;


//method to handle the date pickers properties
private void setDateTimeField() 
    editTextFrom.setOnClickListener((View.OnClickListener) ProductionCommentsActivity.this);
    editTextTo.setOnClickListener((View.OnClickListener) ProductionCommentsActivity.this);

    //creating a new instance of the calendar
    Calendar newCalendar = Calendar.getInstance();

    //creating a pop up date picker
    datePickerDialogFrom = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() 

        //getting the chosen date and setting its format
        //and writing the chosen date in the edit text
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) 
            Calendar newDate = Calendar.getInstance();
            newDate.set(year, monthOfYear, dayOfMonth);
            editTextFrom.setText(simpleDateFormat.format(newDate.getTime()));
            fromDate = editTextFrom.getText().toString();
        

    ,newCalendar.get(Calendar.YEAR), newCalendar.get(Calendar.MONTH),
            newCalendar.get(Calendar.DAY_OF_MONTH));

    datePickerDialogTo = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() 

        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) 
            Calendar newDate = Calendar.getInstance();
            newDate.set(year, monthOfYear, dayOfMonth);
            editTextTo.setText(simpleDateFormat.format(newDate.getTime()));
            toDate = editTextTo.getText().toString();
        

    ,newCalendar.get(Calendar.YEAR), newCalendar.get(Calendar.MONTH),
            newCalendar.get(Calendar.DAY_OF_MONTH));


// on click method to handle which edit text was touched
// and show the appropriate pop up calendar
@Override
public void onClick(View view) 
    if(view == editTextFrom) 
        datePickerDialogFrom.show();
     else if(view == editTextTo) 
        datePickerDialogTo.show();
    


//method to set format of date and attach the array adapter to the list view
public void searchDates(View view)
    if(!editTextFrom.getText().toString().matches("From:")
            && !editTextTo.getText().toString().matches("To:")) 
            setDateTimeField();
            getProductionComments(fromDate, toDate);
            adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, results);
            listView.setAdapter(adapter);
        Log.d("fire",adapter.toString());
    else
        Toast.makeText(this,"Please enter valid dates", Toast.LENGTH_LONG).show();
    


//get production comments data
public void getProductionComments(String from, String to) 
    try 
        SQLiteDatabase db = dbHandler.getReadableDatabase();

        String query = "SELECT Date,Item,Comments FROM ProductionCommentData WHERE Date " +
                "BETWEEN ? AND ? ORDER BY Date DESC";
        Cursor cursor = db.rawQuery(query,new String[]from,to);

        if (cursor != null) 
            if (cursor.moveToFirst()) 
                do 
                    String date = cursor.getString(cursor.getColumnIndex("Date"));
                    String item = cursor.getString(cursor.getColumnIndex("Item"));
                    String comments = cursor.getString(cursor.getColumnIndex("Comments"));
                    results.add("Date: " + date.substring(0, 10) + newline + newline +
                            "Item: " + item + newline + newline + comments);
                 while (cursor.moveToNext());
            else
                Toast.makeText(this,"No Data was found for the chosen dates",Toast.LENGTH_LONG).show();
            
        
     catch (SQLiteException se)
        Log.e(getClass().getSimpleName(), se.getMessage());
    

这是布局代码:-

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_
android:layout_ android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.qarun.qpcbeta.ProductionCommentsActivity"
android:id="@+id/relativeLayout">


<TextView
    android:layout_
    android:layout_
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Production Comments"
    android:id="@+id/textView6"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true" />

<EditText
    android:layout_
    android:layout_
    android:inputType="date"
    android:ems="10"
    android:id="@+id/editTextFrom"
    android:layout_below="@+id/textView6"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_marginTop="29dp"
    android:editable="false"
    android:textSize="13sp"
    android:text="From:"
    android:focusable="false"/>

<EditText
    android:layout_
    android:layout_
    android:inputType="date"
    android:ems="10"
    android:id="@+id/editTextTo"
    android:layout_alignTop="@+id/editTextFrom"
    android:layout_toLeftOf="@+id/btnSearch"
    android:layout_toStartOf="@+id/btnSearch"
    android:textSize="13sp"
    android:textIsSelectable="false"
    android:text="To:"
    android:focusable="false"/>

<ListView
    android:layout_
    android:layout_
    android:id="@+id/listView"
    android:layout_below="@+id/editTextTo"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"/>

<Button
    android:layout_
    android:layout_
    android:text="Search"
    android:id="@+id/btnSearch"
    android:onClick="searchDates"
    android:layout_above="@+id/listView"
    android:layout_alignRight="@+id/listView"
    android:layout_alignEnd="@+id/listView"/>

提前致谢

【问题讨论】:

【参考方案1】:

adapter.notifyDataSetChanged(); 在这种情况下有效。 [如果没有尝试重新加载列表]

【讨论】:

具体在哪里使用? 在您的点击事件中,或您想要更新的任何地方【参考方案2】:

不要在每次搜索时重新创建适配器。

类字段:

mAdapter // instantiate once
mListView // instantiate once
mResults // refresh with new data when available

这应该发生在onCreate()

mListView = (ListView)findViewByid(//etc
mResults = new ArrayList<>();
//Init mAdapter here only
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mResults);
mListView.setAdapter(mAdapter);

然后,在searchDates(...),做

getProductionComments(fromDate, toDate);//Set mResults with new data
//Don't set adapter here
mAdapter.notifyDataSetChanged(); //refresh adapter

【讨论】:

不幸的是它不起作用,当我触摸搜索按钮时,listView 没有任何反应 您确定您的数据在搜索按钮点击之间发生了变化吗?在您的代码中我看不到任何内容来更改数据库的数据。如果每次检索时db中的数据都是相同的,则ListView内容看起来是一样的。 当然会发生变化,我已经使用 logcat 确定了这一点

以上是关于android listview 不更新的主要内容,如果未能解决你的问题,请参考以下文章

Android,ListView IllegalStateException:“适配器的内容已更改但ListView没有收到通知”

Android ListView 不会在滚动时重绘

Android开发 - 下拉刷新和分段头悬停列表

在 Android 中的顶部 ListView 项目上方(以及最后一个项目下方)添加边距

停止 ListView 滚动动画

为啥当设备在 android 中水平时,ListView 内的嵌套自定义视图会阻止正确聚焦?