在Android

时间:2016-10-10 11:21:57

标签: java android user-interface

如何在Android中创建工作ListView?

正在寻找您修复我的代码,但我正在寻找Android中ListView的简单工作示例,这样我就可以了解创建一个并使用它的过程。但是我已经包含了我的代码,所以你可以看到我来自哪里以及我一直在努力。

我做了以下事情并没有成功:

-

制作了一个xml布局,其中只包含一个TextView项目:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/dir_text_view"
    />

按照以下教程中的说明创建以下类: http://www.vogella.com/tutorials/AndroidListView/article.html

public class DataTempleArrayAdapter extends ArrayAdapter<String> {

HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();

public DataTempleArrayAdapter(Context context, int textViewResourceId,
                          List<String> objects) {
    super(context, textViewResourceId, objects);
    for (int i = 0; i < objects.size(); ++i) {
        mIdMap.put(objects.get(i), i);
    }
}

@Override
public long getItemId(int position) {
    String item = getItem(position);
    return mIdMap.get(item);
}

@Override
public boolean hasStableIds() {
    return true;
}

}

在主要活动中,我有一段代码,我尝试在此处向与DataTempleArrayAdapter关联的ArrayList添加字符串列表:

int i;
for (i=0;i<dirContents.length;i++) {
    dirList.add(dirContents[i]);
    //Toast.makeText(this, dirList.get(i), Toast.LENGTH_SHORT).show();
}
adapter.notifyDataSetChanged();

dirList已成功填充,而适配器根本不更新ListView。

-

在你提出要求之前,我在这里包括其余的相关代码:

activity_main.xml中:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="org.hacktivity.datatemple.MainActivity">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:inputType="text"
    android:hint="@string/directory"
    android:ems="10"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:id="@+id/dirEditText" />

    <Button
        android:text="→"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:id="@+id/dirButton"
        android:onClick="populateDirList" />

</LinearLayout>

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:id="@+id/dirListView" />

</LinearLayout>


</RelativeLayout>

还有MainActivity类:

public class MainActivity extends AppCompatActivity {

ListView dirListView;
EditText et;
DataTempleArrayAdapter adapter;
ArrayList<String> dirList;

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

    dirListView = (ListView) findViewById(R.id.dirListView);
    et = (EditText) findViewById(R.id.dirEditText);

    dirList = new ArrayList<String>();


    dirListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {

            Toast.makeText(getApplicationContext(),
                    "Click ListItem Number " + position, Toast.LENGTH_LONG)
                    .show();

            populateDirList(view);
        }

    });


    ArrayList<String> dirList = new ArrayList<String>();
    adapter = new DataTempleArrayAdapter(this,
            R.id.dir_text_view, dirList);

    dirListView.setAdapter(adapter);

}

public void populateDirList (View view) {

    File f;

    // NO INPUT.
    if (et.getText().toString().equals("")) {
        Toast.makeText(this, "empty string", Toast.LENGTH_SHORT).show();
        return;
    }

    f = new File(et.getText().toString());
    if (f == null) { return; }

    String dirContents[] = f.list();
    if (dirContents == null) { return; }
    dirList = new ArrayList<String>(Arrays.asList(f.list()));

    adapter.clear();

    int i;
    for (i=0;i<dirContents.length;i++) {
        dirList.add(dirContents[i]);
        //Toast.makeText(this, dirList.get(i), Toast.LENGTH_SHORT).show();
    }
    adapter.notifyDataSetChanged();

}
}

3 个答案:

答案 0 :(得分:1)

摘自您的代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
//...
dirList = new ArrayList<String>();
//...
ArrayList<String> dirList = new ArrayList<String>();
adapter = new DataTempleArrayAdapter(this,
        R.id.dir_text_view, dirList);
//...
}

我打赌你已经看到了问题所在,但万一你不知道:你有一个字段和一个同名的局部变量。您将局部变量传递给适配器。当然,适配器不会对场上的变化作出反应,因为它不知道它的存在。

答案 1 :(得分:1)

我认为您所做的错误是通过以下方式向Array Adapter提供UI组件:

adapter = new DataTempleArrayAdapter(this, R.id.dir_text_view, dirList);

第二项不应是ID,而是布局文件。 Android已经实现了一个List项目布局,其中包含您可以使用的textview:android.R.layout.simple_list_item_1

所以用

替换你的行
adapter = new DataTempleArrayAdapter(this, android.R.layout.simple_list_item_1, dirList);

,你又近了一步。

(这样你就不需要你的&#34; xml布局,其中只有一个TextView项目&#34;)

答案 2 :(得分:1)

  • 理解ListView的最佳资源之一确实是 你在Vogella

  • 中提到过的一个
  • 了解其中的另一个很酷的资源 notifyDataSetChanged()方法适用于ListView this post from StackOverflow

  • 有关如何使用 CustomLayouts 的简短说明 ListView(没有ViewHolder模式)检查另一个最好的 提供的参考资料:Mkyong

  • 在ListView中讨论 ViewHolder模式的好处: 检查this StackOverflow post

  • 简明示例和解释ViewHolder模式 ListView:检查this example from JavaCodeGeeks

为了修复你的代码,我认为之前给出的答案只是问题的一部分:

您必须确实评论该行

 //ArrayList<String> dirList = new ArrayList<String>();

因为,就像@ F43nd1r提到的那样,这也是传递给适配器的列表的不同实例

但是当你这样做时还有更多:

dirList = new ArrayList<String>(Arrays.asList(f.list()));

您正在实例化一个新的,不同的列表,适配器所持有的旧引用 NOT 更改...它仍将保留OLD对象列表< / p>

你应该用它代替:

    dirList.clear();
    dirList.addAll(Arrays.asList(f.list()));

希望这有帮助!