notifyDataSetChanged()通知适配器后,ListView没有更新。

3

我正在尝试在安卓中制作一个文件浏览器,我使用了一个带有列表视图的布局(如下代码所示)。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="500dp"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:id="@+id/tvfileExplorer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/fileExplorer"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" 
        android:layout_gravity="center_horizontal">
        <Button
            android:id="@+id/bRoot"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margins"
            android:layout_weight=".33"
            android:text="@string/root" />
        <Button
            android:id="@+id/bOk"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margins"
            android:text="@string/ok" 
            android:layout_weight=".33"/>
        <Button
            android:id="@+id/bCancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margins"
            android:text="@string/cancel"
            android:layout_weight=".33" />
    </LinearLayout>    
    <ListView
        android:id="@+id/lvFileList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/margins" 
        android:choiceMode="multipleChoice">
    </ListView>
</LinearLayout>

在我将所有的文件和文件夹添加到一个列表中后,我调用了列表适配器的notifyDataSetChanged()方法。但是ListView没有更新。您可以看到下面是该活动的代码。

public class FileExplorer extends Activity{ 
    private File currentDirectory = new File("/");
    private List<String> directoryEntries = new ArrayList<String>();
    private ArrayAdapter<String> lvFileExplorerListAdapter;
    private Activity mActivity;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.file_explorer);        
        mActivity = this;

        lvFileExplorerListAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_list_item_multiple_choice, directoryEntries);

        ListView lvFileExplorerList = (ListView)findViewById(R.id.lvFileList);

        lvFileExplorerList.setAdapter(lvFileExplorerListAdapter);        

        Button bCancel = (Button)findViewById(R.id.bCancel);
        bCancel.setOnClickListener(new OnClickListener() {          
        @Override
        public void onClick(View v) {       
            finish();
        }
    });

        Button bRoot = (Button)findViewById(R.id.bRoot);
        bRoot.setOnClickListener(new OnClickListener() {            
        @Override
        public void onClick(View v) {
            browseToRoot();
        }
    });

        browseToRoot();
    }

    private void browseToRoot() {
        browseTo(new File("/"));    
    }       

    private void browseTo(final File aDirectory){
    if (aDirectory.isDirectory()){
            this.currentDirectory = aDirectory;
            fill(aDirectory.listFiles());
        }
    }

    private void fill(File[] files) {
    directoryEntries.clear();

    if(this.currentDirectory.getParent() != null)
        directoryEntries.add(getString(R.string.upOneLevel));

    int currentPathStringLenght = this.currentDirectory.getAbsolutePath().length();
    for (File file : files){                     
            directoryEntries.add(file.getAbsolutePath().substring(currentPathStringLenght));
    } 

    lvFileExplorerListAdapter.notifyDataSetChanged();
    }
}

需要强调的是该列表所包含的值应当是正确的。

有任何建议吗? 谢谢


你确定没有在其他地方重新分配列表变量吗?如果有,这将导致这些问题。 - barry
1
另一个建议-尝试将一些字符串硬编码到您的列表中并通知适配器。可能是没有添加任何内容到列表中,因此您看不到任何更改。 - barry
我没有重新分配列表,但明天我会使用您的建议来看看会发生什么。 - Dporem
@barry 做了你建议的更改,但仍然存在相同的问题。 - Dporem
3个回答

1

我解决了我的问题...

在布局中,我有包含按钮的LinearLayout。就像你在上面看到的那样,我使用了*match_parent*,这导致它覆盖了列表。我将其更改为wrap_content,现在一切都正常了。

感谢大家的帮助!


0

问题出在这里:

directoryEntries.add(file.getAbsolutePath().substring(currentPathStringLenght));

您正在向directoryEntries添加项目,而适配器保留了自己的数据副本。 请尝试将该行替换为:

lvFileExplorerListAdapter.add(file.getAbsolutePath().substring(currentPathStringLenght)) ; 

无论何时您需要更改列表项,都必须直接在适配器上进行操作。

我按照你的建议进行了更改,但仍然存在同样的问题。我认为我的实现是正确的,因为我之前已经成功地使用过相同的方法。 - Dporem
那是不正确的。只要您不重新分配列表变量,就可以对其进行操作而不是适配器。 - barry
1
当然可以...只要你在将列表传递给适配器后不执行directoryEntries = new ArrayList<String>();,你就可以添加和删除其中的内容,然后只需通知适配器即可 - 你不必直接从适配器中添加和删除内容。 - barry
这就是我在第一篇帖子中所做的代码。 - Dporem

0

你尝试过在notifyDatasetChanged之后使视图无效吗?

lvFileExplorerList.invalidate();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接