ArrayList 适配器(用于 ListView)仅显示第一个添加的项目

Posted

技术标签:

【中文标题】ArrayList 适配器(用于 ListView)仅显示第一个添加的项目【英文标题】:ArrayList Adapter (for ListView) only displaying the first added item 【发布时间】:2016-12-27 06:28:01 【问题描述】:

Edit3:我自己的项目列表布局:

<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@android:id/text1"
      android:layout_
      android:layout_
      android:textAppearance="?android:attr/textAppearanceListItemSmall"
      android:gravity="center_vertical"
/>

Edit2:老实说,我可能只是制作一个为每个文件创建按钮的 for 循环。这太让人头疼了,不值得花时间。

编辑:我想强调一个事实,即我已将我的确切代码复制并粘贴到一个新的测试应用程序中,它运行良好。这可能会给你们一个线索。

经过大量调试,我缩小了一个问题的范围。我正在尝试将项目(文件)添加到 ArrayList,然后将其放入 ArrayAdapter,最后在 ListView 中显示项目。问题是只显示第一个添加的项目。

这就是我的尝试:

ListView listView = (ListView) view.findViewById(R.id.templateFilesList);

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



    File myDir = getContext().getFilesDir();
    File[] templateFiles = myDir.listFiles();

    int length = templateFiles.length;

    for(int i = 0; i < length; i++)
        templateList.add(templateFiles[i].getName());
    

    ArrayAdapter arrayAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1,
            templateList);

    listView.setAdapter(arrayAdapter);

templateFiles[] 数组正确获取了 Internal Storage 中的 8 个文件(通过 logcat/debugger 确认),但 ListView 中仅显示第一项。这里有一个更清晰的问题:

// If I replace the for loop with this:

    templateList.add(templateFiles[1].getName());
    templateList.add(templateFiles[0].getName());

仅显示模板文件[1]。同样,如果我这样做:

    templateList.add(templateFiles[0].getName());
    templateList.add(templateFiles[1].getName());

仅显示模板文件[0]。关于出了什么问题的任何想法?

这是我的 XML:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context="com.template_housing.MyTemplatesFrag"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    >

<TextView
        android:layout_
        android:layout_
        android:text="@string/my_templates"
        android:textSize="34sp"
        android:textColor="@color/black"
        android:background="@color/Gold1"
        android:gravity="center_horizontal"
        android:padding="5dp"
        android:layout_marginBottom="10dp"
/>

<ListView
        android:id="@+id/templateFilesList"
        android:layout_
        android:layout_
>

</ListView>

【问题讨论】:

你也可以发布你的xml代码吗? 尝试在列表中添加一些简单的字符串("a","b","c"...),而不是templateFiles[i],看看问题是否仍然存在。 您的代码似乎没问题。我假设您的ListView 已正确填充,但不知何故只有第一项可见。请在您的setAdapter() 呼叫后通过在您的ListView 实例上呼叫getCount() 进行确认。如果是这种情况,请发布您的布局的 XML 代码。 好的,xml 已发布。 @Leo.Han - 放入简单字符串仍然存在仅显示第一个(在本例中为“a”)的问题。 getCount 结果为 8。这是正确的,因为我在内部存储中有 8 个文件。 【参考方案1】:

我复制了您的代码并在 Android Studio 中运行它。好像没问题。

这是我的活动代码(相同的xml代码),唯一的区别是我使用了一个活动,你可以使用一个片段。

public class MainActivity extends AppCompatActivity 

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ListView listView = (ListView) findViewById(R.id.templateFilesList);
    ArrayList<String> templateList = new ArrayList<>();

    File myDir = getFilesDir();
    File[] templateFiles = myDir.listFiles();
    int length = templateFiles.length;

    //case 1: in my project, length is 1, show only one element, see case2.
//        for (int i = 0; i < length; i++) 
//            templateList.add(templateFiles[i].getName());
//        

    //case 2: try to add simple strings, 
    //because you said put simple strings in the list could cause the problem, too.
    templateList.add("a1");
    templateList.add("a2");
    templateList.add("a3");

    ArrayAdapter arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
            templateList);
    listView.setAdapter(arrayAdapter);


我在 GitHub 上分享了我的代码。我强烈建议您将完整代码发布到 Github 上,让我们来查看您的代码。

【讨论】:

是的,将我的确切代码复制并粘贴到新的测试应用程序中效果很好。我现在对此很迷茫......我现在会考虑将其发布到 GitHub【参考方案2】:

可能是您的阵列适配器设置不正确,因此无法正常工作,因此请尝试使用以下代码替换您的阵列适配器并检查它是否正常工作,

   ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
          android.R.layout.simple_list_item_1, android.R.id.text1, templateList);

【讨论】:

你可以使用这个或者getApplicationContext()任何一个 "this" 和 "getApplicationContext" 将整个语句用红色下划线表示。改用 getContext() 不会出错,但同样的原始问题仍然存在。【参考方案3】:

您也可以发布简单的列表项 1 XML 文件吗?这个问题与 Java 代码无关,它与 XML 和元素的大小有关。尝试删除列表视图顶部的文本视图,您的简单列表项视图应该有 wrap content 作为布局高度。

如果你仍然想使用 textview,你可以使用 weight 属性。给你的文本视图赋予 0 的权重,给列表视图赋予 1 的权重。

【讨论】:

不会是一个问题,因为如果单个项目匹配 [parent 那么其他人仍然会通过向下滚动来。 哦,我明白了 :) 但我很确定这是与 XML 相关的。就是看不到什么 将列表视图结束标记设为自结束标记会有所不同吗? 你的意思是像这样 ?? 都可以 :) 删除文本视图后同样的问题。【参考方案4】:

尝试将其转换为字符串数组:

String [] templateListArray = templateList.toArray(new String[templateList.size()]);

然后按如下进行赋值:

ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1,
            templateListArray);

希望这会解决它。

【讨论】:

同样的问题,它只显示第一项。 试试更新的。并检查数组适配器包含哪些值, 同样的问题。字符串数组在传递到数组适配器时包含正确的项目【参考方案5】:

如果您要更新适配器的内容,您也应该致电 notifyDataSetChanged() 以确保您的适配器知道您的内容确实发生了变化

【讨论】:

notifyDataSetChanged() 如果您在设置适配器之后更新数据集,则应调用。这里完全没有必要。 请发布您的xml文件 @JorgeMendez XML 已发布。

以上是关于ArrayList 适配器(用于 ListView)仅显示第一个添加的项目的主要内容,如果未能解决你的问题,请参考以下文章

ArrayList.add 不适用于 AsyncTask

更改了arraylist时,ArrayList和ListView的Android数组适配器不会更新

更改数组列表时,带有 ArrayList 和 ListView 的 Android 数组适配器不会更新

ArrayList 对象正在返回 java android 中 ListView 上的一行

片段中的 Listview 适配器给出空指针异常

从片段更新ListView适配器内的TextView